2019-05-31 11:56:07 -04:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
|
|
|
export function eventTargetLegacyPatch(_global: any, api: _ZonePrivate) {
|
|
|
|
const {eventNames, globalSources, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
|
|
|
|
api.getGlobalObjects() !;
|
|
|
|
const WTF_ISSUE_555 =
|
|
|
|
'Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video';
|
|
|
|
const NO_EVENT_TARGET =
|
|
|
|
'ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex,WebSocket'
|
|
|
|
.split(',');
|
|
|
|
const EVENT_TARGET = 'EventTarget';
|
|
|
|
|
|
|
|
let apis: any[] = [];
|
|
|
|
const isWtf = _global['wtf'];
|
|
|
|
const WTF_ISSUE_555_ARRAY = WTF_ISSUE_555.split(',');
|
|
|
|
|
|
|
|
if (isWtf) {
|
|
|
|
// Workaround for: https://github.com/google/tracing-framework/issues/555
|
|
|
|
apis = WTF_ISSUE_555_ARRAY.map((v) => 'HTML' + v + 'Element').concat(NO_EVENT_TARGET);
|
|
|
|
} else if (_global[EVENT_TARGET]) {
|
|
|
|
apis.push(EVENT_TARGET);
|
|
|
|
} else {
|
|
|
|
// Note: EventTarget is not available in all browsers,
|
|
|
|
// if it's not available, we instead patch the APIs in the IDL that inherit from EventTarget
|
|
|
|
apis = NO_EVENT_TARGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isDisableIECheck = _global['__Zone_disable_IE_check'] || false;
|
|
|
|
const isEnableCrossContextCheck = _global['__Zone_enable_cross_context_check'] || false;
|
|
|
|
const ieOrEdge = api.isIEOrEdge();
|
|
|
|
|
|
|
|
const ADD_EVENT_LISTENER_SOURCE = '.addEventListener:';
|
|
|
|
const FUNCTION_WRAPPER = '[object FunctionWrapper]';
|
|
|
|
const BROWSER_TOOLS = 'function __BROWSERTOOLS_CONSOLE_SAFEFUNC() { [native code] }';
|
|
|
|
|
2019-07-21 09:53:20 -04:00
|
|
|
const pointerEventsMap: {[key: string]: string} = {
|
|
|
|
'MSPointerCancel': 'pointercancel',
|
|
|
|
'MSPointerDown': 'pointerdown',
|
|
|
|
'MSPointerEnter': 'pointerenter',
|
|
|
|
'MSPointerHover': 'pointerhover',
|
|
|
|
'MSPointerLeave': 'pointerleave',
|
|
|
|
'MSPointerMove': 'pointermove',
|
|
|
|
'MSPointerOut': 'pointerout',
|
|
|
|
'MSPointerOver': 'pointerover',
|
|
|
|
'MSPointerUp': 'pointerup'
|
|
|
|
};
|
|
|
|
|
2019-05-31 11:56:07 -04:00
|
|
|
// predefine all __zone_symbol__ + eventName + true/false string
|
|
|
|
for (let i = 0; i < eventNames.length; i++) {
|
|
|
|
const eventName = eventNames[i];
|
|
|
|
const falseEventName = eventName + FALSE_STR;
|
|
|
|
const trueEventName = eventName + TRUE_STR;
|
|
|
|
const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
|
|
|
|
const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
|
|
|
|
zoneSymbolEventNames[eventName] = {};
|
|
|
|
zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
|
|
|
|
zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
|
|
|
|
}
|
|
|
|
|
|
|
|
// predefine all task.source string
|
2019-06-22 01:44:38 -04:00
|
|
|
for (let i = 0; i < WTF_ISSUE_555_ARRAY.length; i++) {
|
2019-05-31 11:56:07 -04:00
|
|
|
const target: any = WTF_ISSUE_555_ARRAY[i];
|
|
|
|
const targets: any = globalSources[target] = {};
|
|
|
|
for (let j = 0; j < eventNames.length; j++) {
|
|
|
|
const eventName = eventNames[j];
|
|
|
|
targets[eventName] = target + ADD_EVENT_LISTENER_SOURCE + eventName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const checkIEAndCrossContext = function(
|
|
|
|
nativeDelegate: any, delegate: any, target: any, args: any) {
|
|
|
|
if (!isDisableIECheck && ieOrEdge) {
|
|
|
|
if (isEnableCrossContextCheck) {
|
|
|
|
try {
|
|
|
|
const testString = delegate.toString();
|
|
|
|
if ((testString === FUNCTION_WRAPPER || testString == BROWSER_TOOLS)) {
|
|
|
|
nativeDelegate.apply(target, args);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
nativeDelegate.apply(target, args);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const testString = delegate.toString();
|
|
|
|
if ((testString === FUNCTION_WRAPPER || testString == BROWSER_TOOLS)) {
|
|
|
|
nativeDelegate.apply(target, args);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (isEnableCrossContextCheck) {
|
|
|
|
try {
|
|
|
|
delegate.toString();
|
|
|
|
} catch (error) {
|
|
|
|
nativeDelegate.apply(target, args);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
const apiTypes: any[] = [];
|
|
|
|
for (let i = 0; i < apis.length; i++) {
|
|
|
|
const type = _global[apis[i]];
|
|
|
|
apiTypes.push(type && type.prototype);
|
|
|
|
}
|
|
|
|
// vh is validateHandler to check event handler
|
|
|
|
// is valid or not(for security check)
|
2019-07-21 09:53:20 -04:00
|
|
|
api.patchEventTarget(_global, apiTypes, {
|
|
|
|
vh: checkIEAndCrossContext,
|
|
|
|
transferEventName: (eventName: string) => {
|
|
|
|
const pointerEventName = pointerEventsMap[eventName];
|
|
|
|
return pointerEventName || eventName;
|
|
|
|
}
|
|
|
|
});
|
2019-05-31 11:56:07 -04:00
|
|
|
(Zone as any)[api.symbol('patchEventTarget')] = !!_global[EVENT_TARGET];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function patchEvent(global: any, api: _ZonePrivate) {
|
|
|
|
api.patchEventPrototype(global, api);
|
|
|
|
}
|