diff --git a/NON-STANDARD-APIS.md b/NON-STANDARD-APIS.md
index 6e6f6dbb7..c3c9676cb 100644
--- a/NON-STANDARD-APIS.md
+++ b/NON-STANDARD-APIS.md
@@ -67,6 +67,24 @@ remove the comment of the following line
//import './extra/bluebird.spec';
```
+## Others
+
+* Cordova
+
+patch `cordova.exec` API
+
+`cordova.exec(success, error, service, action, args);`
+
+`success` and `error` will be patched with `Zone.wrap`.
+
+to load the patch, you should load in the following order.
+
+```
+
+
+
+```
+
## Usage
By default, those APIs' support will not be loaded in zone.js or zone-node.js,
diff --git a/gulpfile.js b/gulpfile.js
index c5579ac6f..6d77c543f 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -123,6 +123,14 @@ gulp.task('build/webapis-shadydom.min.js', ['compile-esm'], function(cb) {
return generateScript('./lib/browser/shadydom.ts', 'webapis-shadydom.min.js', true, cb);
});
+gulp.task('build/zone-patch-cordova.js', ['compile-esm'], function(cb) {
+ return generateScript('./lib/extra/cordova.ts', 'zone-patch-cordova.js', false, cb);
+});
+
+gulp.task('build/zone-patch-cordova.min.js', ['compile-esm'], function(cb) {
+ return generateScript('./lib/extra/cordova.ts', 'zone-patch-cordova.min.js', true, cb);
+});
+
gulp.task('build/bluebird.js', ['compile-esm'], function(cb) {
return generateScript('./lib/extra/bluebird.ts', 'zone-bluebird.js', false, cb);
});
@@ -204,6 +212,8 @@ gulp.task('build', [
'build/webapis-notification.min.js',
'build/webapis-shadydom.js',
'build/webapis-shadydom.min.js',
+ 'build/zone-patch-cordova.js',
+ 'build/zone-patch-cordova.min.js',
'build/zone-mix.js',
'build/bluebird.js',
'build/bluebird.min.js',
diff --git a/karma-build.conf.js b/karma-build.conf.js
index 33ab1fea2..87c87a5ea 100644
--- a/karma-build.conf.js
+++ b/karma-build.conf.js
@@ -9,7 +9,7 @@
module.exports = function (config) {
require('./karma-base.conf.js')(config);
config.files.push('build/test/wtf_mock.js');
- config.files.push('build/test/custom_error.js');
+ config.files.push('build/test/test_fake_polyfill.js');
config.files.push('build/lib/zone.js');
config.files.push('build/lib/common/promise.js');
config.files.push('build/lib/common/error-rewrite.js');
diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts
index 745910db4..42ae9937a 100644
--- a/lib/browser/browser.ts
+++ b/lib/browser/browser.ts
@@ -193,4 +193,5 @@ Zone.__load_patch('PromiseRejectionEvent', (global: any, Zone: ZoneType, api: _Z
Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchEventTargetMethods = patchEventTargetMethods;
api.patchOnProperties = patchOnProperties;
+ api.patchMethod = patchMethod;
});
\ No newline at end of file
diff --git a/lib/extra/cordova.ts b/lib/extra/cordova.ts
new file mode 100644
index 000000000..d6ac49b12
--- /dev/null
+++ b/lib/extra/cordova.ts
@@ -0,0 +1,21 @@
+/**
+ * @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
+ */
+Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
+ if (global.cordova) {
+ const nativeExec: Function = api.patchMethod(
+ global.cordova, 'exec', (delegate: Function) => function(self: any, args: any[]) {
+ if (args.length > 0 && typeof args[0] === 'function') {
+ args[0] = Zone.current.wrap(args[0], 'cordova.exec.success');
+ }
+ if (args.length > 1 && typeof args[1] === 'function') {
+ args[1] = Zone.current.wrap(args[1], 'cordova.exec.error');
+ }
+ return nativeExec.apply(self, args);
+ });
+ }
+});
\ No newline at end of file
diff --git a/lib/zone.ts b/lib/zone.ts
index d3f2bf597..38cb179ad 100644
--- a/lib/zone.ts
+++ b/lib/zone.ts
@@ -323,6 +323,10 @@ interface _ZonePrivate {
patchEventTargetMethods:
(obj: any, addFnName?: string, removeFnName?: string, metaCreator?: any) => boolean;
patchOnProperties: (obj: any, properties: string[]) => void;
+ patchMethod:
+ (target: any, name: string,
+ patchFn: (delegate: Function, delegateName: string, name: string) =>
+ (self: any, args: any[]) => any) => Function;
}
/** @internal */
@@ -1294,7 +1298,8 @@ const Zone: ZoneType = (function(global: any) {
scheduleMicroTask: scheduleMicroTask,
showUncaughtError: () => !(Zone as any)[__symbol__('ignoreConsoleErrorUncaughtError')],
patchEventTargetMethods: () => false,
- patchOnProperties: noop
+ patchOnProperties: noop,
+ patchMethod: () => noop
};
let _currentZoneFrame: _ZoneFrame = {parent: null, zone: new Zone(null, null)};
let _currentTask: Task = null;
diff --git a/test/browser-zone-setup.ts b/test/browser-zone-setup.ts
index 70ec87fd5..1b3d6d6ed 100644
--- a/test/browser-zone-setup.ts
+++ b/test/browser-zone-setup.ts
@@ -14,4 +14,5 @@ import '../lib/zone-spec/long-stack-trace';
import '../lib/zone-spec/proxy';
import '../lib/zone-spec/sync-test';
import '../lib/zone-spec/task-tracking';
-import '../lib/zone-spec/wtf';
\ No newline at end of file
+import '../lib/zone-spec/wtf';
+import '../lib/extra/cordova';
\ No newline at end of file
diff --git a/test/browser_entry_point.ts b/test/browser_entry_point.ts
index 99183dbec..25efb0b0f 100644
--- a/test/browser_entry_point.ts
+++ b/test/browser_entry_point.ts
@@ -22,4 +22,5 @@ import './browser/XMLHttpRequest.spec';
import './browser/MediaQuery.spec';
import './browser/Notification.spec';
import './mocha-patch.spec';
-import './jasmine-patch.spec';
\ No newline at end of file
+import './jasmine-patch.spec';
+import './extra/cordova.spec';
\ No newline at end of file
diff --git a/test/extra/cordova.spec.ts b/test/extra/cordova.spec.ts
new file mode 100644
index 000000000..5884845a7
--- /dev/null
+++ b/test/extra/cordova.spec.ts
@@ -0,0 +1,40 @@
+/**
+ * @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
+ */
+describe('cordova test', () => {
+ it('cordova.exec() should be patched as macroTask', (done) => {
+ const cordova = (window as any).cordova;
+ if (!cordova) {
+ done();
+ return;
+ }
+
+ const zone = Zone.current.fork({name: 'cordova'});
+
+ zone.run(() => {
+ cordova.exec(
+ () => {
+ expect(Zone.current.name).toEqual('cordova');
+ done();
+ },
+ () => {
+ fail('should not fail');
+ },
+ 'service', 'successAction', ['arg0', 'arg1']);
+
+ cordova.exec(
+ () => {
+ fail('should not success');
+ },
+ () => {
+ expect(Zone.current.name).toEqual('cordova');
+ done();
+ },
+ 'service', 'failAction', ['arg0', 'arg1']);
+ });
+ });
+});
\ No newline at end of file
diff --git a/test/node_entry_point.ts b/test/node_entry_point.ts
index a30da33c7..0c54d2511 100644
--- a/test/node_entry_point.ts
+++ b/test/node_entry_point.ts
@@ -8,7 +8,7 @@
// Must be loaded before zone loads, so that zone can detect WTF.
import './wtf_mock';
-import './custom_error';
+import './test_fake_polyfill';
// Setup tests for Zone without microtask support
import '../lib/zone';
diff --git a/test/custom_error.ts b/test/test_fake_polyfill.ts
similarity index 55%
rename from test/custom_error.ts
rename to test/test_fake_polyfill.ts
index d5dc968e7..87ed43f3e 100644
--- a/test/custom_error.ts
+++ b/test/test_fake_polyfill.ts
@@ -8,7 +8,22 @@
'use strict';
(function(global: any) {
+ // add custom properties to Native Error
const NativeError = global['Error'];
NativeError.customProperty = 'customProperty';
NativeError.customFunction = function() {};
+
+ // add fake cordova polyfill for test
+ const fakeCordova = function() {};
+
+ (fakeCordova as any).exec = function(
+ success: Function, error: Function, service: string, action: string, args: any[]) {
+ if (action === 'successAction') {
+ success();
+ } else {
+ error();
+ }
+ };
+
+ global.cordova = fakeCordova;
})(typeof window === 'object' && window || typeof self === 'object' && self || global);