Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
fix(event): EventTarget of SourceBuffer in samsung tv will have null …
Browse files Browse the repository at this point in the history
…context (#904)

* fix: EventTarget when using Samusung TV and SourceBuffer

* fix(event): add test cases for EventTarget patch for Samsung tv

* ignore null context test in ie9
  • Loading branch information
JiaLiPassion authored and mhevery committed Sep 17, 2017
1 parent 5c8828e commit 8718e07
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 7 deletions.
16 changes: 12 additions & 4 deletions lib/common/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,12 @@ export function patchEventTarget(

// global shared zoneAwareCallback to handle all event callback with capture = false
const globalZoneAwareCallback = function(event: Event) {
const target = this || _global;

if (!event) {
return;
}
// event.target is needed for Samusung TV and SourceBuffer
// || global is needed https://github.com/angular/zone.js/issues/190
const target: any = this || event.target || _global;
const tasks = target[zoneSymbolEventNames[event.type][FALSE_STR]];
if (tasks) {
// invoke all tasks which attached to current target with given event.type and capture = false
Expand All @@ -118,8 +122,12 @@ export function patchEventTarget(

// global shared zoneAwareCallback to handle all event callback with capture = true
const globalZoneAwareCaptureCallback = function(event: Event) {
const target = this || _global;

if (!event) {
return;
}
// event.target is needed for Samusung TV and SourceBuffer
// || global is needed https://github.com/angular/zone.js/issues/190
const target: any = this || event.target || _global;
const tasks = target[zoneSymbolEventNames[event.type][TRUE_STR]];
if (tasks) {
// invoke all tasks which attached to current target with given event.type and capture = false
Expand Down
4 changes: 3 additions & 1 deletion lib/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@ export const isMix: boolean = typeof _global.process !== 'undefined' &&

const ON_PROPERTY_HANDLER_SYMBOL = zoneSymbol('onPropertyHandler');
const zoneSymbolEventNames: {[eventName: string]: string} = {};

const wrapFn = function(event: Event) {
let eventNameSymbol = zoneSymbolEventNames[event.type];
if (!eventNameSymbol) {
eventNameSymbol = zoneSymbolEventNames[event.type] = zoneSymbol('ON_PROPERTY' + event.type);
}
const listener = this[eventNameSymbol];
const target = this || event && event.target || _global;
const listener = target[eventNameSymbol];
let result = listener && listener.apply(this, arguments);

if (result != undefined && !result) {
Expand Down
71 changes: 70 additions & 1 deletion test/browser/browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
*/

import {patchFilteredProperties} from '../../lib/browser/property-descriptor';
import {patchEventTarget} from '../../lib/common/events';
import {isBrowser, isIEOrEdge, isMix, zoneSymbol} from '../../lib/common/utils';
import {ifEnvSupports, ifEnvSupportsWithDone} from '../test-util';
import {getIEVersion, ifEnvSupports, ifEnvSupportsWithDone} from '../test-util';

import Spy = jasmine.Spy;
declare const global: any;
Expand Down Expand Up @@ -243,6 +244,74 @@ describe('Zone', function() {
document.removeEventListener('mousedown', eventListenerSpy);
}));

it('event handler with null context should use event.target',
ifEnvSupports(canPatchOnProperty(Document.prototype, 'onmousedown'), function() {
const ieVer = getIEVersion();
if (ieVer && ieVer === 9) {
// in ie9, this is window object even we call func.apply(undefined)
return;
}
const logs: string[] = [];
const EventTarget = (window as any)['EventTarget'];
let oriAddEventListener = EventTarget && EventTarget.prototype ?
(EventTarget.prototype as any)['__zone_symbol__addEventListener'] :
(HTMLSpanElement.prototype as any)['__zone_symbol__addEventListener'];

if (!oriAddEventListener) {
// no patched addEventListener found
return;
}
let handler1: Function;
let handler2: Function;

const listener = function() {
logs.push('listener1');
};

const listener1 = function() {
logs.push('listener2');
};

HTMLSpanElement.prototype.addEventListener = function(
eventName: string, callback: any) {
if (eventName === 'click') {
handler1 = callback;
} else if (eventName === 'mousedown') {
handler2 = callback;
}
return oriAddEventListener.apply(this, arguments);
};

(HTMLSpanElement.prototype as any)['__zone_symbol__addEventListener'] = null;

patchEventTarget(window, [HTMLSpanElement.prototype]);

const span = document.createElement('span');
document.body.appendChild(span);

zone.run(function() {
span.addEventListener('click', listener);
span.onmousedown = listener1;
});

expect(handler1).toBe(handler2);

handler1.apply(undefined, [{type: 'click', target: span}]);

handler2.apply(undefined, [{type: 'mousedown', target: span}]);

expect(hookSpy).toHaveBeenCalled();
expect(logs).toEqual(['listener1', 'listener2']);
document.body.removeChild(span);
if (EventTarget) {
(EventTarget.prototype as any)['__zone_symbol__addEventListener'] =
oriAddEventListener;
} else {
(HTMLSpanElement.prototype as any)['__zone_symbol__addEventListener'] =
oriAddEventListener;
}
}));

it('SVGElement onclick should be in zone',
ifEnvSupports(
canPatchOnProperty(SVGElement && SVGElement.prototype, 'onmousedown'), function() {
Expand Down
10 changes: 9 additions & 1 deletion test/test-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,12 @@ export function asyncTest(testFn: Function, zone: Zone = Zone.current) {
}, 'asyncTest'));
asyncTestZone.run(testFn, this, [done]);
};
}
}

export function getIEVersion() {
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf('msie') != -1) {
return parseInt(userAgent.split('msie')[1]);
}
return null;
}

0 comments on commit 8718e07

Please sign in to comment.