From 1882451ec03daeebe32f2355030faf7e2f90ae8a Mon Sep 17 00:00:00 2001 From: JiaLiPassion Date: Thu, 2 Jan 2020 15:48:30 +0900 Subject: [PATCH] feat: Monkey patches MessagePort onproperties (onmessage/onmessageerror) (#34610) Close #34581 PR Close #34610 --- packages/zone.js/MODULE.md | 1 + packages/zone.js/bundles.bzl | 1 + packages/zone.js/lib/browser/message-port.ts | 18 +++++++ .../zone.js/test/browser/messageport.spec.ts | 49 +++++++++++++++++++ packages/zone.js/test/browser_entry_point.ts | 1 + packages/zone.js/test/karma_test.bzl | 1 + .../test/npm_package/npm_package.spec.ts | 2 + 7 files changed, 73 insertions(+) create mode 100644 packages/zone.js/lib/browser/message-port.ts create mode 100644 packages/zone.js/test/browser/messageport.spec.ts diff --git a/packages/zone.js/MODULE.md b/packages/zone.js/MODULE.md index ea7923c7cb..2439a7bd57 100644 --- a/packages/zone.js/MODULE.md +++ b/packages/zone.js/MODULE.md @@ -43,6 +43,7 @@ Below is the full list of currently supported modules. |PromiseRejectionEvent|PromiseRejectEvent will fire when ZoneAwarePromise has unhandled error|__Zone_disable_PromiseRejectionEvent = true| |mediaQuery|mediaQuery addListener API will be patched as Zone aware EventTask. (By default, mediaQuery patch will not be loaded by zone.js) |__Zone_disable_mediaQuery = true| |notification|notification onProperties API will be patched as Zone aware EventTask. (By default, notification patch will not be loaded by zone.js) |__Zone_disable_notification = true| +|MessagePort|MessagePort onProperties API will be patched as Zone aware EventTask. (By default, MessagePort patch will not be loaded by zone.js) |__Zone_disable_MessagePort = true| - NodeJS diff --git a/packages/zone.js/bundles.bzl b/packages/zone.js/bundles.bzl index 0c6e6c04e7..bed22a7b54 100644 --- a/packages/zone.js/bundles.bzl +++ b/packages/zone.js/bundles.bzl @@ -40,6 +40,7 @@ ES5_BUNDLES = { "webapis-shadydom": _DIR + "browser/shadydom", "zone-patch-socket-io": _DIR + "extra/socket-io", "zone-patch-user-media": _DIR + "browser/webapis-user-media", + "zone-patch-message-port": _DIR + "browser/message-port", "zone-testing": _DIR + "testing/zone-testing", "zone-testing-bundle": _DIR + "browser/rollup-legacy-test-main", } diff --git a/packages/zone.js/lib/browser/message-port.ts b/packages/zone.js/lib/browser/message-port.ts new file mode 100644 index 0000000000..1ec336b742 --- /dev/null +++ b/packages/zone.js/lib/browser/message-port.ts @@ -0,0 +1,18 @@ +/** + * @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 + */ + +/** + * Monkey patch `MessagePort.prototype.onmessage` and `MessagePort.prototype.onmessageerror` + * property. + */ +Zone.__load_patch('MessagePort', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + const MessagePort = global['MessagePort']; + if (typeof MessagePort !== 'undefined' && MessagePort.prototype) { + api.patchOnProperties(MessagePort.prototype, ['message', 'messageerror']); + } +}); diff --git a/packages/zone.js/test/browser/messageport.spec.ts b/packages/zone.js/test/browser/messageport.spec.ts new file mode 100644 index 0000000000..2459c152fc --- /dev/null +++ b/packages/zone.js/test/browser/messageport.spec.ts @@ -0,0 +1,49 @@ +/** + * @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 + */ + +/** + * Test MessagePort monkey patch. + */ +describe('MessagePort', () => { + let iframe: any; + beforeEach(() => { + iframe = document.createElement('iframe'); + const html = ` + + `; + iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html); + }); + afterEach(() => { + if (iframe) { + document.body.removeChild(iframe); + } + }); + + it('onmessge should in the zone', (done) => { + const channel = new MessageChannel(); + const zone = Zone.current.fork({name: 'zone'}); + iframe.onload = function() { + zone.run(() => { + channel.port1.onmessage = function() { + expect(Zone.current.name).toBe(zone.name); + done(); + }; + Zone.current.fork({name: 'zone1'}).run(() => { + iframe.contentWindow.postMessage('Hello from the main page!', '*', [channel.port2]); + }); + }); + }; + document.body.appendChild(iframe); + }); +}); diff --git a/packages/zone.js/test/browser_entry_point.ts b/packages/zone.js/test/browser_entry_point.ts index 1057086883..2f73b418bf 100644 --- a/packages/zone.js/test/browser_entry_point.ts +++ b/packages/zone.js/test/browser_entry_point.ts @@ -28,3 +28,4 @@ import './browser/Worker.spec'; import './mocha-patch.spec'; import './jasmine-patch.spec'; import './extra/cordova.spec'; +import './browser/messageport.spec'; diff --git a/packages/zone.js/test/karma_test.bzl b/packages/zone.js/test/karma_test.bzl index 5d2fc1b6c0..f88c271da5 100644 --- a/packages/zone.js/test/karma_test.bzl +++ b/packages/zone.js/test/karma_test.bzl @@ -57,6 +57,7 @@ def karma_test(name, env_srcs, env_deps, env_entry_point, test_srcs, test_deps, "//packages/zone.js/dist:zone-patch-fetch.js", "//packages/zone.js/dist:zone-patch-resize-observer.js", "//packages/zone.js/dist:zone-patch-user-media.js", + "//packages/zone.js/dist:zone-patch-message-port.js", ":" + name + "_rollup.umd", ] diff --git a/packages/zone.js/test/npm_package/npm_package.spec.ts b/packages/zone.js/test/npm_package/npm_package.spec.ts index c42c5b3377..73bdaf13dc 100644 --- a/packages/zone.js/test/npm_package/npm_package.spec.ts +++ b/packages/zone.js/test/npm_package/npm_package.spec.ts @@ -123,6 +123,8 @@ describe('Zone.js npm_package', () => { 'zone-patch-fetch.min.js', 'zone-patch-jsonp.js', 'zone-patch-jsonp.min.js', + 'zone-patch-message-port.js', + 'zone-patch-message-port.min.js', 'zone-patch-promise-test.js', 'zone-patch-promise-test.min.js', 'zone-patch-resize-observer.js',