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

Commit 49e0548

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(core): fix #1108, window.onerror should have (message, source, lineno, colno, error) signiture (#1109)
1 parent 875086f commit 49e0548

File tree

5 files changed

+66
-10
lines changed

5 files changed

+66
-10
lines changed

Diff for: file-size-limit.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"path": "dist/zone.min.js",
55
"checkTarget": true,
6-
"limit": 41600
6+
"limit": 42000
77
}
88
]
99
}

Diff for: lib/browser/property-descriptor.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* @suppress {globalThis}
1111
*/
1212

13-
import {isBrowser, isMix, isNode, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, patchClass, patchOnProperties, wrapWithCurrentZone, zoneSymbol} from '../common/utils';
13+
import {isBrowser, isIE, isMix, isNode, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, patchClass, patchOnProperties, wrapWithCurrentZone, zoneSymbol} from '../common/utils';
1414

1515
import * as webSocketPatch from './websocket';
1616

@@ -241,7 +241,7 @@ export interface IgnoreProperty {
241241

242242
function filterProperties(
243243
target: any, onProperties: string[], ignoreProperties: IgnoreProperty[]): string[] {
244-
if (!ignoreProperties) {
244+
if (!ignoreProperties || ignoreProperties.length === 0) {
245245
return onProperties;
246246
}
247247

@@ -276,10 +276,13 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) {
276276
// for browsers that we can patch the descriptor: Chrome & Firefox
277277
if (isBrowser) {
278278
const internalWindow: any = window;
279+
const ignoreErrorProperties =
280+
isIE ? [{target: internalWindow, ignoreProperties: ['error']}] : [];
279281
// in IE/Edge, onProp not exist in window object, but in WindowPrototype
280282
// so we need to pass WindowPrototype to check onProp exist or not
281283
patchFilteredProperties(
282-
internalWindow, eventNames.concat(['messageerror']), ignoreProperties,
284+
internalWindow, eventNames.concat(['messageerror']),
285+
ignoreProperties ? ignoreProperties.concat(ignoreErrorProperties) : ignoreProperties,
283286
ObjectGetPrototypeOf(internalWindow));
284287
patchFilteredProperties(Document.prototype, eventNames, ignoreProperties);
285288

Diff for: lib/common/utils.ts

+30-4
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,26 @@ const wrapFn = function(event: Event) {
135135
}
136136
const target = this || event.target || _global;
137137
const listener = target[eventNameSymbol];
138-
let result = listener && listener.apply(this, arguments);
139-
140-
if (result != undefined && !result) {
141-
event.preventDefault();
138+
let result;
139+
if (isBrowser && target === internalWindow && event.type === 'error') {
140+
// window.onerror have different signiture
141+
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror#window.onerror
142+
// and onerror callback will prevent default when callback return true
143+
const errorEvent: ErrorEvent = event as any;
144+
result = listener &&
145+
listener.call(
146+
this, errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno,
147+
errorEvent.error);
148+
if (result === true) {
149+
event.preventDefault();
150+
}
151+
} else {
152+
result = listener && listener.apply(this, arguments);
153+
if (result != undefined && !result) {
154+
event.preventDefault();
155+
}
142156
}
157+
143158
return result;
144159
};
145160

@@ -475,6 +490,17 @@ export function attachOriginToPatched(patched: Function, original: any) {
475490
let isDetectedIEOrEdge = false;
476491
let ieOrEdge = false;
477492

493+
export function isIE() {
494+
try {
495+
const ua = internalWindow.navigator.userAgent;
496+
if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1) {
497+
return true;
498+
}
499+
} catch (error) {
500+
}
501+
return false;
502+
}
503+
478504
export function isIEOrEdge() {
479505
if (isDetectedIEOrEdge) {
480506
return ieOrEdge;

Diff for: test/browser/browser.spec.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {patchFilteredProperties} from '../../lib/browser/property-descriptor';
1010
import {patchEventTarget} from '../../lib/common/events';
1111
import {isBrowser, isIEOrEdge, isMix, zoneSymbol} from '../../lib/common/utils';
12-
import {getIEVersion, ifEnvSupports, ifEnvSupportsWithDone, isEdge} from '../test-util';
12+
import {getEdgeVersion, getIEVersion, ifEnvSupports, ifEnvSupportsWithDone, isEdge} from '../test-util';
1313

1414
import Spy = jasmine.Spy;
1515
declare const global: any;
@@ -190,7 +190,7 @@ describe('Zone', function() {
190190
'onvrdisplayactivate', 'onvrdisplayblur', 'onvrdisplayconnect',
191191
'onvrdisplaydeactivate', 'onvrdisplaydisconnect', 'onvrdisplayfocus',
192192
'onvrdisplaypointerrestricted', 'onvrdisplaypointerunrestricted',
193-
'onorientationchange'
193+
'onorientationchange', 'onerror'
194194
]);
195195
});
196196

@@ -390,6 +390,24 @@ describe('Zone', function() {
390390
};
391391
expect(testFn).not.toThrow();
392392
}));
393+
394+
it('window.onerror callback signiture should be (message, source, lineno, colno, error)',
395+
ifEnvSupportsWithDone(canPatchOnProperty(window, 'onerror'), function(done: DoneFn) {
396+
let testError = new Error('testError');
397+
window.onerror = function(
398+
message: any, source?: string, lineno?: number, colno?: number, error?: any) {
399+
expect(message).toContain('testError');
400+
if (getEdgeVersion() !== 14) {
401+
// Edge 14, error will be undefined.
402+
expect(error).toBe(testError);
403+
}
404+
setTimeout(done);
405+
return true;
406+
};
407+
setTimeout(() => {
408+
throw testError;
409+
}, 100);
410+
}));
393411
}));
394412

395413
describe('eventListener hooks', function() {

Diff for: test/test-util.ts

+9
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,12 @@ export function isEdge() {
123123
const userAgent = navigator.userAgent.toLowerCase();
124124
return userAgent.indexOf('edge') !== -1;
125125
}
126+
127+
export function getEdgeVersion() {
128+
const ua = navigator.userAgent.toLowerCase();
129+
const edge = ua.indexOf('edge/');
130+
if (edge === -1) {
131+
return -1;
132+
}
133+
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
134+
}

0 commit comments

Comments
 (0)