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

Commit 31d38c1

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(patch): fix #869, should not patch readonly method (#871)
1 parent cbc58c1 commit 31d38c1

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

lib/common/utils.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,21 @@ export function patchMethod(
283283
// somehow we did not find it, but we can see it. This happens on IE for Window properties.
284284
proto = target;
285285
}
286+
286287
const delegateName = zoneSymbol(name);
287288
let delegate: Function;
288289
if (proto && !(delegate = proto[delegateName])) {
289290
delegate = proto[delegateName] = proto[name];
290-
const patchDelegate = patchFn(delegate, delegateName, name);
291-
proto[name] = function() {
292-
return patchDelegate(this, arguments as any);
293-
};
294-
attachOriginToPatched(proto[name], delegate);
291+
// check whether proto[name] is writable
292+
// some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob
293+
const desc = proto && Object.getOwnPropertyDescriptor(proto, name);
294+
if (isPropertyWritable(desc)) {
295+
const patchDelegate = patchFn(delegate, delegateName, name);
296+
proto[name] = function() {
297+
return patchDelegate(this, arguments as any);
298+
};
299+
attachOriginToPatched(proto[name], delegate);
300+
}
295301
}
296302
return delegate;
297303
}

test/common/util.spec.ts

+87
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,92 @@ describe('utils', function() {
241241
});
242242
expect(log).toEqual(['property1patch', 'property2<root>']);
243243
});
244+
245+
it('non writable method should not be patched', () => {
246+
'use strict';
247+
const TestFunction: any = function() {};
248+
const log: string[] = [];
249+
Object.defineProperties(TestFunction.prototype, {
250+
'property2': {
251+
value: function Property2(callback: Function) {
252+
Zone.root.run(callback);
253+
},
254+
writable: false,
255+
configurable: true,
256+
enumerable: true
257+
}
258+
});
259+
260+
const zone = Zone.current.fork({name: 'patch'});
261+
262+
zone.run(() => {
263+
const instance = new TestFunction();
264+
instance.property2(() => {
265+
log.push('property2' + Zone.current.name);
266+
});
267+
});
268+
expect(log).toEqual(['property2<root>']);
269+
log.length = 0;
270+
271+
patchMethod(
272+
TestFunction.prototype, 'property2',
273+
function(delegate: Function, delegateName: string, name: string) {
274+
return function(self: any, args: any) {
275+
log.push('patched property2');
276+
};
277+
});
278+
279+
zone.run(() => {
280+
const instance = new TestFunction();
281+
instance.property2(() => {
282+
log.push('property2' + Zone.current.name);
283+
});
284+
});
285+
expect(log).toEqual(['property2<root>']);
286+
});
287+
288+
it('readonly method should not be patched', () => {
289+
'use strict';
290+
const TestFunction: any = function() {};
291+
const log: string[] = [];
292+
Object.defineProperties(TestFunction.prototype, {
293+
'property2': {
294+
get: function() {
295+
return function Property2(callback: Function) {
296+
Zone.root.run(callback);
297+
};
298+
},
299+
configurable: true,
300+
enumerable: true
301+
}
302+
});
303+
304+
const zone = Zone.current.fork({name: 'patch'});
305+
306+
zone.run(() => {
307+
const instance = new TestFunction();
308+
instance.property2(() => {
309+
log.push('property2' + Zone.current.name);
310+
});
311+
});
312+
expect(log).toEqual(['property2<root>']);
313+
log.length = 0;
314+
315+
patchMethod(
316+
TestFunction.prototype, 'property2',
317+
function(delegate: Function, delegateName: string, name: string) {
318+
return function(self: any, args: any) {
319+
log.push('patched property2');
320+
};
321+
});
322+
323+
zone.run(() => {
324+
const instance = new TestFunction();
325+
instance.property2(() => {
326+
log.push('property2' + Zone.current.name);
327+
});
328+
});
329+
expect(log).toEqual(['property2<root>']);
330+
});
244331
});
245332
});

0 commit comments

Comments
 (0)