Fix memory leak in edit-text.android

Fix fromObjectRecursive to doesn't override source object
This commit is contained in:
Hristo Hristov
2018-01-11 13:25:03 +02:00
parent 82f081d603
commit 18fe9392d6
5 changed files with 62 additions and 36 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -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);