From 20b5a5dc1cdd119e2b6ef62eedb271f6daec0e56 Mon Sep 17 00:00:00 2001 From: JiaLiPassion Date: Mon, 19 Dec 2016 03:27:00 +0900 Subject: [PATCH] fix: inline event handler issue close #525 close #540 --- lib/common/utils.ts | 26 ++++++++++++++++++++++++++ test/browser/browser.spec.ts | 17 +++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib/common/utils.ts b/lib/common/utils.ts index b20691bc3..994220853 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -54,6 +54,15 @@ export const isBrowser: boolean = export function patchProperty(obj, prop) { const desc = Object.getOwnPropertyDescriptor(obj, prop) || {enumerable: true, configurable: true}; + const originalDesc = Object.getOwnPropertyDescriptor(obj, 'original' + prop); + if (!originalDesc && desc.get) { + Object.defineProperty(obj, 'original' + prop, { + enumerable: false, + configurable: true, + get: desc.get + }); + } + // A property descriptor cannot have getter/setter and be writable // deleting the writable and value properties avoids this error: // @@ -89,6 +98,23 @@ export function patchProperty(obj, prop) { // The getter would return undefined for unassigned properties but the default value of an // unassigned property is null desc.get = function() { + let r = this[_prop] || null; + // result will be null when use inline event attribute, + // such as + // because the onclick function is internal raw uncompiled handler + // the onclick will be evaluated when first time event was triggered or + // the property is accessed, https://github.com/angular/zone.js/issues/525 + // so we should use original native get to retrive the handler + if (r === null) { + let oriDesc = Object.getOwnPropertyDescriptor(obj, 'original' + prop); + if (oriDesc && oriDesc.get) { + r = oriDesc.get.apply(this, arguments); + if (r) { + desc.set.apply(this, [r]); + this.removeAttribute(prop); + } + } + } return this[_prop] || null; }; diff --git a/test/browser/browser.spec.ts b/test/browser/browser.spec.ts index d6ee869ea..c794816c3 100644 --- a/test/browser/browser.spec.ts +++ b/test/browser/browser.spec.ts @@ -125,6 +125,23 @@ describe('Zone', function() { expect(hookSpy).toHaveBeenCalled(); expect(eventListenerSpy).not.toHaveBeenCalled(); }); + + it('should support inline event handler attributes', function() { + var hookSpy = jasmine.createSpy('hook'); + var zone = rootZone.fork({ + name: 'spy', + onScheduleTask: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, + task: Task): any => { + hookSpy(); + return parentZoneDelegate.scheduleTask(targetZone, task); + } + }); + + zone.run(function() { + button.setAttribute('onclick', 'return'); + expect(button.onclick).not.toBe(null); + }); + }) }); }); });