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(value1, array);
|
||||||
TKUnit.assertEqual(value2, 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;
|
page.content = stack;
|
||||||
messageContainer.focus();
|
messageContainer.focus();
|
||||||
page.style.fontSize = 11;
|
page.style.fontSize = 11;
|
||||||
if (page.android) {
|
if (platform.isAndroid) {
|
||||||
setTimeout(() => {
|
page.on('navigatedTo', () => {
|
||||||
messageContainer.dismissSoftInput();
|
messageContainer.focus();
|
||||||
(<android.view.View>messageContainer.nativeViewProtected).scrollTo(0, 0);
|
setTimeout(() => messageContainer.dismissSoftInput());
|
||||||
}, 500);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
|
|||||||
@@ -218,13 +218,17 @@ function addPropertiesFromObject(observable: ObservableFromObject, source: any,
|
|||||||
let isRecursive = recursive;
|
let isRecursive = recursive;
|
||||||
for (let prop in source) {
|
for (let prop in source) {
|
||||||
if (source.hasOwnProperty(prop)) {
|
if (source.hasOwnProperty(prop)) {
|
||||||
if (isRecursive) {
|
let value = source[prop];
|
||||||
if (!Array.isArray(source[prop]) && source[prop] && typeof source[prop] === 'object' && !(source[prop] instanceof Observable)) {
|
if (isRecursive
|
||||||
source[prop] = fromObjectRecursive(source[prop]);
|
&& !Array.isArray(value)
|
||||||
}
|
&& value
|
||||||
|
&& typeof value === 'object'
|
||||||
|
&& !(value instanceof Observable)) {
|
||||||
|
value = fromObjectRecursive(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
defineNewProperty(observable, prop);
|
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);
|
this._style = new Style(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used in Angular.
|
||||||
get parentNode() {
|
get parentNode() {
|
||||||
return this._templateParent || this.parent;
|
return this._templateParent || this.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
set parentNode(node: ViewBase) {
|
set parentNode(node: ViewBase) {
|
||||||
this._templateParent = node;
|
this._templateParent = node;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import { ad } from "../../utils/utils";
|
|||||||
export * from "./editable-text-base-common";
|
export * from "./editable-text-base-common";
|
||||||
|
|
||||||
//https://github.com/NativeScript/NativeScript/issues/2942
|
//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 {
|
interface EditTextListeners extends android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener {
|
||||||
}
|
}
|
||||||
@@ -22,6 +23,30 @@ interface EditTextListenersClass {
|
|||||||
|
|
||||||
let EditTextListeners: 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 {
|
function initializeEditTextListeners(): void {
|
||||||
if (EditTextListeners) {
|
if (EditTextListeners) {
|
||||||
return;
|
return;
|
||||||
@@ -71,7 +96,7 @@ function initializeEditTextListeners(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasFocus) {
|
if (hasFocus) {
|
||||||
owner.clearDismissTimer();
|
clearDismissTimer();
|
||||||
owner.notify({ eventName: EditableTextBase.focusEvent, object: owner });
|
owner.notify({ eventName: EditableTextBase.focusEvent, object: owner });
|
||||||
} else {
|
} else {
|
||||||
if (owner._dirtyTextAccumulator || owner._dirtyTextAccumulator === "") {
|
if (owner._dirtyTextAccumulator || owner._dirtyTextAccumulator === "") {
|
||||||
@@ -80,7 +105,7 @@ function initializeEditTextListeners(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
owner.notify({ eventName: EditableTextBase.blurEvent, object: owner });
|
owner.notify({ eventName: EditableTextBase.blurEvent, object: owner });
|
||||||
owner.dismissSoftInput();
|
dismissSoftInput(owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +154,6 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
|||||||
private _inputType: number;
|
private _inputType: number;
|
||||||
|
|
||||||
public _changeFromCode: boolean;
|
public _changeFromCode: boolean;
|
||||||
public _dismissId: NodeJS.Timer;
|
|
||||||
|
|
||||||
public abstract _configureEditText(editText: android.widget.EditText): void;
|
public abstract _configureEditText(editText: android.widget.EditText): void;
|
||||||
|
|
||||||
@@ -168,35 +192,26 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
|||||||
this.nativeViewProtected.setInputType(this._inputType);
|
this.nativeViewProtected.setInputType(this._inputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onUnloaded() {
|
||||||
|
this.dismissSoftInput();
|
||||||
|
super.onUnloaded();
|
||||||
|
}
|
||||||
|
|
||||||
public dismissSoftInput() {
|
public dismissSoftInput() {
|
||||||
const nativeView = this.nativeViewProtected;
|
const nativeView = this.nativeViewProtected;
|
||||||
if (!nativeView) {
|
if (!nativeView) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const activity = this._context as android.app.Activity;
|
ad.dismissSoftInput(nativeView);
|
||||||
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 {
|
public focus(): boolean {
|
||||||
this.clearDismissTimer();
|
const nativeView = this.nativeViewProtected;
|
||||||
|
if (!nativeView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const result = super.focus();
|
const result = super.focus();
|
||||||
if (result) {
|
if (result) {
|
||||||
ad.showSoftInput(this.nativeViewProtected);
|
ad.showSoftInput(this.nativeViewProtected);
|
||||||
|
|||||||
Reference in New Issue
Block a user