mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Fix memory leak in edit-text.android
Fix fromObjectRecursive to doesn't override source object
This commit is contained in:
@@ -559,3 +559,10 @@ export function test_get_set_on_observables_fromObject_with_property_in_json() {
|
||||
TKUnit.assertEqual(value1, array);
|
||||
TKUnit.assertEqual(value2, array);
|
||||
}
|
||||
|
||||
export function test_fromObjectRecursive_does_not_override_source_object_property() {
|
||||
const myObj = {};
|
||||
const source = { name: "a", value: myObj };
|
||||
const observable = fromObjectRecursive(source);
|
||||
TKUnit.assertEqual(source.value, myObj);
|
||||
}
|
||||
@@ -348,11 +348,11 @@ function showReportPage(finalMessage: string) {
|
||||
page.content = stack;
|
||||
messageContainer.focus();
|
||||
page.style.fontSize = 11;
|
||||
if (page.android) {
|
||||
setTimeout(() => {
|
||||
messageContainer.dismissSoftInput();
|
||||
(<android.view.View>messageContainer.nativeViewProtected).scrollTo(0, 0);
|
||||
}, 500);
|
||||
if (platform.isAndroid) {
|
||||
page.on('navigatedTo', () => {
|
||||
messageContainer.focus();
|
||||
setTimeout(() => messageContainer.dismissSoftInput());
|
||||
});
|
||||
}
|
||||
|
||||
return page;
|
||||
|
||||
@@ -218,13 +218,17 @@ function addPropertiesFromObject(observable: ObservableFromObject, source: any,
|
||||
let isRecursive = recursive;
|
||||
for (let prop in source) {
|
||||
if (source.hasOwnProperty(prop)) {
|
||||
if (isRecursive) {
|
||||
if (!Array.isArray(source[prop]) && source[prop] && typeof source[prop] === 'object' && !(source[prop] instanceof Observable)) {
|
||||
source[prop] = fromObjectRecursive(source[prop]);
|
||||
}
|
||||
let value = source[prop];
|
||||
if (isRecursive
|
||||
&& !Array.isArray(value)
|
||||
&& value
|
||||
&& typeof value === 'object'
|
||||
&& !(value instanceof Observable)) {
|
||||
value = fromObjectRecursive(value);
|
||||
}
|
||||
|
||||
defineNewProperty(observable, prop);
|
||||
observable.set(prop, source[prop]);
|
||||
observable.set(prop, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,10 +251,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
this._style = new Style(this);
|
||||
}
|
||||
|
||||
// Used in Angular.
|
||||
get parentNode() {
|
||||
return this._templateParent || this.parent;
|
||||
}
|
||||
|
||||
set parentNode(node: ViewBase) {
|
||||
this._templateParent = node;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ import { ad } from "../../utils/utils";
|
||||
export * from "./editable-text-base-common";
|
||||
|
||||
//https://github.com/NativeScript/NativeScript/issues/2942
|
||||
let dismissKeyboardTimeoutId: any;
|
||||
export let dismissKeyboardTimeoutId: NodeJS.Timer;
|
||||
export let dismissKeyboardOwner: WeakRef<EditableTextBase>;
|
||||
|
||||
interface EditTextListeners extends android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener {
|
||||
}
|
||||
@@ -22,6 +23,30 @@ interface EditTextListenersClass {
|
||||
|
||||
let EditTextListeners: EditTextListenersClass;
|
||||
|
||||
function clearDismissTimer(): void {
|
||||
dismissKeyboardOwner = null;
|
||||
if (dismissKeyboardTimeoutId) {
|
||||
clearTimeout(dismissKeyboardTimeoutId);
|
||||
dismissKeyboardTimeoutId = null;
|
||||
}
|
||||
}
|
||||
|
||||
function dismissSoftInput(owner: EditableTextBase): void {
|
||||
clearDismissTimer();
|
||||
if (!dismissKeyboardTimeoutId) {
|
||||
dismissKeyboardTimeoutId = setTimeout(() => {
|
||||
const owner = dismissKeyboardOwner && dismissKeyboardOwner.get();
|
||||
const activity = (owner && owner._context) as android.app.Activity;
|
||||
const nativeView = owner && owner.nativeViewProtected;
|
||||
dismissKeyboardTimeoutId = null;
|
||||
dismissKeyboardOwner = null;
|
||||
const focused = activity && activity.getCurrentFocus();
|
||||
if (!focused || !(focused instanceof android.widget.EditText)) {
|
||||
ad.dismissSoftInput(nativeView);
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
function initializeEditTextListeners(): void {
|
||||
if (EditTextListeners) {
|
||||
return;
|
||||
@@ -71,7 +96,7 @@ function initializeEditTextListeners(): void {
|
||||
}
|
||||
|
||||
if (hasFocus) {
|
||||
owner.clearDismissTimer();
|
||||
clearDismissTimer();
|
||||
owner.notify({ eventName: EditableTextBase.focusEvent, object: owner });
|
||||
} else {
|
||||
if (owner._dirtyTextAccumulator || owner._dirtyTextAccumulator === "") {
|
||||
@@ -80,7 +105,7 @@ function initializeEditTextListeners(): void {
|
||||
}
|
||||
|
||||
owner.notify({ eventName: EditableTextBase.blurEvent, object: owner });
|
||||
owner.dismissSoftInput();
|
||||
dismissSoftInput(owner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +154,6 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
private _inputType: number;
|
||||
|
||||
public _changeFromCode: boolean;
|
||||
public _dismissId: NodeJS.Timer;
|
||||
|
||||
public abstract _configureEditText(editText: android.widget.EditText): void;
|
||||
|
||||
@@ -168,35 +192,26 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
this.nativeViewProtected.setInputType(this._inputType);
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this.dismissSoftInput();
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
public dismissSoftInput() {
|
||||
const nativeView = this.nativeViewProtected;
|
||||
if (!nativeView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activity = this._context as android.app.Activity;
|
||||
if (!this._dismissId) {
|
||||
this._dismissId = setTimeout(() => {
|
||||
this._dismissId = null;
|
||||
const focused = activity.getCurrentFocus();
|
||||
if (!focused
|
||||
|| focused === nativeView
|
||||
|| !(focused instanceof android.widget.EditText)) {
|
||||
ad.dismissSoftInput(nativeView);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
public clearDismissTimer(): void {
|
||||
if (this._dismissId) {
|
||||
clearTimeout(this._dismissId);
|
||||
this._dismissId = null;
|
||||
}
|
||||
}
|
||||
|
||||
public focus(): boolean {
|
||||
this.clearDismissTimer();
|
||||
const nativeView = this.nativeViewProtected;
|
||||
if (!nativeView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = super.focus();
|
||||
if (result) {
|
||||
ad.showSoftInput(this.nativeViewProtected);
|
||||
|
||||
Reference in New Issue
Block a user