diff --git a/.eslintignore b/.eslintignore
index 95d81af2..a0147878 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,3 +1,4 @@
test/lib
demo
-dist
\ No newline at end of file
+dist
+test/.eslintrc.js
diff --git a/.flowconfig b/.flowconfig
index 3a1d569f..64a6f66f 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -3,6 +3,7 @@
.*/node_modules/flow-runtime
.*/node_modules/npm
.*/node_modules/jsonlint
+.*/node_modules/resolve
.*/dist/module
[include]
[libs]
@@ -12,7 +13,4 @@ node_modules/post-robot/src/declarations.js
node_modules/grumbler-scripts/declarations.js
[options]
module.name_mapper='^src\(.*\)$' -> '/src/\1'
-experimental.const_params=false
-esproposal.export_star_as=enable
-esproposal.decorators=ignore
-include_warnings=true
+experimental.const_params=false
\ No newline at end of file
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
new file mode 100644
index 00000000..fa6c78d8
--- /dev/null
+++ b/.github/workflows/node.js.yml
@@ -0,0 +1,37 @@
+# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+ # run on push but only for the master branch
+ push:
+ branches:
+ - master
+ # run for every pull request
+ pull_request: {}
+jobs:
+ main:
+ runs-on: ubuntu-latest
+ steps:
+ - name: ⬇️ Checkout repo
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: ⎔ Setup node
+ uses: actions/setup-node@v2
+ with:
+ node-version: '14'
+ registry-url: 'https://registry.npmjs.org'
+
+ - name: 📥 Download deps
+ uses: bahmutov/npm-install@v1
+ with:
+ useLockFile: false
+
+ - name: ▶️ Run flow-typed script
+ run: npm run flow-typed
+
+ - name: ▶️ Run test script
+ run: npm run test
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 5bce9ce0..9a784305 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,9 @@
language: node_js
node_js:
- - "lts/*"
+ - 'lts/*'
+before_install:
+ - rm -rf node_modules
+ - npm install -g codecov
script: npm test
+after_success:
+ - codecov
diff --git a/README.md b/README.md
index 8ecbd310..4080f77e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,16 @@
-
+
----
+[![build status][build-badge]][build]
+[![code coverage][coverage-badge]][coverage]
+[![npm version][version-badge]][package]
+
+[build-badge]: https://img.shields.io/github/workflow/status/krakenjs/zoid/build?logo=github&style=flat-square
+[build]: https://github.com/krakenjs/zoid/actions?query=workflow%3Abuild
+[coverage-badge]: https://img.shields.io/codecov/c/github/krakenjs/zoid.svg?style=flat-square
+[coverage]: https://codecov.io/github/krakenjs/zoid/
+[version-badge]: https://img.shields.io/npm/v/zoid.svg?style=flat-square
+[package]: https://www.npmjs.com/package/zoid
A cross-domain component toolkit, supporting:
@@ -13,7 +23,7 @@ It's 'data-down, actions up' style components, but 100% cross-domain using ifram
-----
-### [API Docs](./docs/api.md)
+### [API Docs](./docs/api/index.md)
Public options and methods supported by zoid
diff --git a/SECURITY.md b/SECURITY.md
index ed4322a4..272ffa9f 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,7 +1,7 @@
# Security Policy
## How is Zoid secure?
Zoid uses [Post Robot](https://github.com/krakenjs/post-robot) to do [post messaging](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) between multiple domains.
-Zoid helps secure messaging through iframe sanboxing, domain validation, and data protection.
+Zoid helps secure messaging through iframe sandboxing, domain validation, and data protection.
- __Iframe sandboxing__ is a default browser feature that blocks others from accessing the data of your iframe instance.
- __Domain Validation__ checks the domain of the connection made to the Zoid child component, if requested. If domains don’t match accepted domains the connect fails. This is to stop access to secure components.
- __Data Protection__ is the way Zoid manages checking domains of where the data was sent from to help protect against malicious data being injected through events.
diff --git a/babel.config.js b/babel.config.js
index 2e0a208b..c44b8e7d 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -2,5 +2,9 @@
// eslint-disable-next-line import/no-commonjs
module.exports = {
- extends: 'grumbler-scripts/config/.babelrc-node'
+ extends: 'grumbler-scripts/config/.babelrc-node',
+
+ ignore: [
+ 'test/lib'
+ ]
};
diff --git a/demo/advanced/react-end-to-end/index.htm b/demo/advanced/react-end-to-end/index.htm
index e04e5ebf..ead8eac7 100644
--- a/demo/advanced/react-end-to-end/index.htm
+++ b/demo/advanced/react-end-to-end/index.htm
@@ -4,8 +4,8 @@
-
-
+
+
@@ -17,38 +17,33 @@
-
+
+
@@ -16,70 +16,89 @@
+
diff --git a/demo/frameworks/angular2/index.htm b/demo/frameworks/angular2/index.htm
index 6168cc91..4fcdcbd1 100644
--- a/demo/frameworks/angular2/index.htm
+++ b/demo/frameworks/angular2/index.htm
@@ -5,12 +5,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
@@ -20,13 +20,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/frameworks/vue3/index.htm b/demo/frameworks/vue3/index.htm
new file mode 100644
index 00000000..e2660bdf
--- /dev/null
+++ b/demo/frameworks/vue3/index.htm
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/frameworks/vue3/login.htm b/demo/frameworks/vue3/login.htm
new file mode 100644
index 00000000..f64b85e1
--- /dev/null
+++ b/demo/frameworks/vue3/login.htm
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/frameworks/vue3/login.js b/demo/frameworks/vue3/login.js
new file mode 100644
index 00000000..891e42b6
--- /dev/null
+++ b/demo/frameworks/vue3/login.js
@@ -0,0 +1,12 @@
+
+window.MyLoginZoidComponent = zoid.create({
+
+ // The html tag used to render my component
+
+ tag: 'my-login-component',
+
+ // The url that will be loaded in the iframe or popup, when someone includes my component on their page
+
+ url: new URL('login.htm', window.location.href).href
+});
+
diff --git a/demo/index.htm b/demo/index.htm
index 8d04eb2b..2fcdc9d4 100644
--- a/demo/index.htm
+++ b/demo/index.htm
@@ -34,7 +34,6 @@
basic demos
framework demos
- script tag component
react component
angular component
vue component
diff --git a/dist/zoid.frame.js b/dist/zoid.frame.js
index 919ffd16..76e07957 100644
--- a/dist/zoid.frame.js
+++ b/dist/zoid.frame.js
@@ -63,10 +63,10 @@
"use strict";
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, "PopupOpenError", (function() {
- return PopupOpenError;
+ return dom_PopupOpenError;
}));
__webpack_require__.d(__webpack_exports__, "create", (function() {
- return create;
+ return component_create;
}));
__webpack_require__.d(__webpack_exports__, "destroy", (function() {
return component_destroy;
@@ -89,6 +89,17 @@
__webpack_require__.d(__webpack_exports__, "EVENT", (function() {
return EVENT;
}));
+ function _setPrototypeOf(o, p) {
+ return (_setPrototypeOf = Object.setPrototypeOf || function(o, p) {
+ o.__proto__ = p;
+ return o;
+ })(o, p);
+ }
+ function _inheritsLoose(subClass, superClass) {
+ subClass.prototype = Object.create(superClass.prototype);
+ subClass.prototype.constructor = subClass;
+ _setPrototypeOf(subClass, superClass);
+ }
function _extends() {
return (_extends = Object.assign || function(target) {
for (var i = 1; i < arguments.length; i++) {
@@ -248,8 +259,9 @@
}
}
if (_result2 instanceof ZalgoPromise && (_result2.resolved || _result2.rejected)) {
- _result2.resolved ? promise.resolve(_result2.value) : promise.reject(_result2.error);
- _result2.errorHandled = !0;
+ var promiseResult = _result2;
+ promiseResult.resolved ? promise.resolve(promiseResult.value) : promise.reject(promiseResult.error);
+ promiseResult.errorHandled = !0;
} else utils_isPromise(_result2) ? _result2 instanceof ZalgoPromise && (_result2.resolved || _result2.rejected) ? _result2.resolved ? promise.resolve(_result2.value) : promise.reject(_result2.error) : chain(_result2, promise) : promise.resolve(_result2);
}
handlers.length = 0;
@@ -300,6 +312,10 @@
if ("undefined" == typeof Promise) throw new TypeError("Could not find Promise");
return Promise.resolve(this);
};
+ _proto.lazy = function() {
+ this.errorHandled = !0;
+ return this;
+ };
ZalgoPromise.resolve = function(value) {
return value instanceof ZalgoPromise ? value : utils_isPromise(value) ? new ZalgoPromise((function(resolve, reject) {
return value.then(resolve, reject);
@@ -314,7 +330,7 @@
ZalgoPromise.all = function(promises) {
var promise = new ZalgoPromise;
var count = promises.length;
- var results = [];
+ var results = [].slice();
if (!count) {
promise.resolve(results);
return promise;
@@ -412,9 +428,21 @@
POPUP: "popup"
};
var IE_WIN_ACCESS_ERROR = "Call was rejected by callee.\r\n";
+ function getActualProtocol(win) {
+ void 0 === win && (win = window);
+ return win.location.protocol;
+ }
+ function getProtocol(win) {
+ void 0 === win && (win = window);
+ if (win.mockDomain) {
+ var protocol = win.mockDomain.split("//")[0];
+ if (protocol) return protocol;
+ }
+ return getActualProtocol(win);
+ }
function isAboutProtocol(win) {
void 0 === win && (win = window);
- return "about:" === win.location.protocol;
+ return "about:" === getProtocol(win);
}
function utils_getParent(win) {
void 0 === win && (win = window);
@@ -438,7 +466,7 @@
void 0 === win && (win = window);
var location = win.location;
if (!location) throw new Error("Can not read window location");
- var protocol = location.protocol;
+ var protocol = getActualProtocol(win);
if (!protocol) throw new Error("Can not read window protocol");
if ("file:" === protocol) return "file://";
if ("about:" === protocol) {
@@ -466,6 +494,12 @@
try {
if (isAboutProtocol(win) && canReadFromWindow()) return !0;
} catch (err) {}
+ try {
+ if (function(win) {
+ void 0 === win && (win = window);
+ return "mock:" === getProtocol(win);
+ }(win) && canReadFromWindow()) return !0;
+ } catch (err) {}
try {
if (getActualDomain(win) === getActualDomain(window)) return !0;
} catch (err) {}
@@ -616,6 +650,21 @@
}
return !1;
}
+ function getFrameByName(win, name) {
+ var winFrames = getFrames(win);
+ for (var _i9 = 0; _i9 < winFrames.length; _i9++) {
+ var childFrame = winFrames[_i9];
+ try {
+ if (isSameDomain(childFrame) && childFrame.name === name && -1 !== winFrames.indexOf(childFrame)) return childFrame;
+ } catch (err) {}
+ }
+ try {
+ if (-1 !== winFrames.indexOf(win.frames[name])) return win.frames[name];
+ } catch (err) {}
+ try {
+ if (-1 !== winFrames.indexOf(win[name])) return win[name];
+ } catch (err) {}
+ }
function getAncestor(win) {
void 0 === win && (win = window);
return getOpener(win = win || window) || utils_getParent(win) || void 0;
@@ -722,7 +771,24 @@
} catch (err) {}
return !1;
}
+ function getFrameForWindow(win) {
+ if (isSameDomain(win)) return assertSameDomain(win).frameElement;
+ for (var _i21 = 0, _document$querySelect2 = document.querySelectorAll("iframe"); _i21 < _document$querySelect2.length; _i21++) {
+ var frame = _document$querySelect2[_i21];
+ if (frame && frame.contentWindow && frame.contentWindow === win) return frame;
+ }
+ }
function closeWindow(win) {
+ if (function(win) {
+ void 0 === win && (win = window);
+ return Boolean(utils_getParent(win));
+ }(win)) {
+ var frame = getFrameForWindow(win);
+ if (frame && frame.parentElement) {
+ frame.parentElement.removeChild(frame);
+ return;
+ }
+ }
try {
win.close();
} catch (err) {}
@@ -862,6 +928,55 @@
};
return CrossDomainSafeWeakMap;
}();
+ function _getPrototypeOf(o) {
+ return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(o) {
+ return o.__proto__ || Object.getPrototypeOf(o);
+ })(o);
+ }
+ function _isNativeReflectConstruct() {
+ if ("undefined" == typeof Reflect || !Reflect.construct) return !1;
+ if (Reflect.construct.sham) return !1;
+ if ("function" == typeof Proxy) return !0;
+ try {
+ Date.prototype.toString.call(Reflect.construct(Date, [], (function() {})));
+ return !0;
+ } catch (e) {
+ return !1;
+ }
+ }
+ function construct_construct(Parent, args, Class) {
+ return (construct_construct = _isNativeReflectConstruct() ? Reflect.construct : function(Parent, args, Class) {
+ var a = [ null ];
+ a.push.apply(a, args);
+ var instance = new (Function.bind.apply(Parent, a));
+ Class && _setPrototypeOf(instance, Class.prototype);
+ return instance;
+ }).apply(null, arguments);
+ }
+ function wrapNativeSuper_wrapNativeSuper(Class) {
+ var _cache = "function" == typeof Map ? new Map : void 0;
+ return (wrapNativeSuper_wrapNativeSuper = function(Class) {
+ if (null === Class || !(fn = Class, -1 !== Function.toString.call(fn).indexOf("[native code]"))) return Class;
+ var fn;
+ if ("function" != typeof Class) throw new TypeError("Super expression must either be null or a function");
+ if (void 0 !== _cache) {
+ if (_cache.has(Class)) return _cache.get(Class);
+ _cache.set(Class, Wrapper);
+ }
+ function Wrapper() {
+ return construct_construct(Class, arguments, _getPrototypeOf(this).constructor);
+ }
+ Wrapper.prototype = Object.create(Class.prototype, {
+ constructor: {
+ value: Wrapper,
+ enumerable: !1,
+ writable: !0,
+ configurable: !0
+ }
+ });
+ return _setPrototypeOf(Wrapper, Class);
+ })(Class);
+ }
function getFunctionName(fn) {
return fn.name || fn.__name__ || fn.displayName || "anonymous";
}
@@ -876,13 +991,13 @@
function base64encode(str) {
if ("function" == typeof btoa) return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (function(m, p1) {
return String.fromCharCode(parseInt(p1, 16));
- })));
- if ("undefined" != typeof Buffer) return Buffer.from(str, "utf8").toString("base64");
+ }))).replace(/[=]/g, "");
+ if ("undefined" != typeof Buffer) return Buffer.from(str, "utf8").toString("base64").replace(/[=]/g, "");
throw new Error("Can not find window.btoa or Buffer");
}
function uniqueID() {
var chars = "0123456789abcdef";
- return "xxxxxxxxxx".replace(/./g, (function() {
+ return "uid_" + "xxxxxxxxxx".replace(/./g, (function() {
return chars.charAt(Math.floor(Math.random() * chars.length));
})) + "_" + base64encode((new Date).toISOString().slice(11, 19).replace("T", ".")).replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
}
@@ -905,46 +1020,61 @@
throw new Error("Arguments not serializable -- can not be used to memoize");
}
}
- var memoizedFunctions = [];
+ function getEmptyObject() {
+ return {};
+ }
+ var memoizeGlobalIndex = 0;
+ var memoizeGlobalIndexValidFrom = 0;
function memoize(method, options) {
- var _this = this;
void 0 === options && (options = {});
- var cacheMap = new weakmap_CrossDomainSafeWeakMap;
+ var _options$thisNamespac = options.thisNamespace, thisNamespace = void 0 !== _options$thisNamespac && _options$thisNamespac, cacheTime = options.time;
+ var simpleCache;
+ var thisCache;
+ var memoizeIndex = memoizeGlobalIndex;
+ memoizeGlobalIndex += 1;
var memoizedFunction = function() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
- var cache = cacheMap.getOrSet(options.thisNamespace ? this : method, (function() {
- return {};
- }));
- var key = serializeArgs(args);
- var cacheTime = options.time;
- cache[key] && cacheTime && Date.now() - cache[key].time < cacheTime && delete cache[key];
- if (cache[key]) return cache[key].value;
+ if (memoizeIndex < memoizeGlobalIndexValidFrom) {
+ simpleCache = null;
+ thisCache = null;
+ memoizeIndex = memoizeGlobalIndex;
+ memoizeGlobalIndex += 1;
+ }
+ var cache;
+ cache = thisNamespace ? (thisCache = thisCache || new weakmap_CrossDomainSafeWeakMap).getOrSet(this, getEmptyObject) : simpleCache = simpleCache || {};
+ var cacheKey = serializeArgs(args);
+ var cacheResult = cache[cacheKey];
+ if (cacheResult && cacheTime && Date.now() - cacheResult.time < cacheTime) {
+ delete cache[cacheKey];
+ cacheResult = null;
+ }
+ if (cacheResult) return cacheResult.value;
var time = Date.now();
var value = method.apply(this, arguments);
- cache[key] = {
+ cache[cacheKey] = {
time: time,
value: value
};
- return cache[key].value;
+ return value;
};
memoizedFunction.reset = function() {
- cacheMap.delete(options.thisNamespace ? _this : method);
+ simpleCache = null;
+ thisCache = null;
};
- memoizedFunctions.push(memoizedFunction);
return setFunctionName(memoizedFunction, (options.name || getFunctionName(method)) + "::memoized");
}
memoize.clear = function() {
- for (var _i2 = 0; _i2 < memoizedFunctions.length; _i2++) memoizedFunctions[_i2].reset();
+ memoizeGlobalIndexValidFrom = memoizeGlobalIndex;
};
function memoizePromise(method) {
var cache = {};
function memoizedPromiseFunction() {
- var _arguments = arguments, _this2 = this;
+ var _arguments = arguments, _this = this;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) args[_key2] = arguments[_key2];
var key = serializeArgs(args);
if (cache.hasOwnProperty(key)) return cache[key];
cache[key] = promise_ZalgoPromise.try((function() {
- return method.apply(_this2, _arguments);
+ return method.apply(_this, _arguments);
})).finally((function() {
delete cache[key];
}));
@@ -955,12 +1085,6 @@
};
return setFunctionName(memoizedPromiseFunction, getFunctionName(method) + "::promiseMemoized");
}
- function inlineMemoize(method, logic, args) {
- void 0 === args && (args = []);
- var cache = method.__inline_memoize_cache__ = method.__inline_memoize_cache__ || {};
- var key = serializeArgs(args);
- return cache.hasOwnProperty(key) ? cache[key] : cache[key] = logic.apply(void 0, args);
- }
function src_util_noop() {}
function once(method) {
var called = !1;
@@ -998,6 +1122,12 @@
for (var key in source) source.hasOwnProperty(key) && (obj[key] = source[key]);
return obj;
}
+ memoize((function(obj) {
+ if (Object.values) return Object.values(obj);
+ var result = [];
+ for (var key in obj) obj.hasOwnProperty(key) && result.push(obj[key]);
+ return result;
+ }));
function identity(item) {
return item;
}
@@ -1033,20 +1163,31 @@
function cleanup(obj) {
var tasks = [];
var cleaned = !1;
- return {
+ var cleanErr;
+ var cleaner = {
set: function(name, item) {
if (!cleaned) {
obj[name] = item;
- this.register((function() {
+ cleaner.register((function() {
delete obj[name];
}));
}
return item;
},
register: function(method) {
- cleaned ? method() : tasks.push(once(method));
+ var task = once((function() {
+ return method(cleanErr);
+ }));
+ cleaned ? method(cleanErr) : tasks.push(task);
+ return {
+ cancel: function() {
+ var index = tasks.indexOf(task);
+ -1 !== index && tasks.splice(index, 1);
+ }
+ };
},
- all: function() {
+ all: function(err) {
+ cleanErr = err;
var results = [];
cleaned = !0;
for (;tasks.length; ) {
@@ -1056,16 +1197,30 @@
return promise_ZalgoPromise.all(results).then(src_util_noop);
}
};
+ return cleaner;
}
function assertExists(name, thing) {
if (null == thing) throw new Error("Expected " + name + " to be present");
return thing;
}
- memoize((function(obj) {
- var result = [];
- for (var key in obj) obj.hasOwnProperty(key) && result.push(obj[key]);
- return result;
- }));
+ var util_ExtendableError = function(_Error) {
+ _inheritsLoose(ExtendableError, _Error);
+ function ExtendableError(message) {
+ var _this6;
+ (_this6 = _Error.call(this, message) || this).name = _this6.constructor.name;
+ "function" == typeof Error.captureStackTrace ? Error.captureStackTrace(function(self) {
+ if (void 0 === self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ return self;
+ }(_this6), _this6.constructor) : _this6.stack = new Error(message).stack;
+ return _this6;
+ }
+ return ExtendableError;
+ }(wrapNativeSuper_wrapNativeSuper(Error));
+ function getBody() {
+ var body = document.body;
+ if (!body) throw new Error("Body element not found");
+ return body;
+ }
function isDocumentReady() {
return Boolean(document.body) && "complete" === document.readyState;
}
@@ -1073,7 +1228,7 @@
return Boolean(document.body) && "interactive" === document.readyState;
}
function urlEncode(str) {
- return str.replace(/\?/g, "%3F").replace(/&/g, "%26").replace(/#/g, "%23").replace(/\+/g, "%2B");
+ return encodeURIComponent(str);
}
memoize((function() {
return new promise_ZalgoPromise((function(resolve) {
@@ -1087,25 +1242,32 @@
}));
}));
function parseQuery(queryString) {
- return inlineMemoize(parseQuery, (function() {
- var params = {};
- if (!queryString) return params;
- if (-1 === queryString.indexOf("=")) return params;
- for (var _i2 = 0, _queryString$split2 = queryString.split("&"); _i2 < _queryString$split2.length; _i2++) {
- var pair = _queryString$split2[_i2];
- (pair = pair.split("="))[0] && pair[1] && (params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]));
- }
- return params;
- }), [ queryString ]);
+ return function(method, logic, args) {
+ void 0 === args && (args = []);
+ var cache = method.__inline_memoize_cache__ = method.__inline_memoize_cache__ || {};
+ var key = serializeArgs(args);
+ return cache.hasOwnProperty(key) ? cache[key] : cache[key] = function() {
+ var params = {};
+ if (!queryString) return params;
+ if (-1 === queryString.indexOf("=")) return params;
+ for (var _i2 = 0, _queryString$split2 = queryString.split("&"); _i2 < _queryString$split2.length; _i2++) {
+ var pair = _queryString$split2[_i2];
+ (pair = pair.split("="))[0] && pair[1] && (params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]));
+ }
+ return params;
+ }.apply(void 0, args);
+ }(parseQuery, 0, [ queryString ]);
}
function extendQuery(originalQuery, props) {
void 0 === props && (props = {});
return props && Object.keys(props).length ? function(obj) {
void 0 === obj && (obj = {});
return Object.keys(obj).filter((function(key) {
- return "string" == typeof obj[key];
+ return "string" == typeof obj[key] || "boolean" == typeof obj[key];
})).map((function(key) {
- return urlEncode(key) + "=" + urlEncode(obj[key]);
+ var val = obj[key];
+ if ("string" != typeof val && "boolean" != typeof val) throw new TypeError("Invalid type for query");
+ return urlEncode(key) + "=" + urlEncode(val.toString());
})).join("&");
}(_extends({}, parseQuery(originalQuery), props)) : originalQuery;
}
@@ -1127,20 +1289,22 @@
if (isDocumentReady()) return reject(new Error("Document is ready and element " + name + " does not exist"));
var interval = setInterval((function() {
if (el = getElementSafe(id)) {
+ resolve(el);
clearInterval(interval);
- return resolve(el);
- }
- if (isDocumentReady()) {
+ } else if (isDocumentReady()) {
clearInterval(interval);
return reject(new Error("Document is ready and element " + name + " does not exist"));
}
}), 10);
}));
}
- function PopupOpenError(message) {
- this.message = message;
- }
- PopupOpenError.prototype = Object.create(Error.prototype);
+ var dom_PopupOpenError = function(_ExtendableError) {
+ _inheritsLoose(PopupOpenError, _ExtendableError);
+ function PopupOpenError() {
+ return _ExtendableError.apply(this, arguments) || this;
+ }
+ return PopupOpenError;
+ }(util_ExtendableError);
var awaitFrameLoadPromises;
function awaitFrameLoad(frame) {
if ((awaitFrameLoadPromises = awaitFrameLoadPromises || new weakmap_CrossDomainSafeWeakMap).has(frame)) {
@@ -1247,25 +1411,30 @@
element && element.parentNode && element.parentNode.removeChild(element);
}
function isElementClosed(el) {
- return !el || !el.parentNode;
+ return !(el && el.parentNode && el.ownerDocument && el.ownerDocument.documentElement && el.ownerDocument.documentElement.contains(el));
}
function onResize(el, handler, _temp) {
var _ref2 = void 0 === _temp ? {} : _temp, _ref2$width = _ref2.width, width = void 0 === _ref2$width || _ref2$width, _ref2$height = _ref2.height, height = void 0 === _ref2$height || _ref2$height, _ref2$interval = _ref2.interval, interval = void 0 === _ref2$interval ? 100 : _ref2$interval, _ref2$win = _ref2.win, win = void 0 === _ref2$win ? window : _ref2$win;
var currentWidth = el.offsetWidth;
var currentHeight = el.offsetHeight;
+ var canceled = !1;
handler({
width: currentWidth,
height: currentHeight
});
var check = function() {
- var newWidth = el.offsetWidth;
- var newHeight = el.offsetHeight;
- (width && newWidth !== currentWidth || height && newHeight !== currentHeight) && handler({
- width: newWidth,
- height: newHeight
- });
- currentWidth = newWidth;
- currentHeight = newHeight;
+ if (!canceled && function(el) {
+ return Boolean(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
+ }(el)) {
+ var newWidth = el.offsetWidth;
+ var newHeight = el.offsetHeight;
+ (width && newWidth !== currentWidth || height && newHeight !== currentHeight) && handler({
+ width: newWidth,
+ height: newHeight
+ });
+ currentWidth = newWidth;
+ currentHeight = newHeight;
+ }
};
var observer;
var timeout;
@@ -1284,6 +1453,7 @@
} else timeout = safeInterval(check, interval);
return {
cancel: function() {
+ canceled = !0;
observer.disconnect();
window.removeEventListener("resize", check);
timeout.cancel();
@@ -1294,6 +1464,58 @@
for (;element.parentNode; ) element = element.parentNode;
return "[object ShadowRoot]" === element.toString();
}
+ var currentScript = "undefined" != typeof document ? document.currentScript : null;
+ var getCurrentScript = memoize((function() {
+ if (currentScript) return currentScript;
+ if (currentScript = function() {
+ try {
+ var stack = function() {
+ try {
+ throw new Error("_");
+ } catch (err) {
+ return err.stack || "";
+ }
+ }();
+ var stackDetails = /.*at [^(]*\((.*):(.+):(.+)\)$/gi.exec(stack);
+ var scriptLocation = stackDetails && stackDetails[1];
+ if (!scriptLocation) return;
+ for (var _i22 = 0, _Array$prototype$slic2 = [].slice.call(document.getElementsByTagName("script")).reverse(); _i22 < _Array$prototype$slic2.length; _i22++) {
+ var script = _Array$prototype$slic2[_i22];
+ if (script.src && script.src === scriptLocation) return script;
+ }
+ } catch (err) {}
+ }()) return currentScript;
+ throw new Error("Can not determine current script");
+ }));
+ var currentUID = uniqueID();
+ memoize((function() {
+ var script;
+ try {
+ script = getCurrentScript();
+ } catch (err) {
+ return currentUID;
+ }
+ var uid = script.getAttribute("data-uid");
+ if (uid && "string" == typeof uid) return uid;
+ if ((uid = script.getAttribute("data-uid-auto")) && "string" == typeof uid) return uid;
+ if (script.src) {
+ var hashedString = function(str) {
+ var hash = "";
+ for (var i = 0; i < str.length; i++) {
+ var total = str[i].charCodeAt(0) * i;
+ str[i + 1] && (total += str[i + 1].charCodeAt(0) * (i - 1));
+ hash += String.fromCharCode(97 + Math.abs(total) % 26);
+ }
+ return hash;
+ }(JSON.stringify({
+ src: script.src,
+ dataset: script.dataset
+ }));
+ uid = "uid_" + hashedString.slice(hashedString.length - 30);
+ } else uid = uniqueID();
+ script.setAttribute("data-uid-auto", uid);
+ return uid;
+ }));
function toPx(val) {
return function(val) {
if ("number" == typeof val) return val;
@@ -1308,7 +1530,8 @@
}
function global_getGlobal(win) {
void 0 === win && (win = window);
- return win !== window ? win.__post_robot_10_0_39__ : win.__post_robot_10_0_39__ = win.__post_robot_10_0_39__ || {};
+ var globalKey = "__post_robot_10_0_44__";
+ return win !== window ? win[globalKey] : win[globalKey] = win[globalKey] || {};
}
var getObj = function() {
return {};
@@ -1462,6 +1685,8 @@
return val;
}, _SERIALIZER.null = function(val) {
return val;
+ }, _SERIALIZER[void 0] = function(val) {
+ return serializeType("undefined", val);
}, _SERIALIZER);
var defaultSerializers = {};
var _DESERIALIZER;
@@ -1492,7 +1717,7 @@
return val;
}, _DESERIALIZER.null = function(val) {
return val;
- }, _DESERIALIZER);
+ }, _DESERIALIZER[void 0] = function() {}, _DESERIALIZER);
var defaultDeserializers = {};
new promise_ZalgoPromise((function(resolve) {
if (window.document && window.document.body) return resolve(window.document.body);
@@ -1521,6 +1746,11 @@
}));
windowNamePromise.catch(src_util_noop);
windowTypePromise.catch(src_util_noop);
+ var getName = function() {
+ return winPromise.then((function(win) {
+ if (!isWindowClosed(win)) return isSameDomain(win) ? assertSameDomain(win).name : windowNamePromise;
+ }));
+ };
return {
id: id,
getType: function() {
@@ -1536,11 +1766,7 @@
close: function() {
return winPromise.then(closeWindow);
},
- getName: function() {
- return winPromise.then((function(win) {
- if (!isWindowClosed(win)) return isSameDomain(win) ? assertSameDomain(win).name : windowNamePromise;
- }));
- },
+ getName: getName,
focus: function() {
return winPromise.then((function(win) {
win.focus();
@@ -1551,10 +1777,40 @@
return isWindowClosed(win);
}));
},
- setLocation: function(href) {
+ setLocation: function(href, opts) {
+ void 0 === opts && (opts = {});
return winPromise.then((function(win) {
var domain = window.location.protocol + "//" + window.location.host;
+ var _opts$method = opts.method, method = void 0 === _opts$method ? "get" : _opts$method, body = opts.body;
if (0 === href.indexOf("/")) href = "" + domain + href; else if (!href.match(/^https?:\/\//) && 0 !== href.indexOf(domain)) throw new Error("Expected url to be http or https url, or absolute path, got " + JSON.stringify(href));
+ if ("post" === method) return getName().then((function(name) {
+ if (!name) throw new Error("Can not post to window without target name");
+ !function(_ref3) {
+ var url = _ref3.url, target = _ref3.target, body = _ref3.body, _ref3$method = _ref3.method, method = void 0 === _ref3$method ? "post" : _ref3$method;
+ var form = document.createElement("form");
+ form.setAttribute("target", target);
+ form.setAttribute("method", method);
+ form.setAttribute("action", url);
+ form.style.display = "none";
+ if (body) for (var _i24 = 0, _Object$keys4 = Object.keys(body); _i24 < _Object$keys4.length; _i24++) {
+ var _body$key;
+ var key = _Object$keys4[_i24];
+ var input = document.createElement("input");
+ input.setAttribute("name", key);
+ input.setAttribute("value", null == (_body$key = body[key]) ? void 0 : _body$key.toString());
+ form.appendChild(input);
+ }
+ getBody().appendChild(form);
+ form.submit();
+ getBody().removeChild(form);
+ }({
+ url: href,
+ target: name,
+ method: method,
+ body: body
+ });
+ }));
+ if ("get" !== method) throw new Error("Unsupported method: " + method);
if (isSameDomain(win)) try {
if (win.location && "function" == typeof win.location.replace) {
win.location.replace(href);
@@ -1567,13 +1823,7 @@
setName: function(name) {
return winPromise.then((function(win) {
var sameDomain = isSameDomain(win);
- var frame = function(win) {
- if (isSameDomain(win)) return assertSameDomain(win).frameElement;
- for (var _i21 = 0, _document$querySelect2 = document.querySelectorAll("iframe"); _i21 < _document$querySelect2.length; _i21++) {
- var frame = _document$querySelect2[_i21];
- if (frame && frame.contentWindow && frame.contentWindow === win) return frame;
- }
- }(win);
+ var frame = getFrameForWindow(win);
if (!sameDomain) throw new Error("Can not set name for cross-domain window: " + name);
assertSameDomain(win).name = name;
frame && frame.setAttribute("name", name);
@@ -1613,9 +1863,9 @@
return type === WINDOW_TYPE.POPUP;
}));
};
- _proto.setLocation = function(href) {
+ _proto.setLocation = function(href, opts) {
var _this = this;
- return this.serializedWindow.setLocation(href).then((function() {
+ return this.serializedWindow.setLocation(href, opts).then((function() {
return _this;
}));
};
@@ -1972,7 +2222,7 @@
domainBuffer.buffer.push(message);
domainBuffer.flush = domainBuffer.flush || promise_ZalgoPromise.flush().then((function() {
if (isWindowClosed(win)) throw new Error("Window is closed");
- var serializedMessage = serializeMessage(win, domain, ((_ref = {}).__post_robot_10_0_39__ = domainBuffer.buffer || [],
+ var serializedMessage = serializeMessage(win, domain, ((_ref = {}).__post_robot_10_0_44__ = domainBuffer.buffer || [],
_ref), {
on: on,
send: send
@@ -2033,8 +2283,7 @@
}
}
}
- var _RECEIVE_MESSAGE_TYPE;
- var RECEIVE_MESSAGE_TYPES = ((_RECEIVE_MESSAGE_TYPE = {}).postrobot_message_request = function(source, origin, message, _ref) {
+ function handleRequest(source, origin, message, _ref) {
var on = _ref.on, send = _ref.send;
var options = getRequestListener({
name: message.name,
@@ -2094,7 +2343,8 @@
if (options && options.handleError) return options.handleError(err);
throw err;
}));
- }, _RECEIVE_MESSAGE_TYPE.postrobot_message_ack = function(source, origin, message) {
+ }
+ function handleAck(source, origin, message) {
if (!isResponseListenerErrored(message.hash)) {
var options = getResponseListener(message.hash);
if (!options) throw new Error("No handler found for post message ack for message: " + message.name + " from " + origin + " in " + window.location.protocol + "//" + window.location.host + window.location.pathname);
@@ -2106,12 +2356,13 @@
}
options.ack = !0;
}
- }, _RECEIVE_MESSAGE_TYPE.postrobot_message_response = function(source, origin, message) {
+ }
+ function handleResponse(source, origin, message) {
if (!isResponseListenerErrored(message.hash)) {
var options = getResponseListener(message.hash);
if (!options) throw new Error("No handler found for post message response for message: " + message.name + " from " + origin + " in " + window.location.protocol + "//" + window.location.host + window.location.pathname);
if (!matchDomain(options.domain, origin)) throw new Error("Response origin " + origin + " does not match domain " + (pattern = options.domain,
- Array.isArray(pattern) ? "(" + pattern.join(" | ") + ")" : isRegex(pattern) ? "RegExp(" + pattern.toString() : pattern.toString()));
+ Array.isArray(pattern) ? "(" + pattern.join(" | ") + ")" : isRegex(pattern) ? "RegExp(" + pattern.toString() + ")" : pattern.toString()));
var pattern;
if (source !== options.win) throw new Error("Response source does not match registered window");
deleteResponseListener(message.hash);
@@ -2121,7 +2372,7 @@
data: message.data
});
}
- }, _RECEIVE_MESSAGE_TYPE);
+ }
function receive_receiveMessage(event, _ref2) {
var on = _ref2.on, send = _ref2.send;
var receivedMessages = globalStore("receivedMessages");
@@ -2143,7 +2394,7 @@
return;
}
if (parsedMessage && "object" == typeof parsedMessage && null !== parsedMessage) {
- var parseMessages = parsedMessage.__post_robot_10_0_39__;
+ var parseMessages = parsedMessage.__post_robot_10_0_44__;
if (Array.isArray(parseMessages)) return parseMessages;
}
}(event.data, source, origin, {
@@ -2159,10 +2410,10 @@
if (isWindowClosed(source) && !message.fireAndForget) return;
0 === message.origin.indexOf("file:") && (origin = "file://");
try {
- "postrobot_message_request" === message.type ? RECEIVE_MESSAGE_TYPES.postrobot_message_request(source, origin, message, {
+ "postrobot_message_request" === message.type ? handleRequest(source, origin, message, {
on: on,
send: send
- }) : "postrobot_message_response" === message.type ? RECEIVE_MESSAGE_TYPES.postrobot_message_response(source, origin, message) : "postrobot_message_ack" === message.type && RECEIVE_MESSAGE_TYPES.postrobot_message_ack(source, origin, message);
+ }) : "postrobot_message_response" === message.type ? handleResponse(source, origin, message) : "postrobot_message_ack" === message.type && handleAck(source, origin, message);
} catch (err) {
setTimeout((function() {
throw err;
@@ -2373,28 +2624,20 @@
}));
}));
};
- function setup_serializeMessage(destination, domain, obj) {
- return serializeMessage(destination, domain, obj, {
- on: on_on,
- send: send_send
- });
- }
- function setup_deserializeMessage(source, origin, message) {
- return deserializeMessage(source, origin, message, {
- on: on_on,
- send: send_send
- });
- }
function setup_toProxyWindow(win) {
return window_ProxyWindow.toProxyWindow(win, {
send: send_send
});
}
function lib_global_getGlobal(win) {
- void 0 === win && (win = window);
if (!isSameDomain(win)) throw new Error("Can not get global for window on different domain");
- win.__zoid_9_0_58__ || (win.__zoid_9_0_58__ = {});
- return win.__zoid_9_0_58__;
+ win.__zoid_9_0_86__ || (win.__zoid_9_0_86__ = {});
+ return win.__zoid_9_0_86__;
+ }
+ function tryGlobal(win, handler) {
+ try {
+ return handler(lib_global_getGlobal(win));
+ } catch (err) {}
}
function getProxyObject(obj) {
return {
@@ -2407,6 +2650,86 @@
}
};
}
+ function basicSerialize(data) {
+ return base64encode(JSON.stringify(data));
+ }
+ function getUIDRefStore(win) {
+ var global = lib_global_getGlobal(win);
+ global.references = global.references || {};
+ return global.references;
+ }
+ function crossDomainSerialize(_ref) {
+ var data = _ref.data, metaData = _ref.metaData, sender = _ref.sender, receiver = _ref.receiver, _ref$passByReference = _ref.passByReference, passByReference = void 0 !== _ref$passByReference && _ref$passByReference, _ref$basic = _ref.basic, basic = void 0 !== _ref$basic && _ref$basic;
+ var proxyWin = setup_toProxyWindow(receiver.win);
+ var serializedMessage = basic ? JSON.stringify(data) : serializeMessage(proxyWin, receiver.domain, data, {
+ on: on_on,
+ send: send_send
+ });
+ var reference = passByReference ? function(val) {
+ var uid = uniqueID();
+ getUIDRefStore(window)[uid] = val;
+ return {
+ type: "uid",
+ uid: uid
+ };
+ }(serializedMessage) : {
+ type: "raw",
+ val: serializedMessage
+ };
+ return {
+ serializedData: basicSerialize({
+ sender: {
+ domain: sender.domain
+ },
+ metaData: metaData,
+ reference: reference
+ }),
+ cleanReference: function() {
+ win = window, "uid" === (ref = reference).type && delete getUIDRefStore(win)[ref.uid];
+ var win, ref;
+ }
+ };
+ }
+ function crossDomainDeserialize(_ref2) {
+ var sender = _ref2.sender, _ref2$basic = _ref2.basic, basic = void 0 !== _ref2$basic && _ref2$basic;
+ var message = function(serializedData) {
+ return JSON.parse(function(str) {
+ if ("function" == typeof atob) return decodeURIComponent([].map.call(atob(str), (function(c) {
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
+ })).join(""));
+ if ("undefined" != typeof Buffer) return Buffer.from(str, "base64").toString("utf8");
+ throw new Error("Can not find window.atob or Buffer");
+ }(serializedData));
+ }(_ref2.data);
+ var reference = message.reference, metaData = message.metaData;
+ var win;
+ win = "function" == typeof sender.win ? sender.win({
+ metaData: metaData
+ }) : sender.win;
+ var domain;
+ domain = "function" == typeof sender.domain ? sender.domain({
+ metaData: metaData
+ }) : "string" == typeof sender.domain ? sender.domain : message.sender.domain;
+ var serializedData = function(win, ref) {
+ if ("raw" === ref.type) return ref.val;
+ if ("uid" === ref.type) return getUIDRefStore(win)[ref.uid];
+ throw new Error("Unsupported ref type: " + ref.type);
+ }(win, reference);
+ return {
+ data: basic ? JSON.parse(serializedData) : function(source, origin, message) {
+ return deserializeMessage(source, origin, message, {
+ on: on_on,
+ send: send_send
+ });
+ }(win, domain, serializedData),
+ metaData: metaData,
+ sender: {
+ win: win,
+ domain: domain
+ },
+ reference: reference
+ };
+ }
var PROP_TYPE = {
STRING: "string",
OBJECT: "object",
@@ -2432,12 +2755,109 @@
RESIZE: "zoid-resize",
FOCUS: "zoid-focus"
};
+ function buildChildWindowName(_ref) {
+ return "__zoid__" + _ref.name + "__" + _ref.serializedPayload + "__";
+ }
+ function parseWindowName(windowName) {
+ if (!windowName) throw new Error("No window name");
+ var _windowName$split = windowName.split("__"), zoidcomp = _windowName$split[1], name = _windowName$split[2], serializedInitialPayload = _windowName$split[3];
+ if ("zoid" !== zoidcomp) throw new Error("Window not rendered by zoid - got " + zoidcomp);
+ if (!name) throw new Error("Expected component name");
+ if (!serializedInitialPayload) throw new Error("Expected serialized payload ref");
+ return {
+ name: name,
+ serializedInitialPayload: serializedInitialPayload
+ };
+ }
+ var parseInitialParentPayload = memoize((function(windowName) {
+ var _crossDomainDeseriali = crossDomainDeserialize({
+ data: parseWindowName(windowName).serializedInitialPayload,
+ sender: {
+ win: function(_ref2) {
+ return function(windowRef) {
+ if ("opener" === windowRef.type) return assertExists("opener", getOpener(window));
+ if ("parent" === windowRef.type && "number" == typeof windowRef.distance) return assertExists("parent", function(win, n) {
+ void 0 === n && (n = 1);
+ return function(win, n) {
+ void 0 === n && (n = 1);
+ var parent = win;
+ for (var i = 0; i < n; i++) {
+ if (!parent) return;
+ parent = utils_getParent(parent);
+ }
+ return parent;
+ }(win, getDistanceFromTop(win) - n);
+ }(window, windowRef.distance));
+ if ("global" === windowRef.type && windowRef.uid && "string" == typeof windowRef.uid) {
+ var _ret = function() {
+ var uid = windowRef.uid;
+ var ancestor = getAncestor(window);
+ if (!ancestor) throw new Error("Can not find ancestor window");
+ for (var _i2 = 0, _getAllFramesInWindow2 = getAllFramesInWindow(ancestor); _i2 < _getAllFramesInWindow2.length; _i2++) {
+ var frame = _getAllFramesInWindow2[_i2];
+ if (isSameDomain(frame)) {
+ var win = tryGlobal(frame, (function(global) {
+ return global.windows && global.windows[uid];
+ }));
+ if (win) return {
+ v: win
+ };
+ }
+ }
+ }();
+ if ("object" == typeof _ret) return _ret.v;
+ } else if ("name" === windowRef.type) {
+ var name = windowRef.name;
+ return assertExists("namedWindow", function(win, name) {
+ return getFrameByName(win, name) || function findChildFrameByName(win, name) {
+ var frame = getFrameByName(win, name);
+ if (frame) return frame;
+ for (var _i11 = 0, _getFrames4 = getFrames(win); _i11 < _getFrames4.length; _i11++) {
+ var namedFrame = findChildFrameByName(_getFrames4[_i11], name);
+ if (namedFrame) return namedFrame;
+ }
+ }(getTop(win) || win, name);
+ }(assertExists("ancestor", getAncestor(window)), name));
+ }
+ throw new Error("Unable to find " + windowRef.type + " parent component window");
+ }(_ref2.metaData.windowRef);
+ }
+ }
+ });
+ return {
+ parent: _crossDomainDeseriali.sender,
+ payload: _crossDomainDeseriali.data,
+ reference: _crossDomainDeseriali.reference
+ };
+ }));
+ function getInitialParentPayload() {
+ return parseInitialParentPayload(window.name);
+ }
+ function window_getWindowRef(targetWindow, currentWindow) {
+ void 0 === currentWindow && (currentWindow = window);
+ if (targetWindow === utils_getParent(currentWindow)) return {
+ type: "parent",
+ distance: getDistanceFromTop(targetWindow)
+ };
+ if (targetWindow === getOpener(currentWindow)) return {
+ type: "opener"
+ };
+ if (isSameDomain(targetWindow) && !(win = targetWindow, win === getTop(win))) {
+ var windowName = assertSameDomain(targetWindow).name;
+ if (windowName) return {
+ type: "name",
+ name: windowName
+ };
+ }
+ var win;
+ }
function normalizeChildProp(propsDef, props, key, value, helpers) {
if (!propsDef.hasOwnProperty(key)) return value;
var prop = propsDef[key];
return "function" == typeof prop.childDecorate ? prop.childDecorate({
value: value,
uid: helpers.uid,
+ tag: helpers.tag,
close: helpers.close,
focus: helpers.focus,
onError: helpers.onError,
@@ -2446,34 +2866,11 @@
getParent: helpers.getParent,
getParentDomain: helpers.getParentDomain,
show: helpers.show,
- hide: helpers.hide
+ hide: helpers.hide,
+ export: helpers.export,
+ getSiblings: helpers.getSiblings
}) : value;
}
- function parseChildWindowName(windowName) {
- return inlineMemoize(parseChildWindowName, (function() {
- if (!windowName) throw new Error("No window name");
- var _windowName$split = windowName.split("__"), zoidcomp = _windowName$split[1], name = _windowName$split[2], encodedPayload = _windowName$split[3];
- if ("zoid" !== zoidcomp) throw new Error("Window not rendered by zoid - got " + zoidcomp);
- if (!name) throw new Error("Expected component name");
- if (!encodedPayload) throw new Error("Expected encoded payload");
- try {
- return JSON.parse(function(str) {
- if ("function" == typeof atob) return decodeURIComponent([].map.call(atob(str), (function(c) {
- return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
- })).join(""));
- if ("undefined" != typeof Buffer) return Buffer.from(str, "base64").toString("utf8");
- throw new Error("Can not find window.atob or Buffer");
- }(encodedPayload));
- } catch (err) {
- throw new Error("Can not decode window name payload: " + encodedPayload + ": " + stringifyError(err));
- }
- }), [ windowName ]);
- }
- function getChildPayload() {
- try {
- return parseChildWindowName(window.name);
- } catch (err) {}
- }
function child_focus() {
return promise_ZalgoPromise.try((function() {
window.focus();
@@ -2484,33 +2881,88 @@
window.close();
}));
}
- function props_getQueryParam(prop, key, value) {
- return promise_ZalgoPromise.try((function() {
- return "function" == typeof prop.queryParam ? prop.queryParam({
- value: value
- }) : "string" == typeof prop.queryParam ? prop.queryParam : key;
- }));
+ var props_defaultNoop = function() {
+ return src_util_noop;
+ };
+ var props_decorateOnce = function(_ref) {
+ return once(_ref.value);
+ };
+ function eachProp(props, propsDef, handler) {
+ for (var _i2 = 0, _Object$keys2 = Object.keys(_extends({}, props, propsDef)); _i2 < _Object$keys2.length; _i2++) {
+ var key = _Object$keys2[_i2];
+ handler(key, propsDef[key], props[key]);
+ }
}
- function getQueryValue(prop, key, value) {
- return promise_ZalgoPromise.try((function() {
- return "function" == typeof prop.queryValue && isDefined(value) ? prop.queryValue({
- value: value
- }) : value;
+ function serializeProps(propsDef, props, method) {
+ var params = {};
+ return promise_ZalgoPromise.all(function(props, propsDef, handler) {
+ var results = [];
+ eachProp(props, propsDef, (function(key, propDef, value) {
+ var result = function(key, propDef, value) {
+ return promise_ZalgoPromise.resolve().then((function() {
+ var _METHOD$GET$METHOD$PO, _METHOD$GET$METHOD$PO2;
+ if (null != value && propDef) {
+ var getParam = (_METHOD$GET$METHOD$PO = {}, _METHOD$GET$METHOD$PO.get = propDef.queryParam,
+ _METHOD$GET$METHOD$PO.post = propDef.bodyParam, _METHOD$GET$METHOD$PO)[method];
+ var getValue = (_METHOD$GET$METHOD$PO2 = {}, _METHOD$GET$METHOD$PO2.get = propDef.queryValue,
+ _METHOD$GET$METHOD$PO2.post = propDef.bodyValue, _METHOD$GET$METHOD$PO2)[method];
+ if (getParam) return promise_ZalgoPromise.hash({
+ finalParam: promise_ZalgoPromise.try((function() {
+ return "function" == typeof getParam ? getParam({
+ value: value
+ }) : "string" == typeof getParam ? getParam : key;
+ })),
+ finalValue: promise_ZalgoPromise.try((function() {
+ return "function" == typeof getValue && isDefined(value) ? getValue({
+ value: value
+ }) : value;
+ }))
+ }).then((function(_ref) {
+ var finalParam = _ref.finalParam, finalValue = _ref.finalValue;
+ var result;
+ if ("boolean" == typeof finalValue) result = finalValue.toString(); else if ("string" == typeof finalValue) result = finalValue.toString(); else if ("object" == typeof finalValue && null !== finalValue) {
+ if (propDef.serialization === PROP_SERIALIZATION.JSON) result = JSON.stringify(finalValue); else if (propDef.serialization === PROP_SERIALIZATION.BASE64) result = base64encode(JSON.stringify(finalValue)); else if (propDef.serialization === PROP_SERIALIZATION.DOTIFY || !propDef.serialization) {
+ result = function dotify(obj, prefix, newobj) {
+ void 0 === prefix && (prefix = "");
+ void 0 === newobj && (newobj = {});
+ prefix = prefix ? prefix + "." : prefix;
+ for (var key in obj) obj.hasOwnProperty(key) && null != obj[key] && "function" != typeof obj[key] && (obj[key] && Array.isArray(obj[key]) && obj[key].length && obj[key].every((function(val) {
+ return "object" != typeof val;
+ })) ? newobj["" + prefix + key + "[]"] = obj[key].join(",") : obj[key] && "object" == typeof obj[key] ? newobj = dotify(obj[key], "" + prefix + key, newobj) : newobj["" + prefix + key] = obj[key].toString());
+ return newobj;
+ }(finalValue, key);
+ for (var _i2 = 0, _Object$keys2 = Object.keys(result); _i2 < _Object$keys2.length; _i2++) {
+ var dotkey = _Object$keys2[_i2];
+ params[dotkey] = result[dotkey];
+ }
+ return;
+ }
+ } else "number" == typeof finalValue && (result = finalValue.toString());
+ params[finalParam] = result;
+ }));
+ }
+ }));
+ }(key, propDef, value);
+ results.push(result);
+ }));
+ return results;
+ }(props, propsDef)).then((function() {
+ return params;
}));
}
- function parentComponent(options, overrides, parentWin) {
- void 0 === overrides && (overrides = {});
- void 0 === parentWin && (parentWin = window);
- var propsDef = options.propsDef, containerTemplate = options.containerTemplate, prerenderTemplate = options.prerenderTemplate, tag = options.tag, name = options.name, attributes = options.attributes, dimensions = options.dimensions, autoResize = options.autoResize, url = options.url, domainMatch = options.domain;
+ function parentComponent(_ref) {
+ var uid = _ref.uid, options = _ref.options, _ref$overrides = _ref.overrides, overrides = void 0 === _ref$overrides ? {} : _ref$overrides, _ref$parentWin = _ref.parentWin, parentWin = void 0 === _ref$parentWin ? window : _ref$parentWin;
+ var propsDef = options.propsDef, containerTemplate = options.containerTemplate, prerenderTemplate = options.prerenderTemplate, tag = options.tag, name = options.name, attributes = options.attributes, dimensions = options.dimensions, autoResize = options.autoResize, url = options.url, domainMatch = options.domain, xports = options.exports;
var initPromise = new promise_ZalgoPromise;
var handledErrors = [];
var clean = cleanup();
var state = {};
+ var inputProps = {};
var internalState = {
visible: !0
};
var event = overrides.event ? overrides.event : (triggered = {}, handlers = {},
- {
+ emitter = {
on: function(eventName, handler) {
var handlerList = handlers[eventName] = handlers[eventName] || [];
handlerList.push(handler);
@@ -2525,7 +2977,7 @@
};
},
once: function(eventName, handler) {
- var listener = this.on(eventName, (function() {
+ var listener = emitter.on(eventName, (function() {
listener.cancel();
handler();
}));
@@ -2536,13 +2988,13 @@
var handlerList = handlers[eventName];
var promises = [];
if (handlerList) {
- var _loop = function(_i4) {
- var handler = handlerList[_i4];
+ var _loop = function(_i2) {
+ var handler = handlerList[_i2];
promises.push(promise_ZalgoPromise.try((function() {
return handler.apply(void 0, args);
})));
};
- for (var _i4 = 0; _i4 < handlerList.length; _i4++) _loop(_i4);
+ for (var _i2 = 0; _i2 < handlerList.length; _i2++) _loop(_i2);
}
return promise_ZalgoPromise.all(promises).then(src_util_noop);
},
@@ -2550,17 +3002,19 @@
if (triggered[eventName]) return promise_ZalgoPromise.resolve();
triggered[eventName] = !0;
for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) args[_key4 - 1] = arguments[_key4];
- return this.trigger.apply(this, [ eventName ].concat(args));
+ return emitter.trigger.apply(emitter, [ eventName ].concat(args));
},
reset: function() {
handlers = {};
}
});
- var triggered, handlers;
+ var triggered, handlers, emitter;
var props = overrides.props ? overrides.props : {};
var currentProxyWin;
var currentProxyContainer;
var childComponent;
+ var currentChildDomain;
+ var currentContainer;
var onErrorOverride = overrides.onError;
var getProxyContainerOverride = overrides.getProxyContainer;
var showOverride = overrides.show;
@@ -2577,12 +3031,22 @@
var watchForUnloadOverride = overrides.watchForUnload;
var getInternalStateOverride = overrides.getInternalState;
var setInternalStateOverride = overrides.setInternalState;
- var getPropsForChild = function(domain) {
+ var resolveInitPromise = function() {
+ return promise_ZalgoPromise.try((function() {
+ return overrides.resolveInitPromise ? overrides.resolveInitPromise() : initPromise.resolve();
+ }));
+ };
+ var rejectInitPromise = function(err) {
+ return promise_ZalgoPromise.try((function() {
+ return overrides.rejectInitPromise ? overrides.rejectInitPromise(err) : initPromise.reject(err);
+ }));
+ };
+ var getPropsForChild = function(initialChildDomain) {
var result = {};
for (var _i2 = 0, _Object$keys2 = Object.keys(props); _i2 < _Object$keys2.length; _i2++) {
var key = _Object$keys2[_i2];
var prop = propsDef[key];
- prop && !1 === prop.sendToChild || prop && prop.sameDomain && !matchDomain(domain, getDomain(window)) || (result[key] = props[key]);
+ prop && !1 === prop.sendToChild || prop && prop.sameDomain && !matchDomain(initialChildDomain, getDomain(window)) || (result[key] = props[key]);
}
return promise_ZalgoPromise.hash(result);
};
@@ -2611,32 +3075,6 @@
});
}));
};
- var getProxyContainer = function(container) {
- return getProxyContainerOverride ? getProxyContainerOverride(container) : promise_ZalgoPromise.try((function() {
- return elementReady(container);
- })).then((function(containerElement) {
- isShadowElement(containerElement) && (containerElement = function(element) {
- var shadowHost = function(element) {
- var shadowRoot = function(element) {
- for (;element.parentNode; ) element = element.parentNode;
- if (isShadowElement(element)) return element;
- }(element);
- if (shadowRoot.host) return shadowRoot.host;
- }(element);
- if (!shadowHost) throw new Error("Element is not in shadow dom");
- if (isShadowElement(shadowHost)) throw new Error("Host element is also in shadow dom");
- var slotName = "shadow-slot-" + uniqueID();
- var slot = document.createElement("slot");
- slot.setAttribute("name", slotName);
- element.appendChild(slot);
- var slotProvider = document.createElement("div");
- slotProvider.setAttribute("slot", slotName);
- shadowHost.appendChild(slotProvider);
- return slotProvider;
- }(containerElement));
- return getProxyObject(containerElement);
- }));
- };
var setProxyWin = function(proxyWin) {
return setProxyWinOverride ? setProxyWinOverride(proxyWin) : promise_ZalgoPromise.try((function() {
currentProxyWin = proxyWin;
@@ -2668,14 +3106,11 @@
props: props
}) : attributes;
};
- var getChildDomain = function() {
- return domainMatch && "string" == typeof domainMatch ? domainMatch : getDomainFromUrl(getUrl());
+ var getInitialChildDomain = function() {
+ return getDomainFromUrl(getUrl());
};
- var getDomainMatcher = function() {
- return domainMatch && util_isRegex(domainMatch) ? domainMatch : getChildDomain();
- };
- var openFrame = function(context, _ref) {
- var windowName = _ref.windowName;
+ var openFrame = function(context, _ref2) {
+ var windowName = _ref2.windowName;
return openFrameOverride ? openFrameOverride(context, {
windowName: windowName
}) : promise_ZalgoPromise.try((function() {
@@ -2720,37 +3155,47 @@
if (currentProxyWin) return promise_ZalgoPromise.all([ event.trigger(EVENT.FOCUS), currentProxyWin.focus() ]).then(src_util_noop);
}));
};
- var getWindowRef = function(target, domain, uid, context) {
- if (domain === getDomain(window)) {
- var global = lib_global_getGlobal(window);
- global.windows = global.windows || {};
- global.windows[uid] = window;
- clean.register((function() {
- delete global.windows[uid];
- }));
- return {
- type: "global",
- uid: uid
- };
+ var getCurrentWindowReferenceUID = function() {
+ var global = lib_global_getGlobal(window);
+ global.windows = global.windows || {};
+ global.windows[uid] = window;
+ clean.register((function() {
+ delete global.windows[uid];
+ }));
+ return uid;
+ };
+ var getWindowRef = function(target, initialChildDomain, context, proxyWin) {
+ if (initialChildDomain === getDomain(window)) return {
+ type: "global",
+ uid: getCurrentWindowReferenceUID()
+ };
+ if (target !== window) throw new Error("Can not construct cross-domain window reference for different target window");
+ if (props.window) {
+ var actualComponentWindow = proxyWin.getWindow();
+ if (!actualComponentWindow) throw new Error("Can not construct cross-domain window reference for lazy window prop");
+ if (getAncestor(actualComponentWindow) !== window) throw new Error("Can not construct cross-domain window reference for window prop with different ancestor");
}
- return context === CONTEXT.POPUP ? {
+ if (context === CONTEXT.POPUP) return {
type: "opener"
- } : {
+ };
+ if (context === CONTEXT.IFRAME) return {
type: "parent",
distance: getDistanceFromTop(window)
};
+ throw new Error("Can not construct window reference for child");
};
- var initChild = function(childExports) {
+ var initChild = function(childDomain, childExports) {
return promise_ZalgoPromise.try((function() {
+ currentChildDomain = childDomain;
childComponent = childExports;
- initPromise.resolve();
+ resolveInitPromise();
clean.register((function() {
return childExports.close.fireAndForget().catch(src_util_noop);
}));
}));
};
- var resize = function(_ref2) {
- var width = _ref2.width, height = _ref2.height;
+ var resize = function(_ref3) {
+ var width = _ref3.width, height = _ref3.height;
return promise_ZalgoPromise.try((function() {
event.trigger(EVENT.RESIZE, {
width: width,
@@ -2762,47 +3207,35 @@
return promise_ZalgoPromise.try((function() {
return event.trigger(EVENT.DESTROY);
})).catch(src_util_noop).then((function() {
- return clean.all();
+ return clean.all(err);
})).then((function() {
initPromise.asyncReject(err || new Error("Component destroyed"));
}));
};
- var close = function() {
- return closeOverride ? closeOverride() : promise_ZalgoPromise.try((function() {
- return event.trigger(EVENT.CLOSE);
- })).then((function() {
- return destroy(new Error("Window closed"));
+ var close = memoize((function(err) {
+ return promise_ZalgoPromise.try((function() {
+ if (closeOverride) {
+ if (isWindowClosed(closeOverride.__source__)) return;
+ return closeOverride();
+ }
+ return promise_ZalgoPromise.try((function() {
+ return event.trigger(EVENT.CLOSE);
+ })).then((function() {
+ return destroy(err || new Error("Component closed"));
+ }));
}));
- };
- var open = function(context, _ref3) {
- var proxyWin = _ref3.proxyWin, proxyFrame = _ref3.proxyFrame;
+ }));
+ var open = function(context, _ref4) {
+ var proxyWin = _ref4.proxyWin, proxyFrame = _ref4.proxyFrame, windowName = _ref4.windowName;
return openOverride ? openOverride(context, {
proxyWin: proxyWin,
proxyFrame: proxyFrame,
- windowName: _ref3.windowName
+ windowName: windowName
}) : promise_ZalgoPromise.try((function() {
if (context === CONTEXT.IFRAME) {
if (!proxyFrame) throw new Error("Expected proxy frame to be passed");
return proxyFrame.get().then((function(frame) {
return awaitFrameWindow(frame).then((function(win) {
- var frameWatcher = function(element, handler) {
- handler = once(handler);
- var interval;
- isElementClosed(element) ? handler() : interval = safeInterval((function() {
- if (isElementClosed(element)) {
- interval.cancel();
- handler();
- }
- }), 50);
- return {
- cancel: function() {
- interval && interval.cancel();
- }
- };
- }(frame, close);
- clean.register((function() {
- return frameWatcher.cancel();
- }));
clean.register((function() {
return destroyElement(frame);
}));
@@ -2820,7 +3253,9 @@
proxyWin.setWindow(win, {
send: send_send
});
- return proxyWin;
+ return proxyWin.setName(windowName).then((function() {
+ return proxyWin;
+ }));
}));
};
var watchForUnload = function() {
@@ -2839,14 +3274,14 @@
return proxyWin.isClosed().then((function(isClosed) {
if (isClosed) {
closed = !0;
- return close();
+ return close(new Error("Detected component window close"));
}
return promise_ZalgoPromise.delay(200).then((function() {
return proxyWin.isClosed();
})).then((function(secondIsClosed) {
if (secondIsClosed) {
closed = !0;
- return close();
+ return close(new Error("Detected component window close"));
}
}));
})).then((function() {
@@ -2862,29 +3297,36 @@
}
}));
};
- initChild.onError = onError;
- var renderTemplate = function(renderer, _ref6) {
- return renderer({
- container: _ref6.container,
- context: _ref6.context,
- uid: _ref6.uid,
- doc: _ref6.doc,
- frame: _ref6.frame,
- prerenderFrame: _ref6.prerenderFrame,
+ var exportsPromise = new promise_ZalgoPromise;
+ var xport = function(actualExports) {
+ return promise_ZalgoPromise.try((function() {
+ exportsPromise.resolve(actualExports);
+ }));
+ };
+ initChild.onError = onError;
+ var renderTemplate = function(renderer, _ref8) {
+ return renderer({
+ uid: uid,
+ container: _ref8.container,
+ context: _ref8.context,
+ doc: _ref8.doc,
+ frame: _ref8.frame,
+ prerenderFrame: _ref8.prerenderFrame,
focus: focus,
close: close,
state: state,
props: props,
tag: tag,
- dimensions: dimensions,
+ dimensions: "function" == typeof dimensions ? dimensions({
+ props: props
+ }) : dimensions,
event: event
});
};
- var prerender = function(proxyPrerenderWin, _ref7) {
- var context = _ref7.context, uid = _ref7.uid;
+ var prerender = function(proxyPrerenderWin, _ref9) {
+ var context = _ref9.context;
return prerenderOverride ? prerenderOverride(proxyPrerenderWin, {
- context: context,
- uid: uid
+ context: context
}) : promise_ZalgoPromise.try((function() {
if (prerenderTemplate) {
var prerenderWindow = proxyPrerenderWin.getWindow();
@@ -2898,7 +3340,6 @@
var doc = (prerenderWindow = assertSameDomain(prerenderWindow)).document;
var el = renderTemplate(prerenderTemplate, {
context: context,
- uid: uid,
doc: doc
});
if (el) {
@@ -2912,10 +3353,10 @@
}(prerenderWindow, el);
var _autoResize$width = autoResize.width, width = void 0 !== _autoResize$width && _autoResize$width, _autoResize$height = autoResize.height, height = void 0 !== _autoResize$height && _autoResize$height, _autoResize$element = autoResize.element, element = void 0 === _autoResize$element ? "body" : _autoResize$element;
if ((element = getElementSafe(element, doc)) && (width || height)) {
- var prerenderResizeListener = onResize(element, (function(_ref8) {
+ var prerenderResizeListener = onResize(element, (function(_ref10) {
resize({
- width: width ? _ref8.width : void 0,
- height: height ? _ref8.height : void 0
+ width: width ? _ref10.width : void 0,
+ height: height ? _ref10.height : void 0
});
}), {
width: width,
@@ -2929,31 +3370,94 @@
}
}));
};
- var renderContainer = function(proxyContainer, _ref9) {
- var proxyFrame = _ref9.proxyFrame, proxyPrerenderFrame = _ref9.proxyPrerenderFrame, context = _ref9.context, uid = _ref9.uid;
+ var renderContainer = function(proxyContainer, _ref11) {
+ var proxyFrame = _ref11.proxyFrame, proxyPrerenderFrame = _ref11.proxyPrerenderFrame, context = _ref11.context, rerender = _ref11.rerender;
return renderContainerOverride ? renderContainerOverride(proxyContainer, {
proxyFrame: proxyFrame,
proxyPrerenderFrame: proxyPrerenderFrame,
context: context,
- uid: uid
+ rerender: rerender
}) : promise_ZalgoPromise.hash({
container: proxyContainer.get(),
frame: proxyFrame ? proxyFrame.get() : null,
prerenderFrame: proxyPrerenderFrame ? proxyPrerenderFrame.get() : null,
internalState: getInternalState()
- }).then((function(_ref10) {
- var container = _ref10.container, visible = _ref10.internalState.visible;
+ }).then((function(_ref12) {
+ var container = _ref12.container, visible = _ref12.internalState.visible;
var innerContainer = renderTemplate(containerTemplate, {
context: context,
- uid: uid,
container: container,
- frame: _ref10.frame,
- prerenderFrame: _ref10.prerenderFrame,
+ frame: _ref12.frame,
+ prerenderFrame: _ref12.prerenderFrame,
doc: document
});
if (innerContainer) {
visible || hideElement(innerContainer);
appendChild(container, innerContainer);
+ var containerWatcher = function(element, handler) {
+ handler = once(handler);
+ var cancelled = !1;
+ var mutationObservers = [];
+ var interval;
+ var sacrificialFrame;
+ var sacrificialFrameWin;
+ var cancel = function() {
+ cancelled = !0;
+ for (var _i18 = 0; _i18 < mutationObservers.length; _i18++) mutationObservers[_i18].disconnect();
+ interval && interval.cancel();
+ sacrificialFrameWin && sacrificialFrameWin.removeEventListener("unload", elementClosed);
+ sacrificialFrame && destroyElement(sacrificialFrame);
+ };
+ var elementClosed = function() {
+ if (!cancelled) {
+ handler();
+ cancel();
+ }
+ };
+ if (isElementClosed(element)) {
+ elementClosed();
+ return {
+ cancel: cancel
+ };
+ }
+ if (window.MutationObserver) {
+ var mutationElement = element.parentElement;
+ for (;mutationElement; ) {
+ var mutationObserver = new window.MutationObserver((function() {
+ isElementClosed(element) && elementClosed();
+ }));
+ mutationObserver.observe(mutationElement, {
+ childList: !0
+ });
+ mutationObservers.push(mutationObserver);
+ mutationElement = mutationElement.parentElement;
+ }
+ }
+ (sacrificialFrame = document.createElement("iframe")).setAttribute("name", "__detect_close_" + uniqueID() + "__");
+ sacrificialFrame.style.display = "none";
+ awaitFrameWindow(sacrificialFrame).then((function(frameWin) {
+ (sacrificialFrameWin = assertSameDomain(frameWin)).addEventListener("unload", elementClosed);
+ }));
+ element.appendChild(sacrificialFrame);
+ interval = safeInterval((function() {
+ isElementClosed(element) && elementClosed();
+ }), 1e3);
+ return {
+ cancel: cancel
+ };
+ }(innerContainer, (function() {
+ var removeError = new Error("Detected container element removed from DOM");
+ return promise_ZalgoPromise.delay(1).then((function() {
+ if (!isElementClosed(innerContainer)) {
+ clean.all(removeError);
+ return rerender().then(resolveInitPromise, rejectInitPromise);
+ }
+ close(removeError);
+ }));
+ }));
+ clean.register((function() {
+ return containerWatcher.cancel();
+ }));
clean.register((function() {
return destroyElement(innerContainer);
}));
@@ -2974,76 +3478,71 @@
hide: hide
};
};
- var setProps = function(newProps, isUpdate) {
- void 0 === isUpdate && (isUpdate = !1);
+ var setProps = function(newInputProps) {
+ void 0 === newInputProps && (newInputProps = {});
+ var container = currentContainer;
var helpers = getHelpers();
- !function(propsDef, props, inputProps, helpers, isUpdate) {
- void 0 === isUpdate && (isUpdate = !1);
- extend(props, inputProps = inputProps || {});
- var propNames = isUpdate ? [] : [].concat(Object.keys(propsDef));
- for (var _i2 = 0, _Object$keys2 = Object.keys(inputProps); _i2 < _Object$keys2.length; _i2++) {
- var key = _Object$keys2[_i2];
- -1 === propNames.indexOf(key) && propNames.push(key);
- }
- var aliases = [];
+ extend(inputProps, newInputProps);
+ !function(propsDef, existingProps, inputProps, helpers, container) {
var state = helpers.state, close = helpers.close, focus = helpers.focus, event = helpers.event, onError = helpers.onError;
- for (var _i4 = 0; _i4 < propNames.length; _i4++) {
- var _key = propNames[_i4];
- var propDef = propsDef[_key];
- var value = inputProps[_key];
- if (propDef) {
- var alias = propDef.alias;
- if (alias) {
- !isDefined(value) && isDefined(inputProps[alias]) && (value = inputProps[alias]);
- aliases.push(alias);
+ eachProp(inputProps, propsDef, (function(key, propDef, val) {
+ var valueDetermined = !1;
+ var value = val;
+ Object.defineProperty(existingProps, key, {
+ configurable: !0,
+ enumerable: !0,
+ get: function() {
+ if (valueDetermined) return value;
+ valueDetermined = !0;
+ return function() {
+ if (!propDef) return value;
+ var alias = propDef.alias;
+ alias && !isDefined(val) && isDefined(inputProps[alias]) && (value = inputProps[alias]);
+ propDef.value && (value = propDef.value({
+ props: existingProps,
+ state: state,
+ close: close,
+ focus: focus,
+ event: event,
+ onError: onError,
+ container: container
+ }));
+ !propDef.default || isDefined(value) || isDefined(inputProps[key]) || (value = propDef.default({
+ props: existingProps,
+ state: state,
+ close: close,
+ focus: focus,
+ event: event,
+ onError: onError,
+ container: container
+ }));
+ if (isDefined(value)) {
+ if (propDef.type === PROP_TYPE.ARRAY ? !Array.isArray(value) : typeof value !== propDef.type) throw new TypeError("Prop is not of type " + propDef.type + ": " + key);
+ } else if (!1 !== propDef.required && !isDefined(inputProps[key])) throw new Error('Expected prop "' + key + '" to be defined');
+ isDefined(value) && propDef.decorate && (value = propDef.decorate({
+ value: value,
+ props: existingProps,
+ state: state,
+ close: close,
+ focus: focus,
+ event: event,
+ onError: onError,
+ container: container
+ }));
+ return value;
+ }();
}
- propDef.value && (value = propDef.value({
- props: props,
- state: state,
- close: close,
- focus: focus,
- event: event,
- onError: onError
- }));
- !isDefined(value) && propDef.default && (value = propDef.default({
- props: props,
- state: state,
- close: close,
- focus: focus,
- event: event,
- onError: onError
- }));
- if (isDefined(value) && ("array" === propDef.type ? !Array.isArray(value) : typeof value !== propDef.type)) throw new TypeError("Prop is not of type " + propDef.type + ": " + _key);
- props[_key] = value;
- }
- }
- for (var _i6 = 0; _i6 < aliases.length; _i6++) delete props[aliases[_i6]];
- for (var _i8 = 0, _Object$keys4 = Object.keys(props); _i8 < _Object$keys4.length; _i8++) {
- var _key2 = _Object$keys4[_i8];
- var _propDef = propsDef[_key2];
- var _value = props[_key2];
- _propDef && isDefined(_value) && _propDef.decorate && (props[_key2] = _propDef.decorate({
- value: _value,
- props: props,
- state: state,
- close: close,
- focus: focus,
- event: event,
- onError: onError
- }));
- }
- for (var _i10 = 0, _Object$keys6 = Object.keys(propsDef); _i10 < _Object$keys6.length; _i10++) {
- var _key3 = _Object$keys6[_i10];
- if (!1 !== propsDef[_key3].required && !isDefined(props[_key3])) throw new Error('Expected prop "' + _key3 + '" to be defined');
- }
- }(propsDef, props, newProps, helpers, isUpdate);
+ });
+ }));
+ eachProp(existingProps, propsDef, src_util_noop);
+ }(propsDef, props, inputProps, helpers, container);
};
var updateProps = function(newProps) {
- setProps(newProps, !0);
+ setProps(newProps);
return initPromise.then((function() {
var child = childComponent;
var proxyWin = currentProxyWin;
- if (child && proxyWin) return getPropsForChild(getDomainMatcher()).then((function(childProps) {
+ if (child && proxyWin && currentChildDomain) return getPropsForChild(currentChildDomain).then((function(childProps) {
return child.updateProps(childProps).catch((function(err) {
return checkWindowClose(proxyWin).then((function(closed) {
if (!closed) throw err;
@@ -3052,6 +3551,32 @@
}));
}));
};
+ var getProxyContainer = function(container) {
+ return getProxyContainerOverride ? getProxyContainerOverride(container) : promise_ZalgoPromise.try((function() {
+ return elementReady(container);
+ })).then((function(containerElement) {
+ isShadowElement(containerElement) && (containerElement = function insertShadowSlot(element) {
+ var shadowHost = function(element) {
+ var shadowRoot = function(element) {
+ for (;element.parentNode; ) element = element.parentNode;
+ if (isShadowElement(element)) return element;
+ }(element);
+ if (shadowRoot && shadowRoot.host) return shadowRoot.host;
+ }(element);
+ if (!shadowHost) throw new Error("Element is not in shadow dom");
+ var slotName = "shadow-slot-" + uniqueID();
+ var slot = document.createElement("slot");
+ slot.setAttribute("name", slotName);
+ element.appendChild(slot);
+ var slotProvider = document.createElement("div");
+ slotProvider.setAttribute("slot", slotName);
+ shadowHost.appendChild(slotProvider);
+ return isShadowElement(shadowHost) ? insertShadowSlot(slotProvider) : slotProvider;
+ }(containerElement));
+ currentContainer = containerElement;
+ return getProxyObject(containerElement);
+ }));
+ };
return {
init: function() {
!function() {
@@ -3080,7 +3605,7 @@
return props.onProps(newProps);
}));
event.on(EVENT.ERROR, (function(err) {
- return props && props.onError ? props.onError(err) : initPromise.reject(err).then((function() {
+ return props && props.onError ? props.onError(err) : rejectInitPromise(err).then((function() {
setTimeout((function() {
throw err;
}), 1);
@@ -3089,19 +3614,19 @@
clean.register(event.reset);
}();
},
- render: function(target, container, context) {
+ render: function(_ref14) {
+ var target = _ref14.target, container = _ref14.container, context = _ref14.context, rerender = _ref14.rerender;
return promise_ZalgoPromise.try((function() {
- var uid = "zoid-" + tag + "-" + uniqueID();
- var domain = getDomainMatcher();
- var childDomain = getChildDomain();
- !function(target, domain, container) {
+ var initialChildDomain = getInitialChildDomain();
+ var childDomainMatch = domainMatch || getInitialChildDomain();
+ !function(target, childDomainMatch, container) {
if (target !== window) {
if (!isSameTopWindow(window, target)) throw new Error("Can only renderTo an adjacent frame");
var origin = getDomain();
- if (!matchDomain(domain, origin) && !isSameDomain(target)) throw new Error("Can not render remotely to " + domain.toString() + " - can only render to " + origin);
+ if (!matchDomain(childDomainMatch, origin) && !isSameDomain(target)) throw new Error("Can not render remotely to " + childDomainMatch.toString() + " - can only render to " + origin);
if (container && "string" != typeof container) throw new Error("Container passed to renderTo must be a string selector, got " + typeof container + " }");
}
- }(target, domain, container);
+ }(target, childDomainMatch, container);
var delegatePromise = promise_ZalgoPromise.try((function() {
if (target !== window) return function(context, target) {
var delegateProps = {};
@@ -3111,20 +3636,23 @@
propDef && propDef.allowDelegate && (delegateProps[propName] = props[propName]);
}
var childOverridesPromise = send_send(target, "zoid_delegate_" + name, {
+ uid: uid,
overrides: {
props: delegateProps,
event: event,
close: close,
onError: onError,
getInternalState: getInternalState,
- setInternalState: setInternalState
+ setInternalState: setInternalState,
+ resolveInitPromise: resolveInitPromise,
+ rejectInitPromise: rejectInitPromise
}
- }).then((function(_ref11) {
- var parent = _ref11.data.parent;
- clean.register((function() {
- if (!isWindowClosed(target)) return parent.destroy();
+ }).then((function(_ref13) {
+ var parentComp = _ref13.data.parent;
+ clean.register((function(err) {
+ if (!isWindowClosed(target)) return parentComp.destroy(err);
}));
- return parent.getDelegateOverrides();
+ return parentComp.getDelegateOverrides();
})).catch((function(err) {
throw new Error("Unable to delegate rendering. Possibly the component is not loaded in the target window.\n\n" + stringifyError(err));
}));
@@ -3201,134 +3729,110 @@
}));
var windowProp = props.window;
var watchForUnloadPromise = watchForUnload();
- var buildUrlPromise = function(propsDef, props) {
- var params = {};
- var keys = Object.keys(props);
- return promise_ZalgoPromise.all(keys.map((function(key) {
- var prop = propsDef[key];
- if (prop) return promise_ZalgoPromise.resolve().then((function() {
- var value = props[key];
- if (value && prop.queryParam) return value;
- })).then((function(value) {
- if (null != value) return promise_ZalgoPromise.all([ props_getQueryParam(prop, key, value), getQueryValue(prop, 0, value) ]).then((function(_ref) {
- var queryParam = _ref[0], queryValue = _ref[1];
- var result;
- if ("boolean" == typeof queryValue) result = queryValue.toString(); else if ("string" == typeof queryValue) result = queryValue.toString(); else if ("object" == typeof queryValue && null !== queryValue) {
- if (prop.serialization === PROP_SERIALIZATION.JSON) result = JSON.stringify(queryValue); else if (prop.serialization === PROP_SERIALIZATION.BASE64) result = btoa(JSON.stringify(queryValue)); else if (prop.serialization === PROP_SERIALIZATION.DOTIFY || !prop.serialization) {
- result = function dotify(obj, prefix, newobj) {
- void 0 === prefix && (prefix = "");
- void 0 === newobj && (newobj = {});
- prefix = prefix ? prefix + "." : prefix;
- for (var key in obj) obj.hasOwnProperty(key) && null != obj[key] && "function" != typeof obj[key] && (obj[key] && Array.isArray(obj[key]) && obj[key].length && obj[key].every((function(val) {
- return "object" != typeof val;
- })) ? newobj["" + prefix + key + "[]"] = obj[key].join(",") : obj[key] && "object" == typeof obj[key] ? newobj = dotify(obj[key], "" + prefix + key, newobj) : newobj["" + prefix + key] = obj[key].toString());
- return newobj;
- }(queryValue, key);
- for (var _i12 = 0, _Object$keys8 = Object.keys(result); _i12 < _Object$keys8.length; _i12++) {
- var dotkey = _Object$keys8[_i12];
- params[dotkey] = result[dotkey];
- }
- return;
- }
- } else "number" == typeof queryValue && (result = queryValue.toString());
- params[queryParam] = result;
- }));
- }));
- }))).then((function() {
- return params;
- }));
- }(propsDef, props).then((function(query) {
- return function(url, options) {
- var query = options.query || {};
- var hash = options.hash || {};
- var originalUrl;
- var originalHash;
- var _url$split = url.split("#");
- originalHash = _url$split[1];
- var _originalUrl$split = (originalUrl = _url$split[0]).split("?");
- originalUrl = _originalUrl$split[0];
- var queryString = extendQuery(_originalUrl$split[1], query);
- var hashString = extendQuery(originalHash, hash);
- queryString && (originalUrl = originalUrl + "?" + queryString);
- hashString && (originalUrl = originalUrl + "#" + hashString);
- return originalUrl;
- }(function(url) {
- if (!(domain = getDomainFromUrl(url), 0 === domain.indexOf("mock:"))) return url;
- var domain;
- throw new Error("Mock urls not supported out of test mode");
- }(getUrl()), {
- query: query
- });
- }));
+ var buildBodyPromise = serializeProps(propsDef, props, "post");
var onRenderPromise = event.trigger(EVENT.RENDER);
var getProxyContainerPromise = getProxyContainer(container);
var getProxyWindowPromise = getProxyWindow();
+ var finalSetPropsPromise = getProxyContainerPromise.then((function() {
+ return setProps();
+ }));
+ var buildUrlPromise = finalSetPropsPromise.then((function() {
+ return serializeProps(propsDef, props, "get").then((function(query) {
+ return function(url, options) {
+ var query = options.query || {};
+ var hash = options.hash || {};
+ var originalUrl;
+ var originalHash;
+ var _url$split = url.split("#");
+ originalHash = _url$split[1];
+ var _originalUrl$split = (originalUrl = _url$split[0]).split("?");
+ originalUrl = _originalUrl$split[0];
+ var queryString = extendQuery(_originalUrl$split[1], query);
+ var hashString = extendQuery(originalHash, hash);
+ queryString && (originalUrl = originalUrl + "?" + queryString);
+ hashString && (originalUrl = originalUrl + "#" + hashString);
+ return originalUrl;
+ }(function(url) {
+ if (!(domain = getDomainFromUrl(url), 0 === domain.indexOf("mock:"))) return url;
+ var domain;
+ throw new Error("Mock urls not supported out of test mode");
+ }(getUrl()), {
+ query: query
+ });
+ }));
+ }));
var buildWindowNamePromise = getProxyWindowPromise.then((function(proxyWin) {
- return function(_temp) {
- var _ref4 = void 0 === _temp ? {} : _temp, proxyWin = _ref4.proxyWin, childDomain = _ref4.childDomain, domain = _ref4.domain, context = (void 0 === _ref4.target && window,
- _ref4.context), uid = _ref4.uid;
- return function(proxyWin, childDomain, domain, uid) {
- return getPropsForChild(domain).then((function(childProps) {
- var value = setup_serializeMessage(proxyWin, domain, childProps);
- var propRef = childDomain === getDomain() ? {
- type: "uid",
- uid: uid
- } : {
- type: "raw",
- value: value
+ return function(_temp2) {
+ var _ref6 = void 0 === _temp2 ? {} : _temp2, proxyWin = _ref6.proxyWin, initialChildDomain = _ref6.initialChildDomain, childDomainMatch = _ref6.childDomainMatch, _ref6$target = _ref6.target, target = void 0 === _ref6$target ? window : _ref6$target, context = _ref6.context;
+ return function(_temp) {
+ var _ref5 = void 0 === _temp ? {} : _temp, proxyWin = _ref5.proxyWin, childDomainMatch = _ref5.childDomainMatch, context = _ref5.context;
+ return getPropsForChild(_ref5.initialChildDomain).then((function(childProps) {
+ return {
+ uid: uid,
+ context: context,
+ tag: tag,
+ childDomainMatch: childDomainMatch,
+ version: "9_0_86",
+ props: childProps,
+ exports: (win = proxyWin, {
+ init: function(childExports) {
+ return initChild(this.origin, childExports);
+ },
+ close: close,
+ checkClose: function() {
+ return checkWindowClose(win);
+ },
+ resize: resize,
+ onError: onError,
+ show: show,
+ hide: hide,
+ export: xport
+ })
};
- if ("uid" === propRef.type) {
- var global = lib_global_getGlobal(window);
- global.props = global.props || {};
- global.props[uid] = value;
- clean.register((function() {
- delete global.props[uid];
- }));
- }
- return propRef;
+ var win;
}));
- }(proxyWin, childDomain, domain, uid).then((function(propsRef) {
- return {
- uid: uid,
- context: context,
- tag: tag,
- version: "9_0_58",
- childDomain: childDomain,
- parentDomain: getDomain(window),
- parent: getWindowRef(0, childDomain, uid, context),
- props: propsRef,
- exports: setup_serializeMessage(proxyWin, domain, (win = proxyWin, {
- init: initChild,
- close: close,
- checkClose: function() {
- return checkWindowClose(win);
- },
- resize: resize,
- onError: onError,
- show: show,
- hide: hide
- }))
- };
- var win;
+ }({
+ proxyWin: proxyWin,
+ initialChildDomain: initialChildDomain,
+ childDomainMatch: childDomainMatch,
+ context: context
+ }).then((function(childPayload) {
+ var _crossDomainSerialize = crossDomainSerialize({
+ data: childPayload,
+ metaData: {
+ windowRef: getWindowRef(target, initialChildDomain, context, proxyWin)
+ },
+ sender: {
+ domain: getDomain(window)
+ },
+ receiver: {
+ win: proxyWin,
+ domain: childDomainMatch
+ },
+ passByReference: initialChildDomain === getDomain()
+ }), serializedData = _crossDomainSerialize.serializedData;
+ clean.register(_crossDomainSerialize.cleanReference);
+ return serializedData;
}));
}({
- proxyWin: (_ref5 = {
+ proxyWin: (_ref7 = {
proxyWin: proxyWin,
- childDomain: childDomain,
- domain: domain,
+ initialChildDomain: initialChildDomain,
+ childDomainMatch: childDomainMatch,
target: target,
- context: context,
- uid: uid
+ context: context
}).proxyWin,
- childDomain: _ref5.childDomain,
- domain: _ref5.domain,
- target: _ref5.target,
- context: _ref5.context,
- uid: _ref5.uid
- }).then((function(childPayload) {
- return "__zoid__" + name + "__" + base64encode(JSON.stringify(childPayload)) + "__";
+ initialChildDomain: _ref7.initialChildDomain,
+ childDomainMatch: _ref7.childDomainMatch,
+ target: _ref7.target,
+ context: _ref7.context
+ }).then((function(serializedPayload) {
+ return buildChildWindowName({
+ name: name,
+ serializedPayload: serializedPayload
+ });
}));
- var _ref5;
+ var _ref7;
}));
var openFramePromise = buildWindowNamePromise.then((function(windowName) {
return openFrame(context, {
@@ -3340,12 +3844,12 @@
proxyContainer: getProxyContainerPromise,
proxyFrame: openFramePromise,
proxyPrerenderFrame: openPrerenderFramePromise
- }).then((function(_ref12) {
- return renderContainer(_ref12.proxyContainer, {
+ }).then((function(_ref15) {
+ return renderContainer(_ref15.proxyContainer, {
context: context,
- uid: uid,
- proxyFrame: _ref12.proxyFrame,
- proxyPrerenderFrame: _ref12.proxyPrerenderFrame
+ proxyFrame: _ref15.proxyFrame,
+ proxyPrerenderFrame: _ref15.proxyPrerenderFrame,
+ rerender: rerender
});
})).then((function(proxyContainer) {
return proxyContainer;
@@ -3354,19 +3858,19 @@
windowName: buildWindowNamePromise,
proxyFrame: openFramePromise,
proxyWin: getProxyWindowPromise
- }).then((function(_ref13) {
- var proxyWin = _ref13.proxyWin;
+ }).then((function(_ref16) {
+ var proxyWin = _ref16.proxyWin;
return windowProp ? proxyWin : open(context, {
- windowName: _ref13.windowName,
+ windowName: _ref16.windowName,
proxyWin: proxyWin,
- proxyFrame: _ref13.proxyFrame
+ proxyFrame: _ref16.proxyFrame
});
}));
var openPrerenderPromise = promise_ZalgoPromise.hash({
proxyWin: openPromise,
proxyPrerenderFrame: openPrerenderFramePromise
- }).then((function(_ref14) {
- return openPrerender(context, _ref14.proxyWin, _ref14.proxyPrerenderFrame);
+ }).then((function(_ref17) {
+ return openPrerender(context, _ref17.proxyWin, _ref17.proxyPrerenderFrame);
}));
var setStatePromise = openPromise.then((function(proxyWin) {
currentProxyWin = proxyWin;
@@ -3375,28 +3879,37 @@
var prerenderPromise = promise_ZalgoPromise.hash({
proxyPrerenderWin: openPrerenderPromise,
state: setStatePromise
- }).then((function(_ref15) {
- return prerender(_ref15.proxyPrerenderWin, {
- context: context,
- uid: uid
+ }).then((function(_ref18) {
+ return prerender(_ref18.proxyPrerenderWin, {
+ context: context
});
}));
var setWindowNamePromise = promise_ZalgoPromise.hash({
proxyWin: openPromise,
windowName: buildWindowNamePromise
- }).then((function(_ref16) {
- if (windowProp) return _ref16.proxyWin.setName(_ref16.windowName);
+ }).then((function(_ref19) {
+ if (windowProp) return _ref19.proxyWin.setName(_ref19.windowName);
+ }));
+ var getMethodPromise = promise_ZalgoPromise.hash({
+ body: buildBodyPromise
+ }).then((function(_ref20) {
+ return options.method ? options.method : Object.keys(_ref20.body).length ? "post" : "get";
}));
var loadUrlPromise = promise_ZalgoPromise.hash({
proxyWin: openPromise,
- builtUrl: buildUrlPromise,
+ windowUrl: buildUrlPromise,
+ body: buildBodyPromise,
+ method: getMethodPromise,
windowName: setWindowNamePromise,
prerender: prerenderPromise
- }).then((function(_ref17) {
- return _ref17.proxyWin.setLocation(_ref17.builtUrl);
+ }).then((function(_ref21) {
+ return _ref21.proxyWin.setLocation(_ref21.windowUrl, {
+ method: _ref21.method,
+ body: _ref21.body
+ });
}));
var watchForClosePromise = openPromise.then((function(proxyWin) {
- !function watchForClose(proxyWin) {
+ !function watchForClose(proxyWin, context) {
var cancelled = !1;
clean.register((function() {
cancelled = !0;
@@ -3404,9 +3917,9 @@
return promise_ZalgoPromise.delay(2e3).then((function() {
return proxyWin.isClosed();
})).then((function(isClosed) {
- return isClosed ? close() : cancelled ? void 0 : watchForClose(proxyWin);
+ if (!cancelled) return isClosed ? close(new Error("Detected " + context + " close")) : watchForClose(proxyWin, context);
}));
- }(proxyWin);
+ }(proxyWin, context);
}));
var onDisplayPromise = promise_ZalgoPromise.hash({
container: renderContainerPromise,
@@ -3445,7 +3958,8 @@
runTimeoutPromise: runTimeoutPromise,
onRenderedPromise: onRenderedPromise,
delegatePromise: delegatePromise,
- watchForUnloadPromise: watchForUnloadPromise
+ watchForUnloadPromise: watchForUnloadPromise,
+ finalSetPropsPromise: finalSetPropsPromise
});
})).catch((function(err) {
return promise_ZalgoPromise.all([ onError(err), destroy(err) ]).then((function() {
@@ -3456,7 +3970,11 @@
})).then(src_util_noop);
},
destroy: destroy,
+ getProps: function() {
+ return props;
+ },
setProps: setProps,
+ export: xport,
getHelpers: getHelpers,
getDelegateOverrides: function() {
return promise_ZalgoPromise.try((function() {
@@ -3475,11 +3993,19 @@
setProxyWin: setProxyWin
};
}));
+ },
+ getExports: function() {
+ return xports({
+ getExports: function() {
+ return exportsPromise;
+ }
+ });
}
};
}
function defaultContainerTemplate(_ref) {
- var uid = _ref.uid, frame = _ref.frame, prerenderFrame = _ref.prerenderFrame, doc = _ref.doc, props = _ref.props, event = _ref.event, _ref$dimensions = _ref.dimensions, width = _ref$dimensions.width, height = _ref$dimensions.height;
+ var uid = _ref.uid, frame = _ref.frame, prerenderFrame = _ref.prerenderFrame, doc = _ref.doc, props = _ref.props, event = _ref.event, dimensions = _ref.dimensions;
+ var width = dimensions.width, height = dimensions.height;
if (frame && prerenderFrame) {
var div = doc.createElement("div");
div.setAttribute("id", uid);
@@ -3508,27 +4034,23 @@
return div;
}
}
- var props_defaultNoop = function() {
- return src_util_noop;
- };
- var props_decorateOnce = function(_ref) {
- return once(_ref.value);
- };
- var component_clean = cleanup();
- function component_component(opts) {
+ var cleanInstances = cleanup();
+ var cleanZoid = cleanup();
+ function component(opts) {
var options = function(options) {
- var tag = options.tag, url = options.url, domain = options.domain, bridgeUrl = options.bridgeUrl, _options$props = options.props, propsDef = void 0 === _options$props ? {} : _options$props, _options$dimensions = options.dimensions, dimensions = void 0 === _options$dimensions ? {} : _options$dimensions, _options$autoResize = options.autoResize, autoResize = void 0 === _options$autoResize ? {} : _options$autoResize, _options$allowedParen = options.allowedParentDomains, allowedParentDomains = void 0 === _options$allowedParen ? "*" : _options$allowedParen, _options$attributes = options.attributes, attributes = void 0 === _options$attributes ? {} : _options$attributes, _options$defaultConte = options.defaultContext, defaultContext = void 0 === _options$defaultConte ? CONTEXT.IFRAME : _options$defaultConte, _options$containerTem = options.containerTemplate, containerTemplate = void 0 === _options$containerTem ? defaultContainerTemplate : _options$containerTem, _options$prerenderTem = options.prerenderTemplate, prerenderTemplate = void 0 === _options$prerenderTem ? null : _options$prerenderTem, validate = options.validate, _options$eligible = options.eligible, eligible = void 0 === _options$eligible ? function() {
+ var tag = options.tag, url = options.url, domain = options.domain, bridgeUrl = options.bridgeUrl, _options$props = options.props, props = void 0 === _options$props ? {} : _options$props, _options$dimensions = options.dimensions, dimensions = void 0 === _options$dimensions ? {} : _options$dimensions, _options$autoResize = options.autoResize, autoResize = void 0 === _options$autoResize ? {} : _options$autoResize, _options$allowedParen = options.allowedParentDomains, allowedParentDomains = void 0 === _options$allowedParen ? "*" : _options$allowedParen, _options$attributes = options.attributes, attributes = void 0 === _options$attributes ? {} : _options$attributes, _options$defaultConte = options.defaultContext, defaultContext = void 0 === _options$defaultConte ? CONTEXT.IFRAME : _options$defaultConte, _options$containerTem = options.containerTemplate, containerTemplate = void 0 === _options$containerTem ? defaultContainerTemplate : _options$containerTem, _options$prerenderTem = options.prerenderTemplate, prerenderTemplate = void 0 === _options$prerenderTem ? null : _options$prerenderTem, validate = options.validate, _options$eligible = options.eligible, eligible = void 0 === _options$eligible ? function() {
return {
eligible: !0
};
} : _options$eligible, _options$logger = options.logger, logger = void 0 === _options$logger ? {
info: src_util_noop
- } : _options$logger;
+ } : _options$logger, _options$exports = options.exports, xportsDefinition = void 0 === _options$exports ? src_util_noop : _options$exports, method = options.method, _options$children = options.children, children = void 0 === _options$children ? function() {
+ return {};
+ } : _options$children;
var name = tag.replace(/-/g, "_");
- var _dimensions$width = dimensions.width, width = void 0 === _dimensions$width ? "300px" : _dimensions$width, _dimensions$height = dimensions.height, height = void 0 === _dimensions$height ? "150px" : _dimensions$height;
- propsDef = _extends({}, {
+ var propsDef = _extends({}, {
window: {
- type: "object",
+ type: PROP_TYPE.OBJECT,
sendToChild: !1,
required: !1,
allowDelegate: !0,
@@ -3545,12 +4067,68 @@
}
},
timeout: {
- type: "number",
+ type: PROP_TYPE.NUMBER,
required: !1,
sendToChild: !1
},
+ cspNonce: {
+ type: PROP_TYPE.STRING,
+ required: !1
+ },
+ onDisplay: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ allowDelegate: !0,
+ default: props_defaultNoop,
+ decorate: props_decorateOnce
+ },
+ onRendered: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ default: props_defaultNoop,
+ decorate: props_decorateOnce
+ },
+ onRender: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ default: props_defaultNoop,
+ decorate: props_decorateOnce
+ },
+ onClose: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ allowDelegate: !0,
+ default: props_defaultNoop,
+ decorate: props_decorateOnce
+ },
+ onDestroy: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ allowDelegate: !0,
+ default: props_defaultNoop,
+ decorate: props_decorateOnce
+ },
+ onResize: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ allowDelegate: !0,
+ default: props_defaultNoop
+ },
+ onFocus: {
+ type: PROP_TYPE.FUNCTION,
+ required: !1,
+ sendToChild: !1,
+ allowDelegate: !0,
+ default: props_defaultNoop
+ },
close: {
- type: "function",
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref4) {
@@ -3558,7 +4136,7 @@
}
},
focus: {
- type: "function",
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref5) {
@@ -3566,7 +4144,7 @@
}
},
resize: {
- type: "function",
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref6) {
@@ -3574,119 +4152,86 @@
}
},
uid: {
- type: "string",
+ type: PROP_TYPE.STRING,
required: !1,
sendToChild: !1,
childDecorate: function(_ref7) {
return _ref7.uid;
}
},
- cspNonce: {
- type: "string",
- required: !1
- },
- getParent: {
- type: "function",
+ tag: {
+ type: PROP_TYPE.STRING,
required: !1,
sendToChild: !1,
childDecorate: function(_ref8) {
- return _ref8.getParent;
+ return _ref8.tag;
}
},
- getParentDomain: {
- type: "function",
+ getParent: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref9) {
- return _ref9.getParentDomain;
+ return _ref9.getParent;
}
},
- show: {
- type: "function",
+ getParentDomain: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref10) {
- return _ref10.show;
+ return _ref10.getParentDomain;
}
},
- hide: {
- type: "function",
+ show: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
childDecorate: function(_ref11) {
- return _ref11.hide;
+ return _ref11.show;
}
},
- onDisplay: {
- type: "function",
- required: !1,
- sendToChild: !1,
- allowDelegate: !0,
- default: props_defaultNoop,
- decorate: props_decorateOnce
- },
- onRendered: {
- type: "function",
- required: !1,
- sendToChild: !1,
- default: props_defaultNoop,
- decorate: props_decorateOnce
- },
- onRender: {
- type: "function",
- required: !1,
- sendToChild: !1,
- default: props_defaultNoop,
- decorate: props_decorateOnce
- },
- onClose: {
- type: "function",
- required: !1,
- sendToChild: !1,
- allowDelegate: !0,
- default: props_defaultNoop,
- decorate: props_decorateOnce
- },
- onDestroy: {
- type: "function",
+ hide: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
- allowDelegate: !0,
- default: props_defaultNoop,
- decorate: props_decorateOnce
+ childDecorate: function(_ref12) {
+ return _ref12.hide;
+ }
},
- onResize: {
- type: "function",
+ export: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
- allowDelegate: !0,
- default: props_defaultNoop
+ childDecorate: function(_ref13) {
+ return _ref13.export;
+ }
},
- onFocus: {
- type: "function",
+ onError: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
- allowDelegate: !0,
- default: props_defaultNoop
+ childDecorate: function(_ref14) {
+ return _ref14.onError;
+ }
},
- onError: {
- type: "function",
+ onProps: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
- childDecorate: function(_ref12) {
- return _ref12.onError;
+ childDecorate: function(_ref15) {
+ return _ref15.onProps;
}
},
- onProps: {
- type: "function",
+ getSiblings: {
+ type: PROP_TYPE.FUNCTION,
required: !1,
sendToChild: !1,
- default: props_defaultNoop,
- childDecorate: function(_ref13) {
- return _ref13.onProps;
+ childDecorate: function(_ref16) {
+ return _ref16.getSiblings;
}
}
- }, propsDef);
+ }, props);
if (!containerTemplate) throw new Error("Container template required");
return {
name: name,
@@ -3694,11 +4239,9 @@
url: url,
domain: domain,
bridgeUrl: bridgeUrl,
+ method: method,
propsDef: propsDef,
- dimensions: {
- width: width,
- height: height
- },
+ dimensions: dimensions,
autoResize: autoResize,
allowedParentDomains: allowedParentDomains,
attributes: attributes,
@@ -3707,15 +4250,43 @@
prerenderTemplate: prerenderTemplate,
validate: validate,
logger: logger,
- eligible: eligible
+ eligible: eligible,
+ children: children,
+ exports: "function" == typeof xportsDefinition ? xportsDefinition : function(_ref) {
+ var getExports = _ref.getExports;
+ var result = {};
+ var _loop = function(_i2, _Object$keys2) {
+ var key = _Object$keys2[_i2];
+ var type = xportsDefinition[key].type;
+ var valuePromise = getExports().then((function(res) {
+ return res[key];
+ }));
+ result[key] = type === PROP_TYPE.FUNCTION ? function() {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
+ return valuePromise.then((function(value) {
+ return value.apply(void 0, args);
+ }));
+ } : valuePromise;
+ };
+ for (var _i2 = 0, _Object$keys2 = Object.keys(xportsDefinition); _i2 < _Object$keys2.length; _i2++) _loop(_i2, _Object$keys2);
+ return result;
+ }
};
}(opts);
- var name = options.name, tag = options.tag, defaultContext = options.defaultContext, eligible = options.eligible;
- var global = lib_global_getGlobal();
+ var name = options.name, tag = options.tag, defaultContext = options.defaultContext, eligible = options.eligible, children = options.children;
+ var global = lib_global_getGlobal(window);
var instances = [];
var isChild = function() {
- var payload = getChildPayload();
- return Boolean(payload && payload.tag === tag && payload.childDomain === getDomain());
+ if (function(name) {
+ try {
+ return parseWindowName(window.name).name === name;
+ } catch (err) {}
+ return !1;
+ }(name)) {
+ var _payload = getInitialParentPayload().payload;
+ if (_payload.tag === tag && matchDomain(_payload.childDomainMatch, getDomain())) return !0;
+ }
+ return !1;
};
var registerChild = memoize((function() {
if (isChild()) {
@@ -3724,44 +4295,15 @@
throw new Error("Can not register " + name + " as child - child already registered");
}
var child = function(options) {
- var propsDef = options.propsDef, autoResize = options.autoResize, allowedParentDomains = options.allowedParentDomains;
+ var tag = options.tag, propsDef = options.propsDef, autoResize = options.autoResize, allowedParentDomains = options.allowedParentDomains;
var onPropHandlers = [];
- var childPayload = getChildPayload();
+ var _getInitialParentPayl = getInitialParentPayload(), parent = _getInitialParentPayl.parent, payload = _getInitialParentPayl.payload;
+ var parentComponentWindow = parent.win, parentDomain = parent.domain;
var props;
- if (!childPayload) throw new Error("No child payload found");
- if ("9_0_58" !== childPayload.version) throw new Error("Parent window has zoid version " + childPayload.version + ", child window has version 9_0_58");
- var uid = childPayload.uid, parentDomain = childPayload.parentDomain, exports = childPayload.exports, context = childPayload.context, propsRef = childPayload.props;
- var parentComponentWindow = function(ref) {
- var type = ref.type;
- if ("opener" === type) return assertExists("opener", getOpener(window));
- if ("parent" === type && "number" == typeof ref.distance) return assertExists("parent", function(win, n) {
- void 0 === n && (n = 1);
- return function(win, n) {
- void 0 === n && (n = 1);
- var parent = win;
- for (var i = 0; i < n; i++) {
- if (!parent) return;
- parent = utils_getParent(parent);
- }
- return parent;
- }(win, getDistanceFromTop(win) - n);
- }(window, ref.distance));
- if ("global" === type && ref.uid && "string" == typeof ref.uid) {
- var uid = ref.uid;
- var ancestor = getAncestor(window);
- if (!ancestor) throw new Error("Can not find ancestor window");
- for (var _i2 = 0, _getAllFramesInWindow2 = getAllFramesInWindow(ancestor); _i2 < _getAllFramesInWindow2.length; _i2++) {
- var frame = _getAllFramesInWindow2[_i2];
- if (isSameDomain(frame)) {
- var global = lib_global_getGlobal(frame);
- if (global && global.windows && global.windows[uid]) return global.windows[uid];
- }
- }
- }
- throw new Error("Unable to find " + type + " parent component window");
- }(childPayload.parent);
- var parent = setup_deserializeMessage(parentComponentWindow, parentDomain, exports);
- var show = parent.show, hide = parent.hide, close = parent.close;
+ var exportsPromise = new promise_ZalgoPromise;
+ var version = payload.version, uid = payload.uid, parentExports = payload.exports, context = payload.context, initialProps = payload.props;
+ if ("9_0_86" !== version) throw new Error("Parent window has zoid version " + version + ", child window has version 9_0_86");
+ var show = parentExports.show, hide = parentExports.hide, close = parentExports.close, onError = parentExports.onError, checkClose = parentExports.checkClose, parentExport = parentExports.export, parentResize = parentExports.resize, parentInit = parentExports.init;
var getParent = function() {
return parentComponentWindow;
};
@@ -3770,19 +4312,48 @@
};
var onProps = function(handler) {
onPropHandlers.push(handler);
+ return {
+ cancel: function() {
+ onPropHandlers.splice(onPropHandlers.indexOf(handler), 1);
+ }
+ };
};
- var onError = function(err) {
- return promise_ZalgoPromise.try((function() {
- if (parent && parent.onError) return parent.onError(err);
- throw err;
- }));
- };
- var resize = function(_ref2) {
- return parent.resize.fireAndForget({
- width: _ref2.width,
- height: _ref2.height
+ var resize = function(_ref) {
+ return parentResize.fireAndForget({
+ width: _ref.width,
+ height: _ref.height
});
};
+ var xport = function(xports) {
+ exportsPromise.resolve(xports);
+ return parentExport(xports);
+ };
+ var getSiblings = function(_temp) {
+ var anyParent = (void 0 === _temp ? {} : _temp).anyParent;
+ var result = [];
+ var currentParent = props.parent;
+ void 0 === anyParent && (anyParent = !currentParent);
+ if (!anyParent && !currentParent) throw new Error("No parent found for " + tag + " child");
+ for (var _i2 = 0, _getAllFramesInWindow2 = getAllFramesInWindow(window); _i2 < _getAllFramesInWindow2.length; _i2++) {
+ var win = _getAllFramesInWindow2[_i2];
+ if (isSameDomain(win)) {
+ var xprops = assertSameDomain(win).xprops;
+ if (xprops && getParent() === xprops.getParent()) {
+ var winParent = xprops.parent;
+ if (anyParent || !currentParent || winParent && winParent.uid === currentParent.uid) {
+ var xports = tryGlobal(win, (function(global) {
+ return global.exports;
+ }));
+ result.push({
+ props: xprops,
+ exports: xports
+ });
+ }
+ }
+ }
+ }
+ return result;
+ };
var setProps = function(newProps, origin, isUpdate) {
void 0 === isUpdate && (isUpdate = !1);
var normalizedProps = function(parentComponentWindow, propsDef, props, origin, helpers, isUpdate) {
@@ -3803,16 +4374,19 @@
}
return result;
}(parentComponentWindow, propsDef, newProps, origin, {
+ tag: tag,
show: show,
hide: hide,
close: close,
focus: child_focus,
onError: onError,
resize: resize,
+ getSiblings: getSiblings,
onProps: onProps,
getParent: getParent,
getParentDomain: getParentDomain,
- uid: uid
+ uid: uid,
+ export: xport
}, isUpdate);
props ? extend(props, normalizedProps) : props = normalizedProps;
for (var _i4 = 0; _i4 < onPropHandlers.length; _i4++) (0, onPropHandlers[_i4])(props);
@@ -3825,22 +4399,60 @@
return {
init: function() {
return promise_ZalgoPromise.try((function() {
+ isSameDomain(parentComponentWindow) && function(_ref3) {
+ var componentName = _ref3.componentName, parentComponentWindow = _ref3.parentComponentWindow;
+ var _crossDomainDeseriali2 = crossDomainDeserialize({
+ data: parseWindowName(window.name).serializedInitialPayload,
+ sender: {
+ win: parentComponentWindow
+ },
+ basic: !0
+ }), sender = _crossDomainDeseriali2.sender;
+ if ("uid" === _crossDomainDeseriali2.reference.type || "global" === _crossDomainDeseriali2.metaData.windowRef.type) {
+ var _crossDomainSerialize = crossDomainSerialize({
+ data: _crossDomainDeseriali2.data,
+ metaData: {
+ windowRef: window_getWindowRef(parentComponentWindow)
+ },
+ sender: {
+ domain: sender.domain
+ },
+ receiver: {
+ win: window,
+ domain: getDomain()
+ },
+ basic: !0
+ });
+ window.name = buildChildWindowName({
+ name: componentName,
+ serializedPayload: _crossDomainSerialize.serializedData
+ });
+ }
+ }({
+ componentName: options.name,
+ parentComponentWindow: parentComponentWindow
+ });
+ lib_global_getGlobal(window).exports = options.exports({
+ getExports: function() {
+ return exportsPromise;
+ }
+ });
!function(allowedParentDomains, domain) {
if (!matchDomain(allowedParentDomains, domain)) throw new Error("Can not be rendered by domain: " + domain);
}(allowedParentDomains, parentDomain);
markWindowKnown(parentComponentWindow);
!function() {
window.addEventListener("beforeunload", (function() {
- parent.checkClose.fireAndForget();
+ checkClose.fireAndForget();
}));
window.addEventListener("unload", (function() {
- parent.checkClose.fireAndForget();
+ checkClose.fireAndForget();
}));
onCloseWindow(parentComponentWindow, (function() {
child_destroy();
}));
}();
- return parent.init({
+ return parentInit({
updateProps: updateProps,
close: child_destroy
});
@@ -3872,17 +4484,7 @@
},
getProps: function() {
if (props) return props;
- setProps(function(parentComponentWindow, domain, _ref) {
- var type = _ref.type, uid = _ref.uid;
- var props;
- if ("raw" === type) props = _ref.value; else if ("uid" === type) {
- if (!isSameDomain(parentComponentWindow)) throw new Error("Parent component window is on a different domain - expected " + getDomain() + " - can not retrieve props");
- var global = lib_global_getGlobal(parentComponentWindow);
- props = assertExists("props", global && global.props[uid]);
- }
- if (!props) throw new Error("Could not find props");
- return setup_deserializeMessage(parentComponentWindow, domain, props);
- }(parentComponentWindow, parentDomain, propsRef), parentDomain);
+ setProps(initialProps, parentDomain);
return props;
}
};
@@ -3893,40 +4495,60 @@
}));
registerChild();
!function() {
- on_on("zoid_allow_delegate_" + name, (function() {
+ var allowDelegateListener = on_on("zoid_allow_delegate_" + name, (function() {
return !0;
}));
- on_on("zoid_delegate_" + name, (function(_ref) {
+ var delegateListener = on_on("zoid_delegate_" + name, (function(_ref2) {
+ var _ref2$data = _ref2.data;
return {
- parent: parentComponent(options, _ref.data.overrides, _ref.source)
+ parent: parentComponent({
+ uid: _ref2$data.uid,
+ options: options,
+ overrides: _ref2$data.overrides,
+ parentWin: _ref2.source
+ })
};
}));
+ cleanZoid.register(allowDelegateListener.cancel);
+ cleanZoid.register(delegateListener.cancel);
}();
global.components = global.components || {};
if (global.components[tag]) throw new Error("Can not register multiple components with the same tag: " + tag);
global.components[tag] = !0;
return {
- init: function init(props) {
+ init: function init(inputProps) {
var instance;
+ var uid = "zoid-" + tag + "-" + uniqueID();
+ var props = inputProps || {};
var _eligible = eligible({
- props: props = props || {}
+ props: props
}), eligibility = _eligible.eligible, reason = _eligible.reason;
var onDestroy = props.onDestroy;
props.onDestroy = function() {
instance && eligibility && instances.splice(instances.indexOf(instance), 1);
if (onDestroy) return onDestroy.apply(void 0, arguments);
};
- var parent = parentComponent(options);
+ var parent = parentComponent({
+ uid: uid,
+ options: options
+ });
parent.init();
eligibility ? parent.setProps(props) : props.onDestroy && props.onDestroy();
- component_clean.register((function() {
- parent.destroy(new Error("zoid destroyed all components"));
+ cleanInstances.register((function(err) {
+ return parent.destroy(err || new Error("zoid destroyed all components"));
}));
+ var clone = function(_temp) {
+ var _ref4$decorate = (void 0 === _temp ? {} : _temp).decorate;
+ return init((void 0 === _ref4$decorate ? identity : _ref4$decorate)(props));
+ };
var _render = function(target, container, context) {
return promise_ZalgoPromise.try((function() {
- if (!eligibility) return parent.destroy().then((function() {
- throw new Error(reason || name + " component is not eligible");
- }));
+ if (!eligibility) {
+ var err = new Error(reason || name + " component is not eligible");
+ return parent.destroy(err).then((function() {
+ throw err;
+ }));
+ }
if (!isWindow(target)) throw new Error("Must pass window to renderTo");
return function(props, context) {
return promise_ZalgoPromise.try((function() {
@@ -3947,21 +4569,48 @@
if (context === CONTEXT.POPUP) return "body";
throw new Error("Expected element to be passed to render iframe");
}(finalContext, container);
- return parent.render(target, container, finalContext);
+ if (target !== window && "string" != typeof container) throw new Error("Must pass string element when rendering to another window");
+ return parent.render({
+ target: target,
+ container: container,
+ context: finalContext,
+ rerender: function() {
+ var newInstance = clone();
+ extend(instance, newInstance);
+ return newInstance.renderTo(target, container, context);
+ }
+ });
})).catch((function(err) {
return parent.destroy(err).then((function() {
throw err;
}));
}));
};
- instance = _extends({}, parent.getHelpers(), {
+ instance = _extends({}, parent.getExports(), parent.getHelpers(), function() {
+ var childComponents = children();
+ var result = {};
+ var _loop2 = function(_i4, _Object$keys4) {
+ var childName = _Object$keys4[_i4];
+ var Child = childComponents[childName];
+ result[childName] = function(childInputProps) {
+ var parentProps = parent.getProps();
+ var childProps = _extends({}, childInputProps, {
+ parent: {
+ uid: uid,
+ props: parentProps,
+ export: parent.export
+ }
+ });
+ return Child(childProps);
+ };
+ };
+ for (var _i4 = 0, _Object$keys4 = Object.keys(childComponents); _i4 < _Object$keys4.length; _i4++) _loop2(_i4, _Object$keys4);
+ return result;
+ }(), {
isEligible: function() {
return eligibility;
},
- clone: function(_temp) {
- var _ref3$decorate = (void 0 === _temp ? {} : _temp).decorate;
- return init((void 0 === _ref3$decorate ? identity : _ref3$decorate)(props));
- },
+ clone: clone,
render: function(container, context) {
return _render(window, container, context);
},
@@ -3978,8 +4627,8 @@
},
isChild: isChild,
canRenderTo: function(win) {
- return send_send(win, "zoid_allow_delegate_" + name).then((function(_ref2) {
- return _ref2.data;
+ return send_send(win, "zoid_allow_delegate_" + name).then((function(_ref3) {
+ return _ref3.data;
})).catch((function() {
return !1;
}));
@@ -3987,7 +4636,7 @@
registerChild: registerChild
};
}
- function create(options) {
+ var component_create = function(options) {
!function() {
if (!global_getGlobal().initialized) {
global_getGlobal().initialized = !0;
@@ -4059,7 +4708,7 @@
}
var _ref3, on, send, global;
}();
- var comp = component_component(options);
+ var comp = component(options);
var init = function(props) {
return comp.init(props);
};
@@ -4076,16 +4725,16 @@
var child = comp.registerChild();
child && (window.xprops = init.xprops = child.getProps());
return init;
- }
- function destroyAll() {
- var destroyPromise = component_clean.all();
- component_clean = cleanup();
+ };
+ function destroyComponents(err) {
+ var destroyPromise = cleanInstances.all(err);
+ cleanInstances = cleanup();
return destroyPromise;
}
- var destroyComponents = destroyAll;
- function component_destroy() {
+ var destroyAll = destroyComponents;
+ function component_destroy(err) {
destroyAll();
- delete window.__zoid_9_0_58__;
+ delete window.__zoid_9_0_86__;
!function() {
!function() {
var responseListeners = globalStore("responseListeners");
@@ -4098,8 +4747,9 @@
}();
(listener = globalStore().get("postMessageListener")) && listener.cancel();
var listener;
- delete window.__post_robot_10_0_39__;
+ delete window.__post_robot_10_0_44__;
}();
+ return cleanZoid.all(err);
}
} ]);
}));
\ No newline at end of file
diff --git a/dist/zoid.frame.min.js b/dist/zoid.frame.min.js
index 048bacd0..5ded770a 100644
--- a/dist/zoid.frame.min.js
+++ b/dist/zoid.frame.min.js
@@ -1,2 +1,2 @@
-!function(n,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("zoid",[],e):"object"==typeof exports?exports.zoid=e():n.zoid=e()}("undefined"!=typeof self?self:this,(function(){return function(n){var e={};function r(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=n,r.c=e,r.d=function(n,e,t){r.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:t})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,e){if(1&e&&(n=r(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var t=Object.create(null);if(r.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)r.d(t,o,function(e){return n[e]}.bind(null,o));return t},r.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(e,"a",e),e},r.o=function(n,e){return{}.hasOwnProperty.call(n,e)},r.p="",r(r.s=0)}([function(n,e,r){"use strict";function t(){return(t=Object.assign||function(n){for(var e=1;e>>0)+"__",function(){if("undefined"==typeof WeakMap)return!1;if(void 0===Object.freeze)return!1;try{var n=new WeakMap,e={};return Object.freeze(e),n.set(e,"__testvalue__"),"__testvalue__"===n.get(e)}catch(n){return!1}}())try{this.weakmap=new WeakMap}catch(n){}this.keys=[],this.values=[]}var e=n.prototype;return e._cleanupClosedWindows=function(){for(var n=this.weakmap,e=this.keys,r=0;r=3)return"stringifyError stack overflow";try{if(!n)return"";if("string"==typeof n)return n;if(n instanceof Error){var r=n&&n.stack,t=n&&n.message;if(r&&t)return-1!==r.indexOf(t)?r:t+"\n"+r;if(r)return r;if(t)return t}return n&&n.toString&&"function"==typeof n.toString?n.toString():{}.toString.call(n)}catch(n){return"Error while stringifying error: "+rn(n,e+1)}}function tn(n){return"string"==typeof n?n:n&&n.toString&&"function"==typeof n.toString?n.toString():{}.toString.call(n)}function on(n,e){if(!e)return n;if(Object.assign)return Object.assign(n,e);for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);return n}function un(n){return n}function an(n,e){var r;return function t(){r=setTimeout((function(){n(),t()}),e)}(),{cancel:function(){clearTimeout(r)}}}function cn(n){return[].slice.call(n)}function sn(n){return null!=n}function fn(n){return"[object RegExp]"==={}.toString.call(n)}function dn(n,e,r){if(n.hasOwnProperty(e))return n[e];var t=r();return n[e]=t,t}function ln(n){var e=[],r=!1;return{set:function(e,t){return r||(n[e]=t,this.register((function(){delete n[e]}))),t},register:function(n){r?n():e.push(en(n))},all:function(){var n=[];for(r=!0;e.length;){var t=e.shift();n.push(t())}return l.all(n).then(nn)}}}function hn(n,e){if(null==e)throw new Error("Expected "+n+" to be present");return e}function wn(){return Boolean(document.body)&&"complete"===document.readyState}function pn(){return Boolean(document.body)&&"interactive"===document.readyState}function vn(n){return n.replace(/\?/g,"%3F").replace(/&/g,"%26").replace(/#/g,"%23").replace(/\+/g,"%2B")}function mn(n){return Q(mn,(function(){var e={};if(!n)return e;if(-1===n.indexOf("="))return e;for(var r=0,t=n.split("&");r { ... }":"<"+typeof n+">"})).join(", ")+") failed\n\n")+n.stack),n}))})).then((function(n){return{result:n,id:o,name:i}}))}))}));var c=r.__id__||Z();n=oe.unwrap(n);var s=r.__name__||r.name||t;return"string"==typeof s&&"function"==typeof s.indexOf&&0===s.indexOf("anonymous::")&&(s=s.replace("anonymous::",t+"::")),oe.isProxyWindow(n)?(ie(c,r,s,n,e),n.awaitWindow().then((function(n){ie(c,r,s,n,e)}))):ie(c,r,s,n,e),$n("cross_domain_function",{id:c,name:s})}function ce(n,e,r,t){var o,i=t.on,u=t.send;return function(n,e){void 0===e&&(e=Qn);var r=JSON.stringify(n,(function(n){var r=this[n];if(Vn(this))return r;var t=Gn(r);if(!t)return r;var o=e[t]||Kn[t];return o?o(r,n):r}));return void 0===r?"undefined":r}(r,((o={}).promise=function(r,t){return function(n,e,r,t,o){return $n("cross_domain_zalgo_promise",{then:ae(n,e,(function(n,e){return r.then(n,e)}),t,{on:o.on,send:o.send})})}(n,e,r,t,{on:i,send:u})},o.function=function(r,t){return ae(n,e,r,t,{on:i,send:u})},o.object=function(n){return q(n)||oe.isProxyWindow(n)?$n("cross_domain_window",oe.serialize(n,{send:u})):n},o))}function se(n,e,r,t){var o,i=t.send;return function(n,e){if(void 0===e&&(e=ee),"undefined"!==n)return JSON.parse(n,(function(n,r){if(Vn(this))return r;var t,o;if(Vn(r)?(t=r.__type__,o=r.__val__):(t=Gn(r),o=r),!t)return o;var i=e[t]||ne[t];return i?i(o,n):o}))}(r,((o={}).cross_domain_zalgo_promise=function(n){return function(n,e,r){return new l(r.then)}(0,0,n)},o.cross_domain_function=function(r){return function(n,e,r,t){var o=r.id,i=r.name,u=t.send,a=function(r){function t(){var a=arguments;return oe.toProxyWindow(n,{send:u}).awaitWindow().then((function(n){var c=ue(n,o);if(c&&c.val!==t)return c.val.apply({source:window,origin:E()},a);var s=[].slice.call(a);return r.fireAndForget?u(n,"postrobot_method",{id:o,name:i,args:s},{domain:e,fireAndForget:!0}):u(n,"postrobot_method",{id:o,name:i,args:s},{domain:e,fireAndForget:!1}).then((function(n){return n.data.result}))})).catch((function(n){throw n}))}return void 0===r&&(r={}),t.__name__=i,t.__origin__=e,t.__source__=n,t.__id__=o,t.origin=e,t},c=a();return c.fireAndForget=a({fireAndForget:!0}),c}(n,e,r,{send:i})},o.cross_domain_window=function(n){return oe.deserialize(n,{send:i})},o))}var fe,de={};function le(n,e,r,t){var o=t.on,i=t.send;return l.try((function(){var t=Un().getOrSet(n,(function(){return{}}));return t.buffer=t.buffer||[],t.buffer.push(r),t.flush=t.flush||l.flush().then((function(){if(R(n))throw new Error("Window is closed");var r,u=ce(n,e,((r={}).__post_robot_10_0_39__=t.buffer||[],r),{on:o,send:i});delete t.buffer;for(var a=Object.keys(de),c=[],s=0;s1?e-1:0),t=1;t1?e-1:0),t=1;t iframe {\n display: inline-block;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transition: opacity .2s ease-in-out;\n }\n\n #"+e+" > iframe.zoid-invisible {\n opacity: 0;\n }\n\n #"+e+" > iframe.zoid-visible {\n opacity: 1;\n }\n ")),f.appendChild(r),f.appendChild(t),f.appendChild(d),t.classList.add("zoid-visible"),r.classList.add("zoid-invisible"),u.on(De.RENDERED,(function(){t.classList.remove("zoid-visible"),t.classList.add("zoid-invisible"),r.classList.remove("zoid-invisible"),r.classList.add("zoid-visible"),setTimeout((function(){jn(t)}),1)})),u.on(De.RESIZE,(function(n){var e=n.width,r=n.height;"number"==typeof e&&(f.style.width=Tn(e)),"number"==typeof r&&(f.style.height=Tn(r))})),f}}var qe=function(){return nn},Me=function(n){return en(n.value)},Le=ln();function Ue(n){var e=function(n){var e=n.tag,r=n.url,o=n.domain,i=n.bridgeUrl,u=n.props,a=void 0===u?{}:u,c=n.dimensions,s=void 0===c?{}:c,f=n.autoResize,d=void 0===f?{}:f,l=n.allowedParentDomains,h=void 0===l?"*":l,w=n.attributes,p=void 0===w?{}:w,v=n.defaultContext,m=void 0===v?Ce.IFRAME:v,y=n.containerTemplate,g=void 0===y?Fe:y,_=n.prerenderTemplate,E=void 0===_?null:_,x=n.validate,P=n.eligible,W=void 0===P?function(){return{eligible:!0}}:P,O=n.logger,S=void 0===O?{info:nn}:O,C=e.replace(/-/g,"_"),D=s.width,j=void 0===D?"300px":D,k=s.height,A=void 0===k?"150px":k;if(a=t({},{window:{type:"object",sendToChild:!1,required:!1,allowDelegate:!0,validate:function(n){var e=n.value;if(!q(e)&&!oe.isProxyWindow(e))throw new Error("Expected Window or ProxyWindow");if(q(e)){if(R(e))throw new Error("Window is closed");if(!b(e))throw new Error("Window is not same domain")}},decorate:function(n){return xe(n.value)}},timeout:{type:"number",required:!1,sendToChild:!1},close:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.close}},focus:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.focus}},resize:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.resize}},uid:{type:"string",required:!1,sendToChild:!1,childDecorate:function(n){return n.uid}},cspNonce:{type:"string",required:!1},getParent:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.getParent}},getParentDomain:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.getParentDomain}},show:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.show}},hide:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.hide}},onDisplay:{type:"function",required:!1,sendToChild:!1,allowDelegate:!0,default:qe,decorate:Me},onRendered:{type:"function",required:!1,sendToChild:!1,default:qe,decorate:Me},onRender:{type:"function",required:!1,sendToChild:!1,default:qe,decorate:Me},onClose:{type:"function",required:!1,sendToChild:!1,allowDelegate:!0,default:qe,decorate:Me},onDestroy:{type:"function",required:!1,sendToChild:!1,allowDelegate:!0,default:qe,decorate:Me},onResize:{type:"function",required:!1,sendToChild:!1,allowDelegate:!0,default:qe},onFocus:{type:"function",required:!1,sendToChild:!1,allowDelegate:!0,default:qe},onError:{type:"function",required:!1,sendToChild:!1,childDecorate:function(n){return n.onError}},onProps:{type:"function",required:!1,sendToChild:!1,default:qe,childDecorate:function(n){return n.onProps}}},a),!g)throw new Error("Container template required");return{name:C,tag:e,url:r,domain:o,bridgeUrl:i,propsDef:a,dimensions:{width:j,height:A},autoResize:d,allowedParentDomains:h,attributes:p,defaultContext:m,containerTemplate:g,prerenderTemplate:E,validate:x,logger:S,eligible:W}}(n),r=e.name,o=e.tag,i=e.defaultContext,u=e.eligible,a=Pe(),c=[],s=function(){var n=ke();return Boolean(n&&n.tag===o&&n.childDomain===E())},f=X((function(){if(s()){if(window.xprops)throw delete a.components[o],new Error("Can not register "+r+" as child - child already registered");var n=function(n){var e,r=n.propsDef,t=n.autoResize,o=n.allowedParentDomains,i=[],u=ke();if(!u)throw new Error("No child payload found");if("9_0_58"!==u.version)throw new Error("Parent window has zoid version "+u.version+", child window has version 9_0_58");var a=u.uid,c=u.parentDomain,s=u.exports,f=u.context,d=u.props,h=function(n){var e,r,t=n.type;if("opener"===t)return hn("opener",y(window));if("parent"===t&&"number"==typeof n.distance)return hn("parent",(e=window,void 0===(r=n.distance)&&(r=1),function(n,e){void 0===e&&(e=1);for(var r=n,t=0;t>>0)+"__",function(){if("undefined"==typeof WeakMap)return!1;if(void 0===Object.freeze)return!1;try{var n=new WeakMap,e={};return Object.freeze(e),n.set(e,"__testvalue__"),"__testvalue__"===n.get(e)}catch(n){return!1}}())try{this.weakmap=new WeakMap}catch(n){}this.keys=[],this.values=[]}var e=n.prototype;return e._cleanupClosedWindows=function(){for(var n=this.weakmap,e=this.keys,r=0;r=3)return"stringifyError stack overflow";try{if(!n)return"";if("string"==typeof n)return n;if(n instanceof Error){var r=n&&n.stack,t=n&&n.message;if(r&&t)return-1!==r.indexOf(t)?r:t+"\n"+r;if(r)return r;if(t)return t}return n&&n.toString&&"function"==typeof n.toString?n.toString():{}.toString.call(n)}catch(n){return"Error while stringifying error: "+hn(n,e+1)}}function wn(n){return"string"==typeof n?n:n&&n.toString&&"function"==typeof n.toString?n.toString():{}.toString.call(n)}function pn(n,e){if(!e)return n;if(Object.assign)return Object.assign(n,e);for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);return n}function vn(n){return n}function mn(n,e){var r;return function t(){r=setTimeout((function(){n(),t()}),e)}(),{cancel:function(){clearTimeout(r)}}}function yn(n){return[].slice.call(n)}function gn(n){return null!=n}function En(n){return"[object RegExp]"==={}.toString.call(n)}function bn(n,e,r){if(n.hasOwnProperty(e))return n[e];var t=r();return n[e]=t,t}function _n(n){var e,r=[],t=!1,o={set:function(e,r){return t||(n[e]=r,o.register((function(){delete n[e]}))),r},register:function(n){var o=ln((function(){return n(e)}));return t?n(e):r.push(o),{cancel:function(){var n=r.indexOf(o);-1!==n&&r.splice(n,1)}}},all:function(n){e=n;var o=[];for(t=!0;r.length;){var i=r.shift();o.push(i())}return w.all(o).then(dn)}};return o}function xn(n,e){if(null==e)throw new Error("Expected "+n+" to be present");return e}fn.clear=function(){cn=un},fn((function(n){if(Object.values)return Object.values(n);var e=[];for(var r in n)n.hasOwnProperty(r)&&e.push(n[r]);return e}));var Pn=function(n){function e(e){var r;return(r=n.call(this,e)||this).name=r.constructor.name,"function"==typeof Error.captureStackTrace?Error.captureStackTrace(function(n){if(void 0===n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return n}(r),r.constructor):r.stack=new Error(e).stack,r}return o(e,n),e}(Q(Error));function On(){var n=document.body;if(!n)throw new Error("Body element not found");return n}function Cn(){return Boolean(document.body)&&"complete"===document.readyState}function Sn(){return Boolean(document.body)&&"interactive"===document.readyState}function Wn(n){return encodeURIComponent(n)}function Dn(n){return function(e,r,t){void 0===t&&(t=[]);var o=e.__inline_memoize_cache__=e.__inline_memoize_cache__||{},i=on(t);return o.hasOwnProperty(i)?o[i]:o[i]=function(){var e={};if(!n)return e;if(-1===n.indexOf("="))return e;for(var r=0,t=n.split("&");r { ... }":"<"+typeof n+">"})).join(", ")+") failed\n\n")+n.stack),n}))})).then((function(n){return{result:n,id:o,name:i}}))}))}));var c=r.__id__||tn();n=Ee.unwrap(n);var f=r.__name__||r.name||t;return"string"==typeof f&&"function"==typeof f.indexOf&&0===f.indexOf("anonymous::")&&(f=f.replace("anonymous::",t+"::")),Ee.isProxyWindow(n)?(be(c,r,f,n,e),n.awaitWindow().then((function(n){be(c,r,f,n,e)}))):be(c,r,f,n,e),le("cross_domain_function",{id:c,name:f})}function Pe(n,e,r,t){var o,i=t.on,a=t.send;return function(n,e){void 0===e&&(e=pe);var r=JSON.stringify(n,(function(n){var r=this[n];if(se(this))return r;var t=de(r);if(!t)return r;var o=e[t]||we[t];return o?o(r,n):r}));return void 0===r?"undefined":r}(r,((o={}).promise=function(r,t){return function(n,e,r,t,o){return le("cross_domain_zalgo_promise",{then:xe(n,e,(function(n,e){return r.then(n,e)}),t,{on:o.on,send:o.send})})}(n,e,r,t,{on:i,send:a})},o.function=function(r,t){return xe(n,e,r,t,{on:i,send:a})},o.object=function(n){return J(n)||Ee.isProxyWindow(n)?le("cross_domain_window",Ee.serialize(n,{send:a})):n},o))}function Oe(n,e,r,t){var o,i=t.send;return function(n,e){if(void 0===e&&(e=me),"undefined"!==n)return JSON.parse(n,(function(n,r){if(se(this))return r;var t,o;if(se(r)?(t=r.__type__,o=r.__val__):(t=de(r),o=r),!t)return o;var i=e[t]||ve[t];return i?i(o,n):o}))}(r,((o={}).cross_domain_zalgo_promise=function(n){return function(n,e,r){return new w(r.then)}(0,0,n)},o.cross_domain_function=function(r){return function(n,e,r,t){var o=r.id,i=r.name,a=t.send,u=function(r){function t(){var u=arguments;return Ee.toProxyWindow(n,{send:a}).awaitWindow().then((function(n){var c=_e(n,o);if(c&&c.val!==t)return c.val.apply({source:window,origin:O()},u);var f=[].slice.call(u);return r.fireAndForget?a(n,"postrobot_method",{id:o,name:i,args:f},{domain:e,fireAndForget:!0}):a(n,"postrobot_method",{id:o,name:i,args:f},{domain:e,fireAndForget:!1}).then((function(n){return n.data.result}))})).catch((function(n){throw n}))}return void 0===r&&(r={}),t.__name__=i,t.__origin__=e,t.__source__=n,t.__id__=o,t.origin=e,t},c=u();return c.fireAndForget=u({fireAndForget:!0}),c}(n,e,r,{send:i})},o.cross_domain_window=function(n){return Ee.deserialize(n,{send:i})},o))}var Ce={};function Se(n,e,r,t){var o=t.on,i=t.send;return w.try((function(){var t=oe().getOrSet(n,(function(){return{}}));return t.buffer=t.buffer||[],t.buffer.push(r),t.flush=t.flush||w.flush().then((function(){if(I(n))throw new Error("Window is closed");var r,a=Pe(n,e,((r={}).__post_robot_10_0_44__=t.buffer||[],r),{on:o,send:i});delete t.buffer;for(var u=Object.keys(Ce),c=[],f=0;f1?e-1:0),o=1;o1?r-1:0),i=1;i iframe {\n display: inline-block;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n transition: opacity .2s ease-in-out;\n }\n\n #"+e+" > iframe.zoid-invisible {\n opacity: 0;\n }\n\n #"+e+" > iframe.zoid-visible {\n opacity: 1;\n }\n ")),s.appendChild(r),s.appendChild(t),s.appendChild(d),t.classList.add("zoid-visible"),r.classList.add("zoid-invisible"),a.on(Ve.RENDERED,(function(){t.classList.remove("zoid-visible"),t.classList.add("zoid-invisible"),r.classList.remove("zoid-invisible"),r.classList.add("zoid-visible"),setTimeout((function(){Bn(t)}),1)})),a.on(Ve.RESIZE,(function(n){var e=n.width,r=n.height;"number"==typeof e&&(s.style.width=Xn(e)),"number"==typeof r&&(s.style.height=Xn(r))})),s}}var sr=_n(),dr=_n();function lr(n){var e,r,t=function(n){var e=n.tag,r=n.url,t=n.domain,o=n.bridgeUrl,a=n.props,u=void 0===a?{}:a,c=n.dimensions,f=void 0===c?{}:c,s=n.autoResize,d=void 0===s?{}:s,l=n.allowedParentDomains,h=void 0===l?"*":l,w=n.attributes,p=void 0===w?{}:w,v=n.defaultContext,m=void 0===v?Ge.IFRAME:v,y=n.containerTemplate,g=void 0===y?fr:y,E=n.prerenderTemplate,b=void 0===E?null:E,_=n.validate,x=n.eligible,P=void 0===x?function(){return{eligible:!0}}:x,O=n.logger,S=void 0===O?{info:dn}:O,W=n.exports,D=void 0===W?dn:W,N=n.method,j=n.children,R=void 0===j?function(){return{}}:j,T=e.replace(/-/g,"_"),A=i({},{window:{type:Ye.OBJECT,sendToChild:!1,required:!1,allowDelegate:!0,validate:function(n){var e=n.value;if(!J(e)&&!Ee.isProxyWindow(e))throw new Error("Expected Window or ProxyWindow");if(J(e)){if(I(e))throw new Error("Window is closed");if(!C(e))throw new Error("Window is not same domain")}},decorate:function(n){return Fe(n.value)}},timeout:{type:Ye.NUMBER,required:!1,sendToChild:!1},cspNonce:{type:Ye.STRING,required:!1},onDisplay:{type:Ye.FUNCTION,required:!1,sendToChild:!1,allowDelegate:!0,default:or,decorate:ir},onRendered:{type:Ye.FUNCTION,required:!1,sendToChild:!1,default:or,decorate:ir},onRender:{type:Ye.FUNCTION,required:!1,sendToChild:!1,default:or,decorate:ir},onClose:{type:Ye.FUNCTION,required:!1,sendToChild:!1,allowDelegate:!0,default:or,decorate:ir},onDestroy:{type:Ye.FUNCTION,required:!1,sendToChild:!1,allowDelegate:!0,default:or,decorate:ir},onResize:{type:Ye.FUNCTION,required:!1,sendToChild:!1,allowDelegate:!0,default:or},onFocus:{type:Ye.FUNCTION,required:!1,sendToChild:!1,allowDelegate:!0,default:or},close:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.close}},focus:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.focus}},resize:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.resize}},uid:{type:Ye.STRING,required:!1,sendToChild:!1,childDecorate:function(n){return n.uid}},tag:{type:Ye.STRING,required:!1,sendToChild:!1,childDecorate:function(n){return n.tag}},getParent:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.getParent}},getParentDomain:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.getParentDomain}},show:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.show}},hide:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.hide}},export:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.export}},onError:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.onError}},onProps:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.onProps}},getSiblings:{type:Ye.FUNCTION,required:!1,sendToChild:!1,childDecorate:function(n){return n.getSiblings}}},u);if(!g)throw new Error("Container template required");return{name:T,tag:e,url:r,domain:t,bridgeUrl:o,method:N,propsDef:A,dimensions:f,autoResize:d,allowedParentDomains:h,attributes:p,defaultContext:m,containerTemplate:g,prerenderTemplate:b,validate:_,logger:S,eligible:P,children:R,exports:"function"==typeof D?D:function(n){for(var e=n.getExports,r={},t=function(n,t){var o=t[n],i=D[o].type,a=e().then((function(n){return n[o]}));r[o]=i===Ye.FUNCTION?function(){for(var n=arguments.length,e=new Array(n),r=0;r) => void> = [];\n\nexport function dispatchPossiblyUnhandledError(err : mixed, promise : ZalgoPromise) {\n\n if (dispatchedErrors.indexOf(err) !== -1) {\n return;\n }\n\n dispatchedErrors.push(err);\n\n setTimeout(() => {\n if (__DEBUG__) {\n // $FlowFixMe\n throw new Error(`${ err.stack || err.toString() }\\n\\nFrom promise:\\n\\n${ promise.stack }`);\n }\n\n throw err;\n }, 1);\n\n for (let j = 0; j < possiblyUnhandledPromiseHandlers.length; j++) {\n // $FlowFixMe\n possiblyUnhandledPromiseHandlers[j](err, promise);\n }\n}\n\nexport function onPossiblyUnhandledException(handler : (mixed, promise? : ZalgoPromise) => void) : { cancel : () => void } {\n possiblyUnhandledPromiseHandlers.push(handler);\n\n return {\n cancel() {\n possiblyUnhandledPromiseHandlers.splice(possiblyUnhandledPromiseHandlers.indexOf(handler), 1);\n }\n };\n}\n","/* @flow */\n\nimport type { ZalgoPromise } from './promise';\n\nlet activeCount = 0;\nlet flushPromise;\n\nfunction flushActive() {\n if (!activeCount && flushPromise) {\n const promise = flushPromise;\n flushPromise = null;\n promise.resolve();\n }\n}\n\nexport function startActive() {\n activeCount += 1;\n}\n\nexport function endActive() {\n activeCount -= 1;\n flushActive();\n}\n\nexport function awaitActive(Zalgo : Class>) : ZalgoPromise { // eslint-disable-line no-undef\n let promise = flushPromise = flushPromise || new Zalgo();\n flushActive();\n return promise;\n}\n","/* @flow */\n\nimport { isPromise } from './utils';\nimport { onPossiblyUnhandledException, dispatchPossiblyUnhandledError } from './exceptions';\nimport { startActive, endActive, awaitActive } from './flush';\n\nexport class ZalgoPromise {\n\n resolved : boolean\n rejected : boolean\n errorHandled : boolean\n value : R\n error : mixed\n handlers : Array<{\n promise : ZalgoPromise<*>,\n onSuccess : void | (result : R) => mixed,\n onError : void | (error : mixed) => mixed\n }>\n dispatching : boolean\n stack : string\n\n constructor(handler : ?(resolve : (result : R) => void, reject : (error : mixed) => void) => void) {\n\n this.resolved = false;\n this.rejected = false;\n this.errorHandled = false;\n\n this.handlers = [];\n\n if (handler) {\n\n let result;\n let error;\n let resolved = false;\n let rejected = false;\n let isAsync = false;\n\n startActive();\n\n try {\n handler(res => {\n if (isAsync) {\n this.resolve(res);\n } else {\n resolved = true;\n result = res;\n }\n\n }, err => {\n if (isAsync) {\n this.reject(err);\n } else {\n rejected = true;\n error = err;\n }\n });\n\n } catch (err) {\n endActive();\n this.reject(err);\n return;\n }\n\n endActive();\n\n isAsync = true;\n\n if (resolved) {\n // $FlowFixMe\n this.resolve(result);\n } else if (rejected) {\n this.reject(error);\n }\n }\n\n if (__DEBUG__) {\n try {\n throw new Error(`ZalgoPromise`);\n } catch (err) {\n this.stack = err.stack;\n }\n }\n }\n\n resolve(result : R) : ZalgoPromise {\n if (this.resolved || this.rejected) {\n return this;\n }\n\n if (isPromise(result)) {\n throw new Error('Can not resolve promise with another promise');\n }\n\n this.resolved = true;\n this.value = result;\n this.dispatch();\n\n return this;\n }\n\n reject(error : mixed) : ZalgoPromise {\n if (this.resolved || this.rejected) {\n return this;\n }\n\n if (isPromise(error)) {\n throw new Error('Can not reject promise with another promise');\n }\n\n if (!error) {\n // $FlowFixMe\n let err = (error && typeof error.toString === 'function' ? error.toString() : Object.prototype.toString.call(error));\n error = new Error(`Expected reject to be called with Error, got ${ err }`);\n }\n\n this.rejected = true;\n this.error = error;\n\n if (!this.errorHandled) {\n setTimeout(() => {\n if (!this.errorHandled) {\n dispatchPossiblyUnhandledError(error, this);\n }\n }, 1);\n }\n\n this.dispatch();\n\n return this;\n }\n\n asyncReject(error : mixed) : ZalgoPromise {\n this.errorHandled = true;\n this.reject(error);\n return this;\n }\n \n dispatch() {\n\n let { dispatching, resolved, rejected, handlers } = this;\n\n if (dispatching) {\n return;\n }\n\n if (!resolved && !rejected) {\n return;\n }\n\n this.dispatching = true;\n startActive();\n\n const chain = (firstPromise : ZalgoPromise, secondPromise : ZalgoPromise) => {\n return firstPromise.then(res => {\n secondPromise.resolve(res);\n }, err => {\n secondPromise.reject(err);\n });\n };\n\n for (let i = 0; i < handlers.length; i++) {\n\n let { onSuccess, onError, promise } = handlers[i];\n\n let result;\n\n if (resolved) {\n\n try {\n result = onSuccess ? onSuccess(this.value) : this.value;\n } catch (err) {\n promise.reject(err);\n continue;\n }\n\n } else if (rejected) {\n\n if (!onError) {\n promise.reject(this.error);\n continue;\n }\n\n try {\n result = onError(this.error);\n } catch (err) {\n promise.reject(err);\n continue;\n }\n }\n\n if (result instanceof ZalgoPromise && (result.resolved || result.rejected)) {\n\n if (result.resolved) {\n promise.resolve(result.value);\n } else {\n promise.reject(result.error);\n }\n\n result.errorHandled = true;\n\n } else if (isPromise(result)) {\n\n if (result instanceof ZalgoPromise && (result.resolved || result.rejected)) {\n if (result.resolved) {\n promise.resolve(result.value);\n } else {\n promise.reject(result.error);\n }\n\n } else {\n // $FlowFixMe\n chain(result, promise);\n }\n\n } else {\n\n promise.resolve(result);\n }\n }\n\n handlers.length = 0;\n this.dispatching = false;\n endActive();\n }\n\n then(onSuccess : void | (result : R) => (ZalgoPromise | Y), onError : void | (error : mixed) => (ZalgoPromise | Y)) : ZalgoPromise {\n\n if (onSuccess && typeof onSuccess !== 'function' && !onSuccess.call) {\n throw new Error('Promise.then expected a function for success handler');\n }\n\n if (onError && typeof onError !== 'function' && !onError.call) {\n throw new Error('Promise.then expected a function for error handler');\n }\n\n let promise : ZalgoPromise = new ZalgoPromise();\n\n this.handlers.push({\n promise,\n onSuccess,\n onError\n });\n\n this.errorHandled = true;\n\n this.dispatch();\n\n return promise;\n }\n\n catch(onError : (error : mixed) => ZalgoPromise | Y) : ZalgoPromise {\n return this.then(undefined, onError);\n }\n\n finally(onFinally : () => mixed) : ZalgoPromise {\n\n if (onFinally && typeof onFinally !== 'function' && !onFinally.call) {\n throw new Error('Promise.finally expected a function');\n }\n\n return this.then((result) => {\n return ZalgoPromise.try(onFinally)\n .then(() => {\n return result;\n });\n }, (err) => {\n return ZalgoPromise.try(onFinally)\n .then(() => {\n throw err;\n });\n });\n }\n\n timeout(time : number, err : ?Error) : ZalgoPromise {\n\n if (this.resolved || this.rejected) {\n return this;\n }\n\n let timeout = setTimeout(() => {\n\n if (this.resolved || this.rejected) {\n return;\n }\n\n this.reject(err || new Error(`Promise timed out after ${ time }ms`));\n\n }, time);\n\n return this.then(result => {\n clearTimeout(timeout);\n return result;\n });\n }\n\n // $FlowFixMe\n toPromise() : Promise {\n // $FlowFixMe\n if (typeof Promise === 'undefined') {\n throw new TypeError(`Could not find Promise`);\n }\n // $FlowFixMe\n return Promise.resolve(this); // eslint-disable-line compat/compat\n }\n\n static resolve(value : X | ZalgoPromise) : ZalgoPromise {\n\n if (value instanceof ZalgoPromise) {\n return value;\n }\n\n if (isPromise(value)) {\n // $FlowFixMe\n return new ZalgoPromise((resolve, reject) => value.then(resolve, reject));\n }\n\n return new ZalgoPromise().resolve(value);\n }\n\n static reject(error : mixed) : ZalgoPromise {\n return new ZalgoPromise().reject(error);\n }\n\n static asyncReject(error : mixed) : ZalgoPromise {\n return new ZalgoPromise().asyncReject(error);\n }\n\n static all>(promises : X) : ZalgoPromise<$TupleMap(ZalgoPromise | Y) => Y>> { // eslint-disable-line no-undef\n\n let promise = new ZalgoPromise();\n let count = promises.length;\n let results = [];\n\n if (!count) {\n promise.resolve(results);\n return promise;\n }\n\n const chain = (i : number, firstPromise : ZalgoPromise, secondPromise : ZalgoPromise) => {\n return firstPromise.then(res => {\n results[i] = res;\n count -= 1;\n if (count === 0) {\n promise.resolve(results);\n }\n }, err => {\n secondPromise.reject(err);\n });\n };\n\n for (let i = 0; i < promises.length; i++) {\n let prom = promises[i];\n\n if (prom instanceof ZalgoPromise) {\n if (prom.resolved) {\n results[i] = prom.value;\n count -= 1;\n continue;\n }\n } else if (!isPromise(prom)) {\n results[i] = prom;\n count -= 1;\n continue;\n }\n\n chain(i, ZalgoPromise.resolve(prom), promise);\n }\n\n if (count === 0) {\n promise.resolve(results);\n }\n\n return promise;\n }\n\n static hash(promises : O) : ZalgoPromise<$ObjMap(ZalgoPromise | Y) => Y>> { // eslint-disable-line no-undef\n let result = {};\n let awaitPromises = [];\n\n for (const key in promises) {\n if (promises.hasOwnProperty(key)) {\n let value = promises[key];\n\n if (isPromise(value)) {\n awaitPromises.push(value.then(res => {\n result[key] = res;\n }));\n } else {\n result[key] = value;\n }\n }\n }\n \n return ZalgoPromise.all(awaitPromises).then(() => result);\n }\n\n static map(items : Array, method : (T) => (ZalgoPromise | X)) : ZalgoPromise> {\n // $FlowFixMe\n return ZalgoPromise.all(items.map(method));\n }\n\n static onPossiblyUnhandledException(handler : (err : mixed) => void) : { cancel : () => void } {\n return onPossiblyUnhandledException(handler);\n }\n\n static try>(method : (...args : A) => (ZalgoPromise | Y), context : ?C, args : ?A) : ZalgoPromise {\n\n if (method && typeof method !== 'function' && !method.call) {\n throw new Error('Promise.try expected a function');\n }\n\n let result;\n\n startActive();\n \n try {\n // $FlowFixMe\n result = method.apply(context, args || []);\n } catch (err) {\n endActive();\n return ZalgoPromise.reject(err);\n }\n\n endActive();\n\n return ZalgoPromise.resolve(result);\n }\n\n static delay(delay : number) : ZalgoPromise {\n return new ZalgoPromise(resolve => {\n setTimeout(resolve, delay);\n });\n }\n\n static isPromise(value : mixed) : boolean {\n\n if (value && value instanceof ZalgoPromise) {\n return true;\n }\n\n return isPromise(value);\n }\n\n static flush() : ZalgoPromise {\n return awaitActive(ZalgoPromise);\n }\n}\n","/* @flow */\n\nexport function isRegex(item : mixed) : boolean {\n return Object.prototype.toString.call(item) === '[object RegExp]';\n}\n\n// eslint-disable-next-line no-unused-vars\nexport function noop(...args : Array) {\n // pass\n}\n","/* @flow */\n\nexport const PROTOCOL = {\n MOCK: ('mock:' : 'mock:'),\n FILE: ('file:' : 'file:'),\n ABOUT: ('about:' : 'about:')\n};\n\nexport const WILDCARD = '*';\n\nexport const WINDOW_TYPE = {\n IFRAME: ('iframe' : 'iframe'),\n POPUP: ('popup' : 'popup')\n};\n","/* @flow */\n/* eslint max-lines: 0 */\n\nimport { isRegex, noop } from './util';\nimport type { CrossDomainWindowType, SameDomainWindowType, DomainMatcher } from './types';\nimport { PROTOCOL, WILDCARD } from './constants';\n\nlet IE_WIN_ACCESS_ERROR = 'Call was rejected by callee.\\r\\n';\n\nexport function isFileProtocol(win : SameDomainWindowType = window) : boolean {\n return win.location.protocol === PROTOCOL.FILE;\n}\n\nexport function isAboutProtocol(win : SameDomainWindowType = window) : boolean {\n return win.location.protocol === PROTOCOL.ABOUT;\n}\n\nexport function getParent(win? : CrossDomainWindowType = window) : ?CrossDomainWindowType {\n\n if (!win) {\n return;\n }\n\n try {\n if (win.parent && win.parent !== win) {\n return win.parent;\n }\n } catch (err) {\n // pass\n }\n}\n\nexport function getOpener(win? : CrossDomainWindowType = window) : ?CrossDomainWindowType {\n\n if (!win) {\n return;\n }\n\n // Make sure we're not actually an iframe which has had window.open() called on us\n if (getParent(win)) {\n return;\n }\n\n try {\n return win.opener;\n } catch (err) {\n // pass\n }\n}\n\nexport function canReadFromWindow(win : CrossDomainWindowType | SameDomainWindowType) : boolean {\n try {\n // $FlowFixMe\n noop(win && win.location && win.location.href);\n return true;\n } catch (err) {\n // pass\n }\n\n return false;\n}\n\nexport function getActualDomain(win? : SameDomainWindowType = window) : string {\n\n let location = win.location;\n\n if (!location) {\n throw new Error(`Can not read window location`);\n }\n\n let protocol = location.protocol;\n\n if (!protocol) {\n throw new Error(`Can not read window protocol`);\n }\n\n if (protocol === PROTOCOL.FILE) {\n return `${ PROTOCOL.FILE }//`;\n }\n\n if (protocol === PROTOCOL.ABOUT) {\n\n let parent = getParent(win);\n if (parent && canReadFromWindow(parent)) {\n // $FlowFixMe\n return getActualDomain(parent);\n }\n\n return `${ PROTOCOL.ABOUT }//`;\n }\n\n let host = location.host;\n\n if (!host) {\n throw new Error(`Can not read window host`);\n }\n\n return `${ protocol }//${ host }`;\n}\n\nexport function getDomain(win? : SameDomainWindowType = window) : string {\n\n let domain = getActualDomain(win);\n\n if (domain && win.mockDomain && win.mockDomain.indexOf(PROTOCOL.MOCK) === 0) {\n return win.mockDomain;\n }\n\n return domain;\n}\n\nexport function isBlankDomain(win : CrossDomainWindowType) : boolean {\n try {\n // $FlowFixMe\n if (!win.location.href) {\n return true;\n }\n\n if (win.location.href === 'about:blank') {\n return true;\n }\n } catch (err) {\n // pass\n }\n\n return false;\n}\n\nexport function isActuallySameDomain(win : CrossDomainWindowType) : boolean {\n\n try {\n if (win === window) {\n return true;\n }\n\n } catch (err) {\n // pass\n }\n\n try {\n let desc = Object.getOwnPropertyDescriptor(win, 'location');\n\n if (desc && desc.enumerable === false) {\n return false;\n }\n\n } catch (err) {\n // pass\n }\n\n try {\n // $FlowFixMe\n if (isAboutProtocol(win) && canReadFromWindow(win)) {\n return true;\n }\n } catch (err) {\n // pass\n }\n\n try {\n // $FlowFixMe\n if (getActualDomain(win) === getActualDomain(window)) {\n return true;\n }\n\n } catch (err) {\n // pass\n }\n\n return false;\n}\n\nexport function isSameDomain(win : CrossDomainWindowType | SameDomainWindowType) : boolean {\n\n if (!isActuallySameDomain(win)) {\n return false;\n }\n\n try {\n\n if (win === window) {\n return true;\n }\n\n // $FlowFixMe\n if (isAboutProtocol(win) && canReadFromWindow(win)) {\n return true;\n }\n\n // $FlowFixMe\n if (getDomain(window) === getDomain(win)) {\n return true;\n }\n\n } catch (err) {\n // pass\n }\n\n return false;\n}\n\n\nexport function assertSameDomain(win : CrossDomainWindowType | SameDomainWindowType) : SameDomainWindowType {\n if (!isSameDomain(win)) {\n throw new Error(`Expected window to be same domain`);\n }\n\n // $FlowFixMe\n return win;\n}\n\nexport function getParents(win : CrossDomainWindowType) : Array {\n\n let result = [];\n\n try {\n\n while (win.parent !== win) {\n result.push(win.parent);\n win = win.parent;\n }\n\n } catch (err) {\n // pass\n }\n\n return result;\n}\n\nexport function isAncestorParent(parent : CrossDomainWindowType, child : CrossDomainWindowType) : boolean {\n\n if (!parent || !child) {\n return false;\n }\n\n let childParent = getParent(child);\n\n if (childParent) {\n return childParent === parent;\n }\n\n if (getParents(child).indexOf(parent) !== -1) {\n return true;\n }\n\n return false;\n}\n\nexport function getFrames(win : CrossDomainWindowType) : Array {\n\n let result = [];\n\n let frames;\n\n try {\n frames = win.frames;\n } catch (err) {\n frames = win;\n }\n\n let len;\n\n try {\n len = frames.length;\n } catch (err) {\n // pass\n }\n\n if (len === 0) {\n return result;\n }\n\n if (len) {\n for (let i = 0; i < len; i++) {\n\n let frame;\n\n try {\n frame = frames[i];\n } catch (err) {\n continue;\n }\n\n result.push(frame);\n }\n\n return result;\n }\n\n for (let i = 0; i < 100; i++) {\n let frame;\n\n try {\n frame = frames[i];\n } catch (err) {\n return result;\n }\n\n if (!frame) {\n return result;\n }\n\n result.push(frame);\n }\n\n return result;\n}\n\n\nexport function getAllChildFrames(win : CrossDomainWindowType) : Array {\n\n let result = [];\n\n for (let frame of getFrames(win)) {\n result.push(frame);\n\n for (let childFrame of getAllChildFrames(frame)) {\n result.push(childFrame);\n }\n }\n\n return result;\n}\n\nexport function getTop(win? : CrossDomainWindowType = window) : ?CrossDomainWindowType {\n\n try {\n if (win.top) {\n return win.top;\n }\n } catch (err) {\n // pass\n }\n\n if (getParent(win) === win) {\n return win;\n }\n\n try {\n if (isAncestorParent(window, win) && window.top) {\n return window.top;\n }\n } catch (err) {\n // pass\n }\n\n try {\n if (isAncestorParent(win, window) && window.top) {\n return window.top;\n }\n } catch (err) {\n // pass\n }\n\n for (let frame of getAllChildFrames(win)) {\n try {\n if (frame.top) {\n return frame.top;\n }\n } catch (err) {\n // pass\n }\n\n if (getParent(frame) === frame) {\n return frame;\n }\n }\n}\n\nexport function getNextOpener(win? : CrossDomainWindowType = window) : ?CrossDomainWindowType {\n return getOpener(getTop(win) || win);\n}\n\nexport function getUltimateTop(win? : CrossDomainWindowType = window) : CrossDomainWindowType {\n let opener = getNextOpener(win);\n\n if (opener) {\n return getUltimateTop(opener);\n }\n\n return top;\n}\n\nexport function getAllFramesInWindow(win : CrossDomainWindowType) : $ReadOnlyArray {\n let top = getTop(win);\n\n if (!top) {\n throw new Error(`Can not determine top window`);\n }\n\n let result = [ ...getAllChildFrames(top), top ];\n\n // Win may be in shadow dom\n if (result.indexOf(win) === -1) {\n result = [ ...result, win, ...getAllChildFrames(win) ];\n }\n\n return result;\n}\n\nexport function getAllWindows(win? : CrossDomainWindowType = window) : $ReadOnlyArray {\n let frames = getAllFramesInWindow(win);\n let opener = getNextOpener(win);\n\n if (opener) {\n return [ ...getAllWindows(opener), ...frames ];\n } else {\n return frames;\n }\n}\n\nexport function isTop(win : CrossDomainWindowType) : boolean {\n return win === getTop(win);\n}\n\nexport function isFrameWindowClosed(frame : HTMLIFrameElement) : boolean {\n\n if (!frame.contentWindow) {\n return true;\n }\n\n if (!frame.parentNode) {\n return true;\n }\n\n let doc = frame.ownerDocument;\n\n if (doc && doc.documentElement && !doc.documentElement.contains(frame)) {\n let parent = frame;\n\n while (parent.parentNode && parent.parentNode !== parent) {\n parent = parent.parentNode;\n }\n\n // $FlowFixMe\n if (!parent.host || !doc.documentElement.contains(parent.host)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction safeIndexOf(collection : Array, item : T) : number {\n for (let i = 0; i < collection.length; i++) {\n\n try {\n if (collection[i] === item) {\n return i;\n }\n } catch (err) {\n // pass\n }\n }\n\n return -1;\n}\n\nlet iframeWindows = [];\nlet iframeFrames = [];\n\nexport function isWindowClosed(win : CrossDomainWindowType, allowMock : boolean = true) : boolean {\n\n try {\n if (win === window) {\n return false;\n }\n } catch (err) {\n return true;\n }\n\n try {\n if (!win) {\n return true;\n }\n\n } catch (err) {\n return true;\n }\n\n try {\n if (win.closed) {\n return true;\n }\n\n } catch (err) {\n\n // I love you so much IE\n\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return false;\n }\n\n return true;\n }\n\n\n if (allowMock && isSameDomain(win)) {\n try {\n // $FlowFixMe\n if (win.mockclosed) {\n return true;\n }\n } catch (err) {\n // pass\n }\n }\n\n // Mobile safari\n\n try {\n if (!win.parent || !win.top) {\n return true;\n }\n } catch (err) {\n // pass\n }\n\n // Yes, this actually happens in IE. win === win errors out when the window\n // is from an iframe, and the iframe was removed from the page.\n\n try {\n noop(win === win); // eslint-disable-line no-self-compare\n } catch (err) {\n return true;\n }\n\n // IE orphaned frame\n\n let iframeIndex = safeIndexOf(iframeWindows, win);\n\n if (iframeIndex !== -1) {\n let frame = iframeFrames[iframeIndex];\n\n if (frame && isFrameWindowClosed(frame)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction cleanIframes() {\n for (let i = 0; i < iframeWindows.length; i++) {\n let closed = false;\n\n try {\n closed = iframeWindows[i].closed;\n } catch (err) {\n // pass\n }\n\n if (closed) {\n iframeFrames.splice(i, 1);\n iframeWindows.splice(i, 1);\n }\n }\n}\n\nexport function linkFrameWindow(frame : HTMLIFrameElement) {\n\n cleanIframes();\n\n if (frame && frame.contentWindow) {\n try {\n iframeWindows.push(frame.contentWindow);\n iframeFrames.push(frame);\n } catch (err) {\n // pass\n }\n }\n}\n\nexport function getUserAgent(win : ?SameDomainWindowType) : string {\n win = win || window;\n return win.navigator.mockUserAgent || win.navigator.userAgent;\n}\n\n\nexport function getFrameByName(win : CrossDomainWindowType, name : string) : ?CrossDomainWindowType {\n\n let winFrames = getFrames(win);\n\n for (let childFrame of winFrames) {\n try {\n // $FlowFixMe\n if (isSameDomain(childFrame) && childFrame.name === name && winFrames.indexOf(childFrame) !== -1) {\n return childFrame;\n }\n } catch (err) {\n // pass\n }\n }\n\n try {\n // $FlowFixMe\n if (winFrames.indexOf(win.frames[name]) !== -1) {\n // $FlowFixMe\n return win.frames[name];\n }\n } catch (err) {\n // pass\n }\n\n try {\n if (winFrames.indexOf(win[name]) !== -1) {\n return win[name];\n }\n } catch (err) {\n // pass\n }\n}\n\nexport function findChildFrameByName(win : CrossDomainWindowType, name : string) : ?CrossDomainWindowType {\n\n let frame = getFrameByName(win, name);\n\n if (frame) {\n return frame;\n }\n\n for (let childFrame of getFrames(win)) {\n let namedFrame = findChildFrameByName(childFrame, name);\n\n if (namedFrame) {\n return namedFrame;\n }\n }\n}\n\nexport function findFrameByName(win : CrossDomainWindowType, name : string) : ?CrossDomainWindowType {\n\n let frame;\n\n frame = getFrameByName(win, name);\n\n if (frame) {\n return frame;\n }\n\n let top = getTop(win) || win;\n\n return findChildFrameByName(top, name);\n}\n\nexport function isParent(win : CrossDomainWindowType, frame : CrossDomainWindowType) : boolean {\n\n let frameParent = getParent(frame);\n\n if (frameParent) {\n return frameParent === win;\n }\n\n for (let childFrame of getFrames(win)) {\n if (childFrame === frame) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isOpener(parent : CrossDomainWindowType, child : CrossDomainWindowType) : boolean {\n\n return parent === getOpener(child);\n}\n\nexport function getAncestor(win? : CrossDomainWindowType = window) : ?CrossDomainWindowType {\n win = win || window;\n\n let opener = getOpener(win);\n\n if (opener) {\n return opener;\n }\n\n let parent = getParent(win);\n\n if (parent) {\n return parent;\n }\n}\n\nexport function getAncestors(win : CrossDomainWindowType) : Array {\n\n let results = [];\n\n let ancestor = win;\n\n while (ancestor) {\n ancestor = getAncestor(ancestor);\n if (ancestor) {\n results.push(ancestor);\n }\n }\n\n return results;\n}\n\n\nexport function isAncestor(parent : CrossDomainWindowType, child : CrossDomainWindowType) : boolean {\n\n let actualParent = getAncestor(child);\n\n if (actualParent) {\n if (actualParent === parent) {\n return true;\n }\n\n return false;\n }\n\n if (child === parent) {\n return false;\n }\n\n if (getTop(child) === child) {\n return false;\n }\n\n for (let frame of getFrames(parent)) {\n if (frame === child) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isPopup(win? : CrossDomainWindowType = window) : boolean {\n return Boolean(getOpener(win));\n}\n\nexport function isIframe(win? : CrossDomainWindowType = window) : boolean {\n return Boolean(getParent(win));\n}\n\nexport function isFullpage(win? : CrossDomainWindowType = window) : boolean {\n return Boolean(!isIframe(win) && !isPopup(win));\n}\n\nfunction anyMatch(collection1, collection2) : boolean {\n\n for (let item1 of collection1) {\n for (let item2 of collection2) {\n if (item1 === item2) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function getDistanceFromTop(win : CrossDomainWindowType = window) : number {\n let distance = 0;\n let parent = win;\n\n while (parent) {\n parent = getParent(parent);\n if (parent) {\n distance += 1;\n }\n }\n\n return distance;\n}\n\nexport function getNthParent(win : CrossDomainWindowType, n : number = 1) : ?CrossDomainWindowType {\n let parent = win;\n\n for (let i = 0; i < n; i++) {\n if (!parent) {\n return;\n }\n\n parent = getParent(parent);\n }\n\n return parent;\n}\n\nexport function getNthParentFromTop(win : CrossDomainWindowType, n : number = 1) : ?CrossDomainWindowType {\n return getNthParent(win, getDistanceFromTop(win) - n);\n}\n\nexport function isSameTopWindow(win1 : CrossDomainWindowType, win2 : CrossDomainWindowType) : boolean {\n\n let top1 = getTop(win1) || win1;\n let top2 = getTop(win2) || win2;\n\n try {\n if (top1 && top2) {\n if (top1 === top2) {\n return true;\n }\n\n return false;\n }\n } catch (err) {\n // pass\n }\n\n let allFrames1 = getAllFramesInWindow(win1);\n let allFrames2 = getAllFramesInWindow(win2);\n\n if (anyMatch(allFrames1, allFrames2)) {\n return true;\n }\n\n let opener1 = getOpener(top1);\n let opener2 = getOpener(top2);\n\n if (opener1 && anyMatch(getAllFramesInWindow(opener1), allFrames2)) {\n return false;\n }\n\n if (opener2 && anyMatch(getAllFramesInWindow(opener2), allFrames1)) {\n return false;\n }\n\n return false;\n}\n\nexport function matchDomain(pattern : DomainMatcher, origin : DomainMatcher) : boolean {\n\n if (typeof pattern === 'string') {\n\n if (typeof origin === 'string') {\n return pattern === WILDCARD || origin === pattern;\n }\n\n if (isRegex(origin)) {\n return false;\n }\n\n if (Array.isArray(origin)) {\n return false;\n }\n }\n\n if (isRegex(pattern)) {\n\n if (isRegex(origin)) {\n return pattern.toString() === origin.toString();\n }\n\n if (Array.isArray(origin)) {\n return false;\n }\n\n // $FlowFixMe\n return Boolean(origin.match(pattern));\n }\n\n if (Array.isArray(pattern)) {\n\n if (Array.isArray(origin)) {\n return JSON.stringify(pattern) === JSON.stringify(origin);\n }\n\n if (isRegex(origin)) {\n return false;\n }\n\n return pattern.some(subpattern => matchDomain(subpattern, origin));\n }\n\n return false;\n}\n\nexport function stringifyDomainPattern(pattern : DomainMatcher) : string {\n if (Array.isArray(pattern)) {\n return `(${ pattern.join(' | ') })`;\n } else if (isRegex(pattern)) {\n return `RegExp(${ pattern.toString() }`;\n } else {\n return pattern.toString();\n }\n}\n\nexport function getDomainFromUrl(url : string) : string {\n\n let domain;\n\n if (url.match(/^(https?|mock|file):\\/\\//)) {\n domain = url;\n } else {\n return getDomain();\n }\n\n domain = domain.split('/').slice(0, 3).join('/');\n\n return domain;\n}\n\nexport function onCloseWindow(win : CrossDomainWindowType, callback : Function, delay : number = 1000, maxtime : number = Infinity) : { cancel : () => void } {\n\n let timeout;\n\n let check = () => {\n\n if (isWindowClosed(win)) {\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n return callback();\n }\n\n if (maxtime <= 0) {\n clearTimeout(timeout);\n } else {\n maxtime -= delay;\n timeout = setTimeout(check, delay);\n }\n };\n\n check();\n\n return {\n cancel() {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n };\n}\n\n// eslint-disable-next-line complexity\nexport function isWindow(obj : Object) : boolean {\n\n try {\n if (obj === window) {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (Object.prototype.toString.call(obj) === '[object Window]') {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (window.Window && obj instanceof window.Window) {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (obj && obj.self === obj) {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (obj && obj.parent === obj) {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (obj && obj.top === obj) {\n return true;\n }\n } catch (err) {\n if (err && err.message === IE_WIN_ACCESS_ERROR) {\n return true;\n }\n }\n\n try {\n if (noop(obj === obj) === '__unlikely_value__') { // eslint-disable-line no-self-compare\n return false;\n }\n\n } catch (err) {\n return true;\n }\n\n try {\n if (obj && obj.__cross_domain_utils_window_check__ === '__unlikely_value__') {\n return false;\n }\n\n } catch (err) {\n return true;\n }\n\n try {\n if ('postMessage' in obj && 'self' in obj && 'location' in obj) {\n return true;\n }\n } catch (err) {\n // pass\n }\n\n return false;\n}\n\nexport function isBrowser() : boolean {\n return (typeof window !== 'undefined' && typeof window.location !== 'undefined');\n}\n\nexport function isCurrentDomain(domain : string) : boolean {\n if (!isBrowser()) {\n return false;\n }\n\n return (getDomain() === domain);\n}\n\nexport function isMockDomain(domain : string) : boolean {\n return domain.indexOf(PROTOCOL.MOCK) === 0;\n}\n\nexport function normalizeMockUrl(url : string) : string {\n if (!isMockDomain(getDomainFromUrl(url))) {\n return url;\n }\n\n if (!__TEST__) {\n throw new Error(`Mock urls not supported out of test mode`);\n }\n\n return url.replace(/^mock:\\/\\/[^/]+/, getActualDomain(window));\n}\n\nexport function closeWindow(win : CrossDomainWindowType) {\n try {\n win.close();\n } catch (err) {\n // pass\n }\n}\n\nexport function getFrameForWindow(win : CrossDomainWindowType) : ?HTMLElement {\n if (isSameDomain(win)) {\n return assertSameDomain(win).frameElement;\n }\n\n for (const frame of document.querySelectorAll('iframe')) {\n if (frame && frame.contentWindow && frame.contentWindow === win) {\n return frame;\n }\n }\n}\n","/* @flow */\n\nexport function safeIndexOf(collection : Array, item : T) : number {\n for (let i = 0; i < collection.length; i++) {\n\n try {\n if (collection[i] === item) {\n return i;\n }\n } catch (err) {\n // pass\n }\n }\n\n return -1;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport function noop(...args : Array) {\n // pass\n}\n","/* @flow */\n\nimport { isWindow, isWindowClosed } from 'cross-domain-utils/src';\n\nimport { hasNativeWeakMap } from './native';\nimport { noop, safeIndexOf } from './util';\n\nexport class CrossDomainSafeWeakMap {\n\n name : string\n weakmap : ?WeakMap\n keys : Array\n values : Array\n\n constructor() {\n // eslint-disable-next-line no-bitwise\n this.name = `__weakmap_${ Math.random() * 1e9 >>> 0 }__`;\n\n if (hasNativeWeakMap()) {\n try {\n this.weakmap = new WeakMap();\n } catch (err) {\n // pass\n }\n }\n\n this.keys = [];\n this.values = [];\n }\n\n _cleanupClosedWindows() {\n\n let weakmap = this.weakmap;\n let keys = this.keys;\n\n for (let i = 0; i < keys.length; i++) {\n let value = keys[i];\n\n if (isWindow(value) && isWindowClosed(value)) {\n\n if (weakmap) {\n try {\n weakmap.delete(value);\n } catch (err) {\n // pass\n }\n }\n\n keys.splice(i, 1);\n this.values.splice(i, 1);\n\n i -= 1;\n }\n }\n }\n\n isSafeToReadWrite(key : K) : boolean {\n\n if (isWindow(key)) {\n return false;\n }\n\n try {\n noop(key && key.self);\n noop(key && key[this.name]);\n } catch (err) {\n return false;\n }\n\n return true;\n }\n\n set(key : K, value : V) {\n\n if (!key) {\n throw new Error(`WeakMap expected key`);\n }\n\n let weakmap = this.weakmap;\n\n if (weakmap) {\n try {\n weakmap.set(key, value);\n } catch (err) {\n delete this.weakmap;\n }\n }\n\n if (this.isSafeToReadWrite(key)) {\n try {\n let name = this.name;\n let entry = key[name];\n\n if (entry && entry[0] === key) {\n entry[1] = value;\n } else {\n Object.defineProperty(key, name, {\n value: [ key, value ],\n writable: true\n });\n }\n\n return;\n\n } catch (err) {\n // pass\n }\n }\n\n this._cleanupClosedWindows();\n\n let keys = this.keys;\n let values = this.values;\n let index = safeIndexOf(keys, key);\n\n if (index === -1) {\n keys.push(key);\n values.push(value);\n } else {\n values[index] = value;\n }\n }\n\n get(key : K) : V | void {\n\n if (!key) {\n throw new Error(`WeakMap expected key`);\n }\n\n let weakmap = this.weakmap;\n\n if (weakmap) {\n try {\n if (weakmap.has(key)) {\n return weakmap.get(key);\n }\n \n } catch (err) {\n delete this.weakmap;\n }\n }\n\n if (this.isSafeToReadWrite(key)) {\n try {\n let entry = key[this.name];\n\n if (entry && entry[0] === key) {\n return entry[1];\n }\n\n return;\n } catch (err) {\n // pass\n }\n }\n\n this._cleanupClosedWindows();\n\n let keys = this.keys;\n let index = safeIndexOf(keys, key);\n\n if (index === -1) {\n return;\n }\n\n return this.values[index];\n }\n\n delete(key : K) {\n\n if (!key) {\n throw new Error(`WeakMap expected key`);\n }\n\n let weakmap = this.weakmap;\n\n if (weakmap) {\n try {\n weakmap.delete(key);\n } catch (err) {\n delete this.weakmap;\n }\n }\n\n if (this.isSafeToReadWrite(key)) {\n try {\n let entry = key[this.name];\n\n if (entry && entry[0] === key) {\n entry[0] = entry[1] = undefined;\n }\n } catch (err) {\n // pass\n }\n }\n\n this._cleanupClosedWindows();\n\n let keys = this.keys;\n let index = safeIndexOf(keys, key);\n\n if (index !== -1) {\n keys.splice(index, 1);\n this.values.splice(index, 1);\n }\n }\n\n has(key : K) : boolean {\n\n if (!key) {\n throw new Error(`WeakMap expected key`);\n }\n\n let weakmap = this.weakmap;\n\n if (weakmap) {\n try {\n if (weakmap.has(key)) {\n return true;\n }\n } catch (err) {\n delete this.weakmap;\n }\n }\n\n if (this.isSafeToReadWrite(key)) {\n try {\n let entry = key[this.name];\n\n if (entry && entry[0] === key) {\n return true;\n }\n\n return false;\n } catch (err) {\n // pass\n }\n }\n\n this._cleanupClosedWindows();\n\n let index = safeIndexOf(this.keys, key);\n return index !== -1;\n }\n\n getOrSet(key : K, getter : () => V) : V {\n if (this.has(key)) {\n // $FlowFixMe\n return this.get(key);\n }\n\n let value = getter();\n this.set(key, value);\n return value;\n }\n}\n","/* @flow */\n/* eslint max-lines: 0 */\n\nimport { ZalgoPromise } from 'zalgo-promise/src';\nimport { WeakMap } from 'cross-domain-safe-weakmap/src';\n\nimport type { CancelableType } from './types';\n\nexport function getFunctionName (fn : T) : string {\n return fn.name || fn.__name__ || fn.displayName || 'anonymous';\n}\n\nexport function setFunctionName (fn : T, name : string) : T {\n try {\n delete fn.name;\n fn.name = name;\n } catch (err) {\n // pass\n }\n\n fn.__name__ = fn.displayName = name;\n return fn;\n}\n\nexport function base64encode(str : string) : string {\n if (typeof btoa === 'function') {\n return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (m, p1) => {\n return String.fromCharCode(parseInt(p1, 16));\n }));\n }\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf8').toString('base64');\n }\n\n throw new Error(`Can not find window.btoa or Buffer`);\n}\n\nexport function base64decode(str : string) : string {\n if (typeof atob === 'function') {\n return decodeURIComponent(Array.prototype.map.call(atob(str), c => {\n // eslint-disable-next-line prefer-template\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n }).join(''));\n }\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'base64').toString('utf8');\n }\n\n throw new Error(`Can not find window.atob or Buffer`);\n}\n\nexport function uniqueID() : string {\n\n const chars = '0123456789abcdef';\n\n const randomID = 'xxxxxxxxxx'.replace(/./g, () => {\n return chars.charAt(Math.floor(Math.random() * chars.length));\n });\n\n const timeID = base64encode(\n new Date().toISOString().slice(11, 19).replace('T', '.')\n ).replace(/[^a-zA-Z0-9]/g, '').toLowerCase();\n\n return `${ randomID }_${ timeID }`;\n}\n\nexport function getGlobal() : Object {\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n if (typeof __GLOBAL__ !== 'undefined') {\n return __GLOBAL__;\n }\n throw new Error(`No global found`);\n}\n\nlet objectIDs;\n\nexport function getObjectID(obj : Object) : string {\n\n objectIDs = objectIDs || new WeakMap();\n\n if (obj === null || obj === undefined || (typeof obj !== 'object' && typeof obj !== 'function')) {\n throw new Error(`Invalid object`);\n }\n\n let uid = objectIDs.get(obj);\n\n if (!uid) {\n uid = `${ typeof obj }:${ uniqueID() }`;\n objectIDs.set(obj, uid);\n }\n\n return uid;\n}\n\nfunction serializeArgs(args : $ReadOnlyArray) : string {\n try {\n return JSON.stringify(Array.prototype.slice.call(args), (subkey, val) => {\n if (typeof val === 'function') {\n return `memoize[${ getObjectID(val) }]`;\n }\n return val;\n });\n } catch (err) {\n throw new Error(`Arguments not serializable -- can not be used to memoize`);\n }\n}\ntype MemoizeOptions = {|\n name? : string,\n time? : number,\n thisNamespace? : boolean\n|};\n\nconst getDefaultMemoizeOptions = () : MemoizeOptions => {\n // $FlowFixMe\n return {};\n};\n\nconst memoizedFunctions = [];\n\nexport function memoize(method : F, options? : MemoizeOptions = getDefaultMemoizeOptions()) : F & {| reset : () => void |} {\n const cacheMap = new WeakMap();\n\n const memoizedFunction = function memoizedFunction(...args) : mixed {\n const cache = cacheMap.getOrSet(options.thisNamespace ? this : method, () => ({}));\n\n const key : string = serializeArgs(args);\n\n const cacheTime = options.time;\n if (cache[key] && cacheTime && (Date.now() - cache[key].time) < cacheTime) {\n delete cache[key];\n }\n\n if (cache[key]) {\n return cache[key].value;\n }\n\n const time = Date.now();\n const value = method.apply(this, arguments);\n\n cache[key] = { time, value };\n\n return cache[key].value;\n };\n\n memoizedFunction.reset = () => {\n cacheMap.delete(options.thisNamespace ? this : method);\n };\n\n memoizedFunctions.push(memoizedFunction);\n\n // $FlowFixMe\n const result : F = memoizedFunction;\n\n return setFunctionName(result, `${ options.name || getFunctionName(method) }::memoized`);\n}\n\nmemoize.clear = () => {\n for (const memoizedFunction of memoizedFunctions) {\n memoizedFunction.reset();\n }\n};\n\nexport function promiseIdentity(item : ZalgoPromise | T) : ZalgoPromise {\n // $FlowFixMe\n return ZalgoPromise.resolve(item);\n}\n\n// eslint-disable-next-line flowtype/no-weak-types\nexport function memoizePromise(method : (...args : $ReadOnlyArray) => ZalgoPromise) : ((...args : $ReadOnlyArray) => ZalgoPromise) {\n let cache = {};\n\n // eslint-disable-next-line flowtype/no-weak-types\n function memoizedPromiseFunction(...args : $ReadOnlyArray) : ZalgoPromise {\n const key : string = serializeArgs(args);\n\n if (cache.hasOwnProperty(key)) {\n return cache[key];\n }\n\n cache[key] = ZalgoPromise.try(() => method.apply(this, arguments))\n .finally(() => {\n delete cache[key];\n });\n\n return cache[key];\n }\n\n memoizedPromiseFunction.reset = () => {\n cache = {};\n };\n\n return setFunctionName(memoizedPromiseFunction, `${ getFunctionName(method) }::promiseMemoized`);\n}\n\ntype PromisifyOptions = {|\n name ? : string\n|};\n\nconst getDefaultPromisifyOptions = () : PromisifyOptions => {\n // $FlowFixMe\n return {};\n};\n\n// eslint-disable-next-line flowtype/no-weak-types\nexport function promisify(method : (...args : $ReadOnlyArray) => R, options : PromisifyOptions = getDefaultPromisifyOptions()) : ((...args : $ReadOnlyArray) => ZalgoPromise) {\n function promisifiedFunction() : ZalgoPromise {\n return ZalgoPromise.try(method, this, arguments);\n }\n\n if (options.name) {\n promisifiedFunction.displayName = `${ options.name }:promisified`;\n }\n\n return setFunctionName(promisifiedFunction, `${ getFunctionName(method) }::promisified`);\n}\n\n// eslint-disable-next-line flowtype/no-weak-types\nexport function inlineMemoize(method : (...args : $ReadOnlyArray) => R, logic : (...args : $ReadOnlyArray) => R, args : $ReadOnlyArray = []) : R {\n // $FlowFixMe\n const cache : {| [string] : R |} = method.__inline_memoize_cache__ = method.__inline_memoize_cache__ || {};\n const key = serializeArgs(args);\n\n if (cache.hasOwnProperty(key)) {\n return cache[key];\n }\n \n const result = cache[key] = logic(...args);\n\n return result;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport function noop(...args : $ReadOnlyArray) {\n // pass\n}\n\nexport function once(method : Function) : Function {\n let called = false;\n\n const onceFunction = function() : mixed {\n if (!called) {\n called = true;\n return method.apply(this, arguments);\n }\n };\n\n return setFunctionName(onceFunction, `${ getFunctionName(method) }::once`);\n}\n\nexport function hashStr(str : string) : number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash += str[i].charCodeAt(0) * Math.pow((i % 10) + 1, 5);\n }\n return Math.floor(Math.pow(Math.sqrt(hash), 5));\n}\n\nexport function strHashStr(str : string) : string {\n let hash = '';\n\n for (let i = 0; i < str.length; i++) {\n let total = (str[i].charCodeAt(0) * i);\n\n if (str[i + 1]) {\n total += (str[i + 1].charCodeAt(0) * (i - 1));\n }\n\n hash += String.fromCharCode(97 + (Math.abs(total) % 26));\n }\n\n return hash;\n}\n\nexport function match(str : string, pattern : RegExp) : ?string {\n const regmatch = str.match(pattern);\n if (regmatch) {\n return regmatch[1];\n }\n}\n\nexport function awaitKey(obj : Object, key : string) : ZalgoPromise {\n return new ZalgoPromise(resolve => {\n\n let value = obj[key];\n\n if (value) {\n return resolve(value);\n }\n\n delete obj[key];\n\n Object.defineProperty(obj, key, {\n\n configurable: true,\n\n set(item) {\n value = item;\n\n if (value) {\n resolve(value);\n }\n },\n\n get() : mixed {\n return value;\n }\n });\n });\n}\n\nexport function stringifyError(err : mixed, level : number = 1) : string {\n\n if (level >= 3) {\n return 'stringifyError stack overflow';\n }\n\n try {\n if (!err) {\n return ``;\n }\n\n if (typeof err === 'string') {\n return err;\n }\n\n if (err instanceof Error) {\n const stack = err && err.stack;\n const message = err && err.message;\n\n if (stack && message) {\n if (stack.indexOf(message) !== -1) {\n return stack;\n } else {\n return `${ message }\\n${ stack }`;\n }\n } else if (stack) {\n return stack;\n } else if (message) {\n return message;\n }\n }\n\n if (err && err.toString && typeof err.toString === 'function') {\n // $FlowFixMe\n return err.toString();\n }\n\n return Object.prototype.toString.call(err);\n\n } catch (newErr) {\n return `Error while stringifying error: ${ stringifyError(newErr, level + 1) }`;\n }\n}\n\nexport function stringifyErrorMessage(err : mixed) : string {\n\n const defaultMessage = ``;\n\n if (!err) {\n return defaultMessage;\n }\n\n if (err instanceof Error) {\n return err.message || defaultMessage;\n }\n\n if (typeof err.message === 'string') {\n return err.message || defaultMessage;\n }\n\n return defaultMessage;\n}\n\nexport function stringify(item : mixed) : string {\n if (typeof item === 'string') {\n return item;\n }\n\n if (item && item.toString && typeof item.toString === 'function') {\n // $FlowFixMe\n return item.toString();\n }\n\n return Object.prototype.toString.call(item);\n}\n\nexport function domainMatches(hostname : string, domain : string) : boolean {\n hostname = hostname.split('://')[1];\n const index = hostname.indexOf(domain);\n return (index !== -1 && hostname.slice(index) === domain);\n}\n\nexport function patchMethod(obj : Object, name : string, handler : Function) {\n const original = obj[name];\n\n obj[name] = function patchedMethod() : mixed {\n return handler({\n context: this,\n args: Array.prototype.slice.call(arguments),\n original,\n callOriginal: () => original.apply(this, arguments)\n });\n };\n}\n\nexport function extend(obj : T, source : Object) : T {\n if (!source) {\n return obj;\n }\n\n if (Object.assign) {\n return Object.assign(obj, source);\n }\n\n for (const key in source) {\n if (source.hasOwnProperty(key)) {\n obj[key] = source[key];\n }\n }\n\n return obj;\n}\n\nexport function values(obj : { [string] : T }) : $ReadOnlyArray {\n const result = [];\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n result.push(obj[key]);\n }\n }\n return result;\n}\n\nexport function perc(pixels : number, percentage : number) : number {\n return Math.round((pixels * percentage) / 100);\n}\n\nexport function min(...args : $ReadOnlyArray) : number {\n return Math.min(...args);\n}\n\nexport function max(...args : $ReadOnlyArray) : number {\n return Math.max(...args);\n}\n\nexport function regexMap(str : string, regexp : RegExp, handler : () => T) : $ReadOnlyArray {\n const results = [];\n\n // $FlowFixMe\n str.replace(regexp, function regexMapMatcher(item) {\n results.push(handler ? handler.apply(null, arguments) : item);\n });\n\n // $FlowFixMe\n return results;\n}\n\nexport function svgToBase64(svg : string) : string {\n return `data:image/svg+xml;base64,${ base64encode(svg) }`;\n}\n\nexport function objFilter(obj : { [string] : T }, filter? : (T, ?string) => mixed = Boolean) : { [string] : R } {\n const result = {};\n\n for (const key in obj) {\n if (!obj.hasOwnProperty(key) || !filter(obj[key], key)) {\n continue;\n }\n\n result[key] = obj[key];\n }\n\n return result;\n}\n\nexport function identity (item : T) : T {\n return item;\n}\n\nexport function regexTokenize(text : string, regexp : RegExp) : $ReadOnlyArray {\n const result = [];\n text.replace(regexp, token => {\n result.push(token);\n return '';\n });\n return result;\n}\n\nexport function promiseDebounce(method : () => ZalgoPromise | T, delay : number = 50) : () => ZalgoPromise {\n\n let promise;\n let timeout;\n\n const promiseDebounced = function() : ZalgoPromise {\n if (timeout) {\n clearTimeout(timeout);\n }\n\n const localPromise = promise = promise || new ZalgoPromise();\n\n timeout = setTimeout(() => {\n promise = null;\n timeout = null;\n\n ZalgoPromise.try(method).then(\n result => { localPromise.resolve(result); },\n err => { localPromise.reject(err); }\n );\n }, delay);\n\n return localPromise;\n };\n\n return setFunctionName(promiseDebounced, `${ getFunctionName(method) }::promiseDebounced`);\n}\n\nexport function safeInterval(method : Function, time : number) : {| cancel : () => void |} {\n\n let timeout;\n\n function loop() {\n timeout = setTimeout(() => {\n method();\n loop();\n }, time);\n }\n\n loop();\n\n return {\n cancel() {\n clearTimeout(timeout);\n }\n };\n}\n\nexport function isInteger(str : string) : boolean {\n return Boolean(str.match(/^[0-9]+$/));\n}\n\nexport function isFloat(str : string) : boolean {\n return Boolean(str.match(/^[0-9]+\\.[0-9]+$/));\n}\n\nexport function serializePrimitive(value : string | number | boolean) : string {\n return value.toString();\n}\n\nexport function deserializePrimitive(value : string) : string | number | boolean {\n if (value === 'true') {\n return true;\n } else if (value === 'false') {\n return false;\n } else if (isInteger(value)) {\n return parseInt(value, 10);\n } else if (isFloat(value)) {\n return parseFloat(value);\n } else {\n return value;\n }\n}\n\nexport function dotify(obj : Object, prefix : string = '', newobj : Object = {}) : { [string] : string } {\n prefix = prefix ? `${ prefix }.` : prefix;\n for (const key in obj) {\n if (!obj.hasOwnProperty(key) || obj[key] === undefined || obj[key] === null || typeof obj[key] === 'function') {\n continue;\n } else if (obj[key] && Array.isArray(obj[key]) && obj[key].length && obj[key].every(val => typeof val !== 'object')) {\n newobj[`${ prefix }${ key }[]`] = obj[key].join(',');\n } else if (obj[key] && typeof obj[key] === 'object') {\n newobj = dotify(obj[key], `${ prefix }${ key }`, newobj);\n } else {\n newobj[`${ prefix }${ key }`] = serializePrimitive(obj[key]);\n }\n }\n return newobj;\n}\n\nexport function undotify(obj : { [string] : string }) : Object {\n \n const result = {};\n\n for (let key in obj) {\n if (!obj.hasOwnProperty(key) || typeof obj[key] !== 'string') {\n continue;\n }\n\n let value = obj[key];\n\n if (key.match(/^.+\\[\\]$/)) {\n key = key.slice(0, -2);\n value = value.split(',').map(deserializePrimitive);\n } else {\n value = deserializePrimitive(value);\n }\n\n let keyResult = result;\n const parts = key.split('.');\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isLast = (i + 1 === parts.length);\n const isIndex = !isLast && isInteger(parts[i + 1]);\n\n if (part === 'constructor' || part === 'prototype' || part === '__proto__') {\n throw new Error(`Disallowed key: ${ part }`);\n }\n\n if (isLast) {\n // $FlowFixMe\n keyResult[part] = value;\n } else {\n // $FlowFixMe\n keyResult = keyResult[part] = keyResult[part] || (isIndex ? [] : {});\n }\n }\n }\n\n return result;\n}\n\nexport type EventEmitterType = {|\n on : (eventName : string, handler : Function) => CancelableType,\n once : (eventName : string, handler : Function) => CancelableType,\n trigger : (eventName : string, ...args : $ReadOnlyArray) => ZalgoPromise,\n triggerOnce : (eventName : string, ...args : $ReadOnlyArray) => ZalgoPromise,\n reset : () => void\n|};\n\nexport function eventEmitter() : EventEmitterType {\n const triggered = {};\n let handlers = {};\n\n return {\n\n on(eventName : string, handler : Function) : CancelableType {\n const handlerList = handlers[eventName] = handlers[eventName] || [];\n\n handlerList.push(handler);\n\n let cancelled = false;\n\n return {\n cancel() {\n if (!cancelled) {\n cancelled = true;\n handlerList.splice(handlerList.indexOf(handler), 1);\n }\n\n }\n };\n },\n\n once(eventName : string, handler : Function) : CancelableType {\n\n const listener = this.on(eventName, () => {\n listener.cancel();\n handler();\n });\n\n return listener;\n },\n\n trigger(eventName : string, ...args : $ReadOnlyArray) : ZalgoPromise {\n\n const handlerList = handlers[eventName];\n const promises = [];\n\n if (handlerList) {\n for (const handler of handlerList) {\n promises.push(ZalgoPromise.try(() => handler(...args)));\n }\n }\n\n return ZalgoPromise.all(promises).then(noop);\n },\n\n triggerOnce(eventName : string, ...args : $ReadOnlyArray) : ZalgoPromise {\n\n if (triggered[eventName]) {\n return ZalgoPromise.resolve();\n }\n\n triggered[eventName] = true;\n return this.trigger(eventName, ...args);\n },\n\n reset() {\n handlers = {};\n }\n };\n}\n\nexport function camelToDasherize(string : string) : string {\n return string.replace(/([A-Z])/g, (g) => {\n return `-${ g.toLowerCase() }`;\n });\n}\n\nexport function dasherizeToCamel(string : string) : string {\n return string.replace(/-([a-z])/g, (g) => {\n return g[1].toUpperCase();\n });\n}\n\nexport function capitalizeFirstLetter(string : string) : string {\n return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();\n}\n\nexport function get(item : Object, path : string, def : mixed) : mixed {\n\n if (!path) {\n return def;\n }\n\n const pathParts = path.split('.');\n\n // Loop through each section of our key path\n\n for (let i = 0; i < pathParts.length; i++) {\n\n // If we have an object, we can get the key\n if (typeof item === 'object' && item !== null) {\n item = item[pathParts[i]];\n\n // Otherwise, we should return the default (undefined if not provided)\n } else {\n return def;\n }\n }\n\n // If our final result is undefined, we should return the default\n\n return item === undefined ? def : item;\n}\n\nexport function safeTimeout(method : Function, time : number) {\n\n const interval = safeInterval(() => {\n time -= 100;\n if (time <= 0) {\n interval.cancel();\n method();\n }\n }, 100);\n}\n\nexport function defineLazyProp(obj : Object | $ReadOnlyArray, key : string | number, getter : () => T) {\n if (Array.isArray(obj)) {\n if (typeof key !== 'number') {\n throw new TypeError(`Array key must be number`);\n }\n } else if (typeof obj === 'object' && obj !== null) {\n if (typeof key !== 'string') {\n throw new TypeError(`Object key must be string`);\n }\n }\n \n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: true,\n get: () => {\n // $FlowFixMe\n delete obj[key];\n const value = getter();\n // $FlowFixMe\n obj[key] = value;\n return value;\n },\n set: (value : T) => {\n // $FlowFixMe\n delete obj[key];\n // $FlowFixMe\n obj[key] = value;\n }\n });\n}\n\nexport function arrayFrom(item : Iterable) : $ReadOnlyArray { // eslint-disable-line no-undef\n return Array.prototype.slice.call(item);\n}\n\nexport function isObject(item : mixed) : boolean {\n return (typeof item === 'object' && item !== null);\n}\n\nexport function isObjectObject(obj : mixed) : boolean {\n return isObject(obj) && Object.prototype.toString.call(obj) === '[object Object]';\n}\n\nexport function isPlainObject(obj : mixed) : boolean {\n if (!isObjectObject(obj)) {\n return false;\n }\n\n // $FlowFixMe\n const constructor = obj.constructor;\n\n if (typeof constructor !== 'function') {\n return false;\n }\n\n const prototype = constructor.prototype;\n\n if (!isObjectObject(prototype)) {\n return false;\n }\n\n if (!prototype.hasOwnProperty('isPrototypeOf')) {\n return false;\n }\n\n return true;\n}\n\nexport function replaceObject | Object> (item : T, replacer : (mixed, string | number, string) => mixed, fullKey : string = '') : T {\n\n if (Array.isArray(item)) {\n const length = item.length;\n const result : Array = [];\n\n for (let i = 0; i < length; i++) {\n\n \n defineLazyProp(result, i, () => {\n const itemKey = fullKey ? `${ fullKey }.${ i }` : `${ i }`;\n const el = item[i];\n\n let child = replacer(el, i, itemKey);\n\n if (isPlainObject(child) || Array.isArray(child)) {\n // $FlowFixMe\n child = replaceObject(child, replacer, itemKey);\n }\n\n return child;\n });\n }\n\n // $FlowFixMe\n return result;\n } else if (isPlainObject(item)) {\n const result = {};\n\n for (const key in item) {\n if (!item.hasOwnProperty(key)) {\n continue;\n }\n\n defineLazyProp(result, key, () => {\n const itemKey = fullKey ? `${ fullKey }.${ key }` : `${ key }`;\n // $FlowFixMe\n const el = item[key];\n\n let child = replacer(el, key, itemKey);\n\n if (isPlainObject(child) || Array.isArray(child)) {\n // $FlowFixMe\n child = replaceObject(child, replacer, itemKey);\n }\n\n return child;\n });\n }\n\n // $FlowFixMe\n return result;\n } else {\n throw new Error(`Pass an object or array`);\n }\n}\n\n\nexport function copyProp(source : Object, target : Object, name : string, def : mixed) {\n if (source.hasOwnProperty(name)) {\n const descriptor = Object.getOwnPropertyDescriptor(source, name);\n // $FlowFixMe\n Object.defineProperty(target, name, descriptor);\n\n } else {\n target[name] = def;\n }\n}\n\ntype RegexResultType = {|\n text : string,\n groups : $ReadOnlyArray,\n start : number,\n end : number,\n length : number,\n replace : (text : string) => string\n|};\n\nexport function regex(pattern : string | RegExp, string : string, start : number = 0) : ?RegexResultType {\n\n if (typeof pattern === 'string') {\n // eslint-disable-next-line security/detect-non-literal-regexp\n pattern = new RegExp(pattern);\n }\n\n const result = string.slice(start).match(pattern);\n\n if (!result) {\n return;\n }\n\n // $FlowFixMe\n const index : number = result.index;\n const regmatch = result[0];\n\n return {\n text: regmatch,\n groups: result.slice(1),\n start: start + index,\n end: start + index + regmatch.length,\n length: regmatch.length,\n\n replace(text : string) : string {\n\n if (!regmatch) {\n return '';\n }\n\n return `${ regmatch.slice(0, start + index) }${ text }${ regmatch.slice(index + regmatch.length) }`;\n }\n };\n}\n\nexport function regexAll(pattern : string | RegExp, string : string) : $ReadOnlyArray {\n\n const matches = [];\n let start = 0;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const regmatch = regex(pattern, string, start);\n\n if (!regmatch) {\n break;\n }\n\n matches.push(regmatch);\n start = match.end;\n }\n\n return matches;\n}\n\nexport function isDefined(value : ?mixed) : boolean {\n return value !== null && value !== undefined;\n}\n\nexport function cycle(method : Function) : ZalgoPromise {\n return ZalgoPromise.try(method).then(() => cycle(method));\n}\n\nexport function debounce(method : (...args : $ReadOnlyArray) => T, time : number = 100) : (...args : $ReadOnlyArray) => void {\n\n let timeout;\n\n const debounceWrapper = function() {\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n return method.apply(this, arguments);\n }, time);\n };\n\n return setFunctionName(debounceWrapper, `${ getFunctionName(method) }::debounced`);\n}\n\nexport function isRegex(item : mixed) : boolean {\n return Object.prototype.toString.call(item) === '[object RegExp]';\n}\n\ntype FunctionProxy = (method : T) => T;\n\n// eslint-disable-next-line flowtype/no-weak-types\nexport const weakMapMemoize : FunctionProxy<*> = (method : (arg : any) => R) : ((...args : $ReadOnlyArray) => R) => {\n\n const weakmap = new WeakMap();\n\n // eslint-disable-next-line flowtype/no-weak-types\n return function weakmapMemoized(arg : any) : R {\n return weakmap.getOrSet(arg, () => method.call(this, arg));\n };\n};\n\ntype FunctionPromiseProxy) => ZalgoPromise> = (T) => T;\n\n// eslint-disable-next-line flowtype/no-weak-types\nexport const weakMapMemoizePromise : FunctionPromiseProxy<*, *> = (method : (arg : any) => ZalgoPromise) : ((...args : $ReadOnlyArray) => ZalgoPromise) => {\n\n const weakmap = new WeakMap();\n\n // eslint-disable-next-line flowtype/no-weak-types\n return function weakmapMemoizedPromise(arg : any) : ZalgoPromise {\n return weakmap.getOrSet(arg, () =>\n method.call(this, arg).finally(() => {\n weakmap.delete(arg);\n }));\n };\n};\n\nexport function getOrSet(obj : O, key : string, getter : () => T) : T {\n if (obj.hasOwnProperty(key)) {\n return obj[key];\n }\n\n const val = getter();\n obj[key] = val;\n return val;\n}\n\nexport type CleanupType = {|\n set : (string, T) => T, // eslint-disable-line no-undef\n register : (Function) => void,\n all : () => ZalgoPromise\n|};\n\nexport function cleanup(obj : Object) : CleanupType {\n\n const tasks = [];\n let cleaned = false;\n\n return {\n set(name : string, item : T) : T {\n if (!cleaned) {\n obj[name] = item;\n this.register(() => {\n delete obj[name];\n });\n }\n return item;\n },\n\n register(method : Function) {\n if (cleaned) {\n method();\n } else {\n tasks.push(once(method));\n }\n },\n\n all() : ZalgoPromise {\n const results = [];\n cleaned = true;\n\n while (tasks.length) {\n const task = tasks.shift();\n results.push(task());\n }\n\n return ZalgoPromise.all(results).then(noop);\n }\n };\n}\n\nexport function tryCatch(fn : () => T) : {| result : T, error : void |} | {| result : void, error : mixed |} {\n let result;\n let error;\n\n try {\n result = fn();\n } catch (err) {\n error = err;\n }\n \n // $FlowFixMe\n return { result, error };\n}\n\n// eslint-disable-next-line flowtype/no-mutable-array\nexport function removeFromArray>(arr : T, item : X) {\n const index = arr.indexOf(item);\n if (index !== -1) {\n arr.splice(index, 1);\n }\n}\n\nexport function assertExists(name : string, thing : void | null | T) : T {\n if (thing === null || typeof thing === 'undefined') {\n throw new Error(`Expected ${ name } to be present`);\n }\n \n return thing;\n}\n\nexport function unique(arr : $ReadOnlyArray) : $ReadOnlyArray {\n const result = {};\n for (const item of arr) {\n result[item] = true;\n }\n return Object.keys(result);\n}\n\nexport const memoizedValues = memoize(values);\n\nexport const constHas = (constant : T, value : X) : boolean => {\n return memoizedValues(constant).indexOf(value) !== -1;\n};\n","/* @flow */\n\nexport function hasNativeWeakMap() : boolean {\n\n if (typeof WeakMap === 'undefined') {\n return false;\n }\n\n if (typeof Object.freeze === 'undefined') {\n return false;\n }\n\n try {\n\n let testWeakMap = new WeakMap();\n let testKey = {};\n let testValue = '__testvalue__';\n\n Object.freeze(testKey);\n\n testWeakMap.set(testKey, testValue);\n\n if (testWeakMap.get(testKey) === testValue) {\n return true;\n }\n\n return false;\n\n } catch (err) {\n\n return false;\n }\n}\n","/* @flow */\n/* eslint max-lines: off */\n\nimport { ZalgoPromise } from 'zalgo-promise/src';\nimport { linkFrameWindow, isWindowClosed,\n type SameDomainWindowType, type CrossDomainWindowType } from 'cross-domain-utils/src';\nimport { WeakMap } from 'cross-domain-safe-weakmap/src';\n\nimport { inlineMemoize, memoize, noop, stringify, capitalizeFirstLetter,\n once, extend, safeInterval, uniqueID, arrayFrom } from './util';\nimport { isDevice } from './device';\nimport { KEY_CODES } from './constants';\nimport type { CancelableType } from './types';\n\ntype ElementRefType = string | HTMLElement;\n\nexport function isDocumentReady() : boolean {\n return Boolean(document.body) && (document.readyState === 'complete');\n}\n\nexport function isDocumentInteractive() : boolean {\n return Boolean(document.body) && (document.readyState === 'interactive');\n}\n\nexport function urlEncode(str : string) : string {\n return str.replace(/\\?/g, '%3F').replace(/&/g, '%26').replace(/#/g, '%23').replace(/\\+/g, '%2B');\n}\n\nexport function waitForWindowReady() : ZalgoPromise {\n return inlineMemoize(waitForWindowReady, () : ZalgoPromise => {\n return new ZalgoPromise(resolve => {\n if (isDocumentReady()) {\n resolve();\n }\n\n window.addEventListener('load', () => resolve());\n });\n });\n}\n\nexport const waitForDocumentReady = memoize(() : ZalgoPromise => {\n return new ZalgoPromise(resolve => {\n\n if (isDocumentReady() || isDocumentInteractive()) {\n return resolve();\n }\n\n const interval = setInterval(() => {\n if (isDocumentReady() || isDocumentInteractive()) {\n clearInterval(interval);\n return resolve();\n }\n }, 10);\n });\n});\n\nexport function waitForDocumentBody() : ZalgoPromise {\n return ZalgoPromise.try(() => {\n if (document.body) {\n return document.body;\n }\n\n return waitForDocumentReady().then(() => {\n if (document.body) {\n return document.body;\n }\n\n throw new Error('Document ready but document.body not present');\n });\n });\n}\n\nexport function parseQuery(queryString : string) : Object {\n return inlineMemoize(parseQuery, () : Object => {\n const params = {};\n\n if (!queryString) {\n return params;\n }\n\n if (queryString.indexOf('=') === -1) {\n return params;\n }\n\n for (let pair of queryString.split('&')) {\n pair = pair.split('=');\n\n if (pair[0] && pair[1]) {\n params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n }\n }\n\n return params;\n }, [ queryString ]);\n}\n\n\nexport function getQueryParam(name : string) : string {\n return parseQuery(window.location.search.slice(1))[name];\n}\n\nexport function urlWillRedirectPage(url : string) : boolean {\n\n if (url.indexOf('#') === -1) {\n return true;\n }\n\n if (url.indexOf('#') === 0) {\n return false;\n }\n\n if (url.split('#')[0] === window.location.href.split('#')[0]) {\n return false;\n }\n\n return true;\n}\n\nexport function formatQuery(obj : { [ string ] : string } = {}) : string {\n\n return Object.keys(obj).filter(key => {\n return typeof obj[key] === 'string';\n }).map(key => {\n return `${ urlEncode(key) }=${ urlEncode(obj[key]) }`;\n }).join('&');\n}\n\nexport function extendQuery(originalQuery : string, props : { [ string ] : string } = {}) : string {\n\n if (!props || !Object.keys(props).length) {\n return originalQuery;\n }\n\n return formatQuery({\n ...parseQuery(originalQuery),\n ...props\n });\n}\n\nexport function extendUrl(url : string, options : {| query? : { [string] : string }, hash? : { [string] : string } |}) : string {\n\n const query = options.query || {};\n const hash = options.hash || {};\n\n let originalUrl;\n let originalQuery;\n let originalHash;\n\n [ originalUrl, originalHash ] = url.split('#');\n [ originalUrl, originalQuery ] = originalUrl.split('?');\n\n const queryString = extendQuery(originalQuery, query);\n const hashString = extendQuery(originalHash, hash);\n\n if (queryString) {\n originalUrl = `${ originalUrl }?${ queryString }`;\n }\n\n if (hashString) {\n originalUrl = `${ originalUrl }#${ hashString }`;\n }\n\n return originalUrl;\n}\n\nexport function redirect(url : string, win : CrossDomainWindowType = window) : ZalgoPromise {\n return new ZalgoPromise(resolve => {\n win.location = url;\n if (!urlWillRedirectPage(url)) {\n resolve();\n }\n });\n}\n\nexport function hasMetaViewPort() : boolean {\n const meta = document.querySelector('meta[name=viewport]');\n\n if (isDevice() && window.screen.width < 660 && !meta) {\n return false;\n }\n\n return true;\n}\n\nexport function isElementVisible(el : HTMLElement) : boolean {\n return Boolean(el.offsetWidth || el.offsetHeight || el.getClientRects().length);\n}\n\nexport function getPerformance() : ?Performance {\n return inlineMemoize(getPerformance, () : ?Performance => {\n const performance = window.performance;\n\n if (\n performance &&\n performance.now &&\n performance.timing &&\n performance.timing.connectEnd &&\n performance.timing.navigationStart &&\n (Math.abs(performance.now() - Date.now()) > 1000) &&\n (performance.now() - (performance.timing.connectEnd - performance.timing.navigationStart)) > 0\n ) {\n return performance;\n }\n });\n}\n\nexport function enablePerformance() : boolean {\n return Boolean(getPerformance());\n}\n\nexport function getPageRenderTime() : ZalgoPromise {\n return waitForDocumentReady().then(() => {\n const performance = getPerformance();\n\n if (!performance) {\n return;\n }\n \n const timing = performance.timing;\n\n if (timing.connectEnd && timing.domInteractive) {\n return timing.domInteractive - timing.connectEnd;\n }\n });\n}\n\nexport function htmlEncode(html : string = '') : string {\n return html.toString()\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n}\n\nexport function isBrowser() : boolean {\n return (typeof window !== 'undefined');\n}\n\nexport function querySelectorAll(selector : string, doc : HTMLElement = window.document) : $ReadOnlyArray {\n return Array.prototype.slice.call(doc.querySelectorAll(selector));\n}\n\nexport function onClick(element : HTMLElement, handler : (Event) => void) {\n element.addEventListener('touchstart', noop);\n element.addEventListener('click', handler);\n element.addEventListener('keypress', (event : Event) => {\n // $FlowFixMe\n if (event.keyCode === KEY_CODES.ENTER || event.keyCode === KEY_CODES.SPACE) { // eslint-disable-line unicorn/prefer-event-key\n return handler(event);\n }\n });\n}\n\nexport function getScript({ host = window.location.host, path } : {| host? : string, path : string |}) : ?HTMLScriptElement {\n return inlineMemoize(getScript, () : ?HTMLScriptElement => {\n\n const url = `${ host }${ path }`;\n const scripts = Array.prototype.slice.call(document.getElementsByTagName('script'));\n\n for (const script of scripts) {\n if (!script.src) {\n continue;\n }\n\n const src = script.src.replace(/^https?:\\/\\//, '').split('?')[0];\n\n if (src === url) {\n return script;\n }\n }\n }, [ path ]);\n}\n\nexport function isLocalStorageEnabled() : boolean {\n return inlineMemoize(isLocalStorageEnabled, () => {\n try {\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (window.localStorage) {\n const value = Math.random().toString();\n window.localStorage.setItem('__test__localStorage__', value);\n const result = window.localStorage.getItem('__test__localStorage__');\n window.localStorage.removeItem('__test__localStorage__');\n if (value === result) {\n return true;\n }\n }\n } catch (err) {\n // pass\n }\n return false;\n });\n}\n\nexport function getBrowserLocales() : $ReadOnlyArray<{| country? : string, lang : string |}> {\n const nav = window.navigator; // eslint-disable-line compat/compat\n\n const locales = nav.languages\n ? [ ...nav.languages ]\n : [];\n\n if (nav.language) {\n locales.push(nav.language);\n }\n\n if (nav.userLanguage) {\n locales.push(nav.userLanguage);\n }\n\n return locales.map(locale => {\n\n if (locale && locale.match(/^[a-z]{2}[-_][A-Z]{2}$/)) {\n const [ lang, country ] = locale.split(/[-_]/);\n return { country, lang };\n }\n\n if (locale && locale.match(/^[a-z]{2}$/)) {\n return { lang: locale };\n }\n\n return null;\n\n }).filter(Boolean);\n}\n\n\nexport function appendChild(container : HTMLElement, child : HTMLElement | Text) {\n container.appendChild(child);\n}\n\nexport function isElement(element : mixed) : boolean {\n\n if (element instanceof window.Element) {\n return true;\n }\n\n if (element !== null && typeof element === 'object' && element.nodeType === 1 && typeof element.style === 'object' && typeof element.ownerDocument === 'object') {\n return true;\n }\n\n return false;\n}\n\nexport function getElementSafe(id : ElementRefType, doc : Document | HTMLElement = document) : ?HTMLElement {\n\n if (isElement(id)) {\n // $FlowFixMe\n return id;\n }\n\n if (typeof id === 'string') {\n return doc.querySelector(id);\n }\n}\n\nexport function getElement(id : ElementRefType, doc : Document | HTMLElement = document) : HTMLElement {\n\n const element = getElementSafe(id, doc);\n\n if (element) {\n return element;\n }\n\n throw new Error(`Can not find element: ${ stringify(id) }`);\n}\n\nexport function elementReady(id : ElementRefType) : ZalgoPromise {\n return new ZalgoPromise((resolve, reject) => {\n\n const name = stringify(id);\n let el = getElementSafe(id);\n\n if (el) {\n return resolve(el);\n }\n\n if (isDocumentReady()) {\n return reject(new Error(`Document is ready and element ${ name } does not exist`));\n }\n\n const interval = setInterval(() => {\n\n el = getElementSafe(id);\n\n if (el) {\n clearInterval(interval);\n return resolve(el);\n }\n\n if (isDocumentReady()) {\n clearInterval(interval);\n return reject(new Error(`Document is ready and element ${ name } does not exist`));\n }\n }, 10);\n });\n}\n\nexport function PopupOpenError(message : string) {\n this.message = message;\n}\n\nPopupOpenError.prototype = Object.create(Error.prototype);\n\ntype PopupOptions = {|\n name? : string,\n width? : number,\n height? : number,\n top? : number,\n left? : number,\n status? : 0 | 1,\n resizable? : 0 | 1,\n toolbar? : 0 | 1,\n menubar? : 0 | 1,\n scrollbars? : 0 | 1\n|};\n\nexport function popup(url : string, options? : PopupOptions) : CrossDomainWindowType {\n\n // $FlowFixMe\n options = options || {};\n\n const { width, height } = options;\n\n let top = 0;\n let left = 0;\n\n if (width) {\n if (window.outerWidth) {\n left = Math.round((window.outerWidth - width) / 2) + window.screenX;\n } else if (window.screen.width) {\n left = Math.round((window.screen.width - width) / 2);\n }\n }\n\n if (height) {\n if (window.outerHeight) {\n top = Math.round((window.outerHeight - height) / 2) + window.screenY;\n } else if (window.screen.height) {\n top = Math.round((window.screen.height - height) / 2);\n }\n }\n\n if (width && height) {\n // $FlowFixMe\n options = {\n top,\n left,\n width,\n height,\n status: 1,\n toolbar: 0,\n menubar: 0,\n resizable: 1,\n scrollbars: 1,\n ...options\n };\n }\n\n const name = options.name || '';\n delete options.name;\n\n // eslint-disable-next-line array-callback-return\n const params = Object.keys(options).map(key => {\n // $FlowFixMe\n if (options[key] !== null && options[key] !== undefined) {\n return `${ key }=${ stringify(options[key]) }`;\n }\n }).filter(Boolean).join(',');\n\n let win;\n\n try {\n win = window.open(url, name, params, true);\n } catch (err) {\n throw new PopupOpenError(`Can not open popup window - ${ err.stack || err.message }`);\n }\n\n if (isWindowClosed(win)) {\n const err = new PopupOpenError(`Can not open popup window - blocked`);\n throw err;\n }\n\n window.addEventListener('unload', () => win.close());\n\n return win;\n}\n\n\nexport function writeToWindow(win : SameDomainWindowType, html : string) {\n try {\n win.document.open();\n win.document.write(html);\n win.document.close();\n } catch (err) {\n try {\n win.location = `javascript: document.open(); document.write(${ JSON.stringify(html) }); document.close();`;\n } catch (err2) {\n // pass\n }\n }\n}\n\nexport function writeElementToWindow(win : SameDomainWindowType, el : HTMLElement) {\n\n const tag = el.tagName.toLowerCase();\n\n if (tag !== 'html') {\n throw new Error(`Expected element to be html, got ${ tag }`);\n }\n\n const documentElement = win.document.documentElement;\n\n for (const child of arrayFrom(documentElement.children)) {\n documentElement.removeChild(child);\n }\n\n for (const child of arrayFrom(el.children)) {\n documentElement.appendChild(child);\n }\n}\n\nexport function setStyle(el : HTMLElement, styleText : string, doc : Document = window.document) {\n // $FlowFixMe\n if (el.styleSheet) {\n // $FlowFixMe\n el.styleSheet.cssText = styleText;\n } else {\n el.appendChild(doc.createTextNode(styleText));\n }\n}\n\nexport type ElementOptionsType = {|\n style? : { [ string ] : string },\n id? : string,\n class? : ?$ReadOnlyArray,\n attributes? : { [ string ] : string },\n styleSheet? : ?string,\n html? : ?string\n|};\n\nlet awaitFrameLoadPromises : WeakMap>;\n\nexport function awaitFrameLoad(frame : HTMLIFrameElement) : ZalgoPromise {\n awaitFrameLoadPromises = awaitFrameLoadPromises || new WeakMap();\n\n if (awaitFrameLoadPromises.has(frame)) {\n const promise = awaitFrameLoadPromises.get(frame);\n if (promise) {\n return promise;\n }\n }\n\n const promise = new ZalgoPromise((resolve, reject) => {\n frame.addEventListener('load', () => {\n linkFrameWindow(frame);\n resolve(frame);\n });\n\n frame.addEventListener('error', (err : Event) => {\n if (frame.contentWindow) {\n resolve(frame);\n } else {\n reject(err);\n }\n });\n });\n\n awaitFrameLoadPromises.set(frame, promise);\n\n return promise;\n}\n\nexport function awaitFrameWindow(frame : HTMLIFrameElement) : ZalgoPromise {\n return awaitFrameLoad(frame).then(loadedFrame => {\n\n if (!loadedFrame.contentWindow) {\n throw new Error(`Could not find window in iframe`);\n }\n\n return loadedFrame.contentWindow;\n });\n}\n\nconst getDefaultCreateElementOptions = () : ElementOptionsType => {\n // $FlowFixMe\n return {};\n};\n\nexport function createElement(tag : string = 'div', options : ElementOptionsType = getDefaultCreateElementOptions(), container : ?HTMLElement) : HTMLElement {\n\n tag = tag.toLowerCase();\n const element = document.createElement(tag);\n\n if (options.style) {\n extend(element.style, options.style);\n }\n\n if (options.class) {\n element.className = options.class.join(' ');\n }\n\n if (options.id) {\n element.setAttribute('id', options.id);\n }\n\n if (options.attributes) {\n for (const key of Object.keys(options.attributes)) {\n element.setAttribute(key, options.attributes[key]);\n }\n }\n\n if (options.styleSheet) {\n setStyle(element, options.styleSheet);\n }\n\n if (container) {\n appendChild(container, element);\n }\n\n if (options.html) {\n if (tag === 'iframe') {\n // $FlowFixMe\n if (!container || !element.contentWindow) {\n throw new Error(`Iframe html can not be written unless container provided and iframe in DOM`);\n }\n\n // $FlowFixMe\n writeToWindow(element.contentWindow, options.html);\n\n } else {\n element.innerHTML = options.html;\n }\n }\n\n return element;\n}\n\ntype StringMap = {|\n [ string ] : string\n|};\n\nexport type IframeElementOptionsType = {|\n style? : StringMap,\n class? : ?$ReadOnlyArray,\n attributes? : StringMap,\n styleSheet? : ?string,\n html? : ?string,\n url? : ?string\n|};\n\nconst getDefaultIframeOptions = () : IframeElementOptionsType => {\n // $FlowFixMe\n return {};\n};\n\nconst getDefaultStringMap = () : StringMap => {\n // $FlowFixMe\n return {};\n};\n\nexport function iframe(options : IframeElementOptionsType = getDefaultIframeOptions(), container : ?HTMLElement) : HTMLIFrameElement {\n\n const attributes = options.attributes || getDefaultStringMap();\n const style = options.style || getDefaultStringMap();\n\n // $FlowFixMe\n const newAttributes = {\n allowTransparency: 'true',\n ...attributes\n };\n\n // $FlowFixMe\n const newStyle = {\n backgroundColor: 'transparent',\n border: 'none',\n ...style\n };\n\n const frame = createElement('iframe', {\n attributes: newAttributes,\n style: newStyle,\n html: options.html,\n class: options.class\n });\n\n const isIE = window.navigator.userAgent.match(/MSIE|Edge/i); // eslint-disable-line compat/compat\n\n if (!frame.hasAttribute('id')) {\n frame.setAttribute('id', uniqueID());\n }\n\n // $FlowFixMe\n awaitFrameLoad(frame);\n\n if (container) {\n const el = getElement(container);\n el.appendChild(frame);\n }\n\n if (options.url || isIE) {\n frame.setAttribute('src', options.url || 'about:blank');\n }\n\n // $FlowFixMe\n return frame;\n}\n\nexport function addEventListener(obj : HTMLElement, event : string, handler : (event : Event) => void) : CancelableType {\n obj.addEventListener(event, handler);\n return {\n cancel() {\n obj.removeEventListener(event, handler);\n }\n };\n}\n\nexport function bindEvents(element : HTMLElement, eventNames : $ReadOnlyArray, handler : (event : Event) => void) : CancelableType {\n\n handler = once(handler);\n\n for (const eventName of eventNames) {\n element.addEventListener(eventName, handler);\n }\n\n return {\n cancel: once(() => {\n for (const eventName of eventNames) {\n element.removeEventListener(eventName, handler);\n }\n })\n };\n}\n\nconst VENDOR_PREFIXES = [ 'webkit', 'moz', 'ms', 'o' ];\n\nexport function setVendorCSS(element : HTMLElement, name : string, value : string) {\n\n // $FlowFixMe\n element.style[name] = value;\n\n const capitalizedName = capitalizeFirstLetter(name);\n\n for (const prefix of VENDOR_PREFIXES) {\n // $FlowFixMe\n element.style[`${ prefix }${ capitalizedName }`] = value;\n }\n}\n\nconst ANIMATION_START_EVENTS = [ 'animationstart', 'webkitAnimationStart', 'oAnimationStart', 'MSAnimationStart' ];\nconst ANIMATION_END_EVENTS = [ 'animationend', 'webkitAnimationEnd', 'oAnimationEnd', 'MSAnimationEnd' ];\n\nexport function animate(element : ElementRefType, name : string, clean : (Function) => void, timeout : number = 1000) : ZalgoPromise {\n return new ZalgoPromise((resolve, reject) => {\n\n const el = getElement(element);\n\n if (!el) {\n return resolve();\n }\n\n let hasStarted = false;\n\n // eslint-disable-next-line prefer-const\n let startTimeout;\n let endTimeout;\n // eslint-disable-next-line prefer-const\n let startEvent;\n // eslint-disable-next-line prefer-const\n let endEvent;\n\n function cleanUp() {\n clearTimeout(startTimeout);\n clearTimeout(endTimeout);\n startEvent.cancel();\n endEvent.cancel();\n }\n\n startEvent = bindEvents(el, ANIMATION_START_EVENTS, event => {\n\n // $FlowFixMe\n if (event.target !== el || event.animationName !== name) {\n return;\n }\n\n clearTimeout(startTimeout);\n\n event.stopPropagation();\n\n startEvent.cancel();\n hasStarted = true;\n\n endTimeout = setTimeout(() => {\n cleanUp();\n resolve();\n }, timeout);\n });\n\n endEvent = bindEvents(el, ANIMATION_END_EVENTS, event => {\n\n // $FlowFixMe\n if (event.target !== el || event.animationName !== name) {\n return;\n }\n\n cleanUp();\n\n // $FlowFixMe\n if (typeof event.animationName === 'string' && event.animationName !== name) {\n return reject(`Expected animation name to be ${ name }, found ${ event.animationName }`);\n }\n\n return resolve();\n });\n\n setVendorCSS(el, 'animationName', name);\n\n startTimeout = setTimeout(() => {\n if (!hasStarted) {\n cleanUp();\n return resolve();\n }\n }, 200);\n\n if (clean) {\n clean(cleanUp);\n }\n });\n}\n\nexport function makeElementVisible(element : HTMLElement) {\n element.style.setProperty('visibility', '');\n}\n\nexport function makeElementInvisible(element : HTMLElement) {\n element.style.setProperty('visibility', 'hidden', 'important');\n}\n\n\nexport function showElement(element : HTMLElement) {\n element.style.setProperty('display', '');\n}\n\nexport function hideElement(element : HTMLElement) {\n element.style.setProperty('display', 'none', 'important');\n}\n\nexport function destroyElement(element : HTMLElement) {\n if (element && element.parentNode) {\n element.parentNode.removeChild(element);\n }\n}\n\nexport function showAndAnimate(element : HTMLElement, name : string, clean : (Function) => void) : ZalgoPromise {\n const animation = animate(element, name, clean);\n showElement(element);\n return animation;\n}\n\nexport function animateAndHide(element : HTMLElement, name : string, clean : (Function) => void) : ZalgoPromise {\n return animate(element, name, clean).then(() => {\n hideElement(element);\n });\n}\n\nexport function addClass(element : HTMLElement, name : string) {\n element.classList.add(name);\n}\n\nexport function removeClass(element : HTMLElement, name : string) {\n element.classList.remove(name);\n}\n\nexport function isElementClosed(el : HTMLElement) : boolean {\n if (!el || !el.parentNode) {\n return true;\n }\n return false;\n}\n\nexport function watchElementForClose(element : HTMLElement, handler : () => mixed) : CancelableType {\n handler = once(handler);\n\n let interval;\n\n if (isElementClosed(element)) {\n handler();\n } else {\n interval = safeInterval(() => {\n if (isElementClosed(element)) {\n interval.cancel();\n handler();\n }\n }, 50);\n }\n\n return {\n cancel() {\n if (interval) {\n interval.cancel();\n }\n }\n };\n}\n\nexport function fixScripts(el : HTMLElement, doc : Document = window.document) {\n for (const script of querySelectorAll('script', el)) {\n const parentNode = script.parentNode;\n\n if (!parentNode) {\n continue;\n }\n\n const newScript = doc.createElement('script');\n newScript.text = script.textContent;\n parentNode.replaceChild(newScript, script);\n }\n}\n\ntype OnResizeOptions = {|\n width? : boolean,\n height? : boolean,\n interval? : number,\n win? : SameDomainWindowType\n|};\n\nexport function onResize(el : HTMLElement, handler : ({| width : number, height : number |}) => void, { width = true, height = true, interval = 100, win = window } : OnResizeOptions = {}) : {| cancel : () => void |} {\n let currentWidth = el.offsetWidth;\n let currentHeight = el.offsetHeight;\n\n handler({ width: currentWidth, height: currentHeight });\n\n const check = () => {\n const newWidth = el.offsetWidth;\n const newHeight = el.offsetHeight;\n\n if ((width && newWidth !== currentWidth) || (height && newHeight !== currentHeight)) {\n handler({ width: newWidth, height: newHeight });\n }\n\n currentWidth = newWidth;\n currentHeight = newHeight;\n };\n\n let observer;\n let timeout;\n\n win.addEventListener('resize', check);\n \n if (typeof win.ResizeObserver !== 'undefined') {\n observer = new win.ResizeObserver(check);\n observer.observe(el);\n timeout = safeInterval(check, interval * 10);\n\n } else if (typeof win.MutationObserver !== 'undefined') {\n observer = new win.MutationObserver(check);\n observer.observe(el, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: false\n });\n timeout = safeInterval(check, interval * 10);\n } else {\n timeout = safeInterval(check, interval);\n }\n\n return {\n cancel: () => {\n observer.disconnect();\n window.removeEventListener('resize', check);\n timeout.cancel();\n }\n };\n}\n\nexport function getResourceLoadTime(url : string) : ?number {\n const performance = getPerformance();\n\n if (!performance) {\n return;\n }\n\n if (typeof performance.getEntries !== 'function') {\n return;\n }\n\n const entries = performance.getEntries();\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n\n if (entry && entry.name && entry.name.indexOf(url) === 0 && typeof entry.duration === 'number') {\n return Math.floor(entry.duration);\n }\n }\n}\n\nexport function isShadowElement(element : Node) : boolean {\n while (element.parentNode) {\n element = element.parentNode;\n }\n\n return element.toString() === '[object ShadowRoot]';\n}\n\nexport function getShadowRoot(element : Node) : ?Node {\n while (element.parentNode) {\n element = element.parentNode;\n }\n\n if (isShadowElement(element)) {\n return element;\n }\n}\n\nexport function getShadowHost(element : Node) : ?HTMLElement {\n const shadowRoot = getShadowRoot(element);\n\n // $FlowFixMe\n if (shadowRoot.host) {\n // $FlowFixMe\n return shadowRoot.host;\n }\n}\n\nexport function insertShadowSlot(element : HTMLElement) : HTMLElement {\n const shadowHost = getShadowHost(element);\n\n if (!shadowHost) {\n throw new Error(`Element is not in shadow dom`);\n }\n\n if (isShadowElement(shadowHost)) {\n throw new Error(`Host element is also in shadow dom`);\n }\n\n const slotName = `shadow-slot-${ uniqueID() }`;\n\n const slot = document.createElement('slot');\n slot.setAttribute('name', slotName);\n element.appendChild(slot);\n \n const slotProvider = document.createElement('div');\n slotProvider.setAttribute('slot', slotName);\n shadowHost.appendChild(slotProvider);\n\n return slotProvider;\n}\n\nexport function preventClickFocus(el : HTMLElement) {\n const onFocus = (event : Event) => {\n el.removeEventListener('focus', onFocus);\n event.preventDefault();\n el.blur();\n return false;\n };\n\n el.addEventListener('mousedown', () => {\n el.addEventListener('focus', onFocus);\n setTimeout(() => {\n el.removeEventListener('focus', onFocus);\n }, 1);\n });\n}\n","/* @flow */\n\nexport function isPerc(str : string) : boolean {\n return typeof str === 'string' && (/^[0-9]+%$/).test(str);\n}\n\nexport function isPx(str : string) : boolean {\n return typeof str === 'string' && (/^[0-9]+px$/).test(str);\n}\n\nexport function toNum(val : string | number) : number {\n\n if (typeof val === 'number') {\n return val;\n }\n\n const match = val.match(/^([0-9]+)(px|%)$/);\n\n if (!match) {\n throw new Error(`Could not match css value from ${ val }`);\n }\n\n return parseInt(match[1], 10);\n}\n\nexport function toPx(val : number | string) : string {\n return `${ toNum(val) }px`;\n}\n\nexport function toCSS(val : number | string) : string {\n\n if (typeof val === 'number') {\n return toPx(val);\n }\n\n return isPerc(val) ? val : toPx(val);\n}\n\nexport function percOf(num : number, perc : string) : number {\n return parseInt(num * toNum(perc) / 100, 10);\n}\n\nexport function normalizeDimension(dim : string | number, max : number) : number {\n if (typeof dim === 'number') {\n return dim;\n } else if (isPerc(dim)) {\n return percOf(max, dim);\n } else if (isPx(dim)) {\n return toNum(dim);\n } else {\n throw new Error(`Can not normalize dimension: ${ dim }`);\n }\n}\n","/* @flow */\n\nimport { type CrossDomainWindowType, type SameDomainWindowType } from 'cross-domain-utils/src';\nimport { WeakMap } from 'cross-domain-safe-weakmap/src';\nimport { getOrSet } from 'belter/src';\n\nexport function getGlobal(win : SameDomainWindowType = window) : Object {\n if (win !== window) {\n return win[__POST_ROBOT__.__GLOBAL_KEY__];\n }\n const global : Object = win[__POST_ROBOT__.__GLOBAL_KEY__] = win[__POST_ROBOT__.__GLOBAL_KEY__] || {};\n return global;\n}\n\nexport function deleteGlobal() {\n delete window[__POST_ROBOT__.__GLOBAL_KEY__];\n}\n\ntype ObjectGetter = () => Object;\nconst getObj : ObjectGetter = () => ({});\n\ntype GetOrSet = ((string, () => T) => T) & ((string, () => void) => void);\n\ntype GlobalStore = {|\n get : ((string, T) => T) & ((string, void) => T | void),\n set : (string, T) => T,\n has : (string) => boolean,\n del : (string) => void,\n getOrSet : GetOrSet,\n reset : () => void,\n keys : () => $ReadOnlyArray\n|};\n\nexport function globalStore(key? : string = 'store', defStore? : ObjectGetter = getObj) : GlobalStore {\n return getOrSet(getGlobal(), key, () => {\n let store = defStore();\n\n return {\n has: (storeKey) => {\n return store.hasOwnProperty(storeKey);\n },\n get: (storeKey, defVal) => {\n // $FlowFixMe\n return store.hasOwnProperty(storeKey) ? store[storeKey] : defVal;\n },\n set: (storeKey, val) => {\n store[storeKey] = val;\n return val;\n },\n del: (storeKey) => {\n delete store[storeKey];\n },\n getOrSet: (storeKey, getter) => {\n // $FlowFixMe\n return getOrSet(store, storeKey, getter);\n },\n reset: () => {\n store = defStore();\n },\n keys: () => {\n return Object.keys(store);\n }\n };\n });\n}\n\nexport class WildCard {}\n\nexport function getWildcard() : WildCard {\n const global = getGlobal();\n global.WINDOW_WILDCARD = global.WINDOW_WILDCARD || new WildCard();\n return global.WINDOW_WILDCARD;\n}\n\ntype WindowStore = {|\n get : ((CrossDomainWindowType | WildCard, T) => T) & ((CrossDomainWindowType | WildCard, void) => T | void),\n set : (CrossDomainWindowType | WildCard, T) => T,\n has : (CrossDomainWindowType | WildCard) => boolean,\n del : (CrossDomainWindowType | WildCard) => void,\n getOrSet : (CrossDomainWindowType | WildCard, () => T) => T\n|};\n\nexport function windowStore(key? : string = 'store', defStore? : ObjectGetter = getObj) : WindowStore {\n return globalStore('windowStore').getOrSet(key, () => {\n const winStore = new WeakMap();\n\n const getStore = (win : CrossDomainWindowType | WildCard) : ObjectGetter => {\n return winStore.getOrSet(win, defStore);\n };\n \n return {\n has: (win) => {\n const store = getStore(win);\n return store.hasOwnProperty(key);\n },\n get: (win, defVal) => {\n const store = getStore(win);\n // $FlowFixMe\n return store.hasOwnProperty(key) ? store[key] : defVal;\n },\n set: (win, val) => {\n const store = getStore(win);\n store[key] = val;\n return val;\n },\n del: (win) => {\n const store = getStore(win);\n delete store[key];\n },\n getOrSet: (win, getter) => {\n const store = getStore(win);\n return getOrSet(store, key, getter);\n }\n };\n });\n}\n","/* @flow */\n\nimport { getAncestor, type CrossDomainWindowType } from 'cross-domain-utils/src';\nimport { ZalgoPromise } from 'zalgo-promise/src';\nimport { uniqueID } from 'belter/src';\n\nimport { MESSAGE_NAME, WILDCARD } from '../conf';\nimport { windowStore, globalStore } from '../global';\nimport type { OnType, SendType, CancelableType } from '../types';\n\nfunction getInstanceID() : string {\n return globalStore('instance').getOrSet('instanceID', uniqueID);\n}\n\nfunction getHelloPromise(win : CrossDomainWindowType) : ZalgoPromise<{| domain : string |}> {\n const helloPromises = windowStore('helloPromises');\n return helloPromises.getOrSet(win, () => new ZalgoPromise());\n}\n\nfunction resolveHelloPromise(win : CrossDomainWindowType, { domain }) : ZalgoPromise<{| domain : string |}> {\n const helloPromises = windowStore('helloPromises');\n const existingPromise = helloPromises.get(win);\n if (existingPromise) {\n existingPromise.resolve({ domain });\n }\n const newPromise = ZalgoPromise.resolve({ domain });\n helloPromises.set(win, newPromise);\n return newPromise;\n}\n\nfunction listenForHello({ on } : {| on : OnType |}) : CancelableType {\n return on(MESSAGE_NAME.HELLO, { domain: WILDCARD }, ({ source, origin }) => {\n resolveHelloPromise(source, { domain: origin });\n return { instanceID: getInstanceID() };\n });\n}\n\nexport function sayHello(win : CrossDomainWindowType, { send } : {| send : SendType |}) : ZalgoPromise<{| win : CrossDomainWindowType, domain : string, instanceID : string |}> {\n return send(win, MESSAGE_NAME.HELLO, { instanceID: getInstanceID() }, { domain: WILDCARD, timeout: -1 })\n .then(({ origin, data: { instanceID } }) => {\n resolveHelloPromise(win, { domain: origin });\n return { win, domain: origin, instanceID };\n });\n}\n\nexport function getWindowInstanceID(win : CrossDomainWindowType, { send } : {| send : SendType |}) : ZalgoPromise {\n return windowStore('windowInstanceIDPromises').getOrSet(win, () => {\n return sayHello(win, { send }).then(({ instanceID }) => instanceID);\n });\n}\n\nexport function initHello({ on, send } : {| on : OnType, send : SendType |}) : CancelableType {\n return globalStore('builtinListeners').getOrSet('helloListener', () => {\n const listener = listenForHello({ on });\n\n const parent = getAncestor();\n if (parent) {\n sayHello(parent, { send }).catch(err => {\n if (__TEST__ && parent[__POST_ROBOT__.__GLOBAL_KEY__]) {\n throw err;\n }\n });\n }\n\n return listener;\n });\n}\n\nexport function awaitWindowHello(win : CrossDomainWindowType, timeout : number = 5000, name : string = 'Window') : ZalgoPromise<{| domain : string |}> {\n let promise = getHelloPromise(win);\n\n if (timeout !== -1) {\n promise = promise.timeout(timeout, new Error(`${ name } did not load after ${ timeout }ms`));\n }\n\n return promise;\n}\n","/* @flow */\n\nexport const MESSAGE_TYPE = {\n REQUEST: ('postrobot_message_request' : 'postrobot_message_request'),\n RESPONSE: ('postrobot_message_response' : 'postrobot_message_response'),\n ACK: ('postrobot_message_ack' : 'postrobot_message_ack')\n};\n\nexport const MESSAGE_ACK = {\n SUCCESS: ('success' : 'success'),\n ERROR: ('error' : 'error')\n};\n\nexport const MESSAGE_NAME = {\n METHOD: ('postrobot_method' : 'postrobot_method'),\n HELLO: ('postrobot_hello' : 'postrobot_hello'),\n OPEN_TUNNEL: ('postrobot_open_tunnel' : 'postrobot_open_tunnel')\n};\n\nexport const SEND_STRATEGY = {\n POST_MESSAGE: ('postrobot_post_message' : 'postrobot_post_message'),\n BRIDGE: ('postrobot_bridge' : 'postrobot_bridge'),\n GLOBAL: ('postrobot_global' : 'postrobot_global')\n};\n\nexport const BRIDGE_NAME_PREFIX = '__postrobot_bridge__';\nexport const POSTROBOT_PROXY = '__postrobot_proxy__';\n\nexport const WILDCARD = '*';\n\nexport const SERIALIZATION_TYPE = {\n CROSS_DOMAIN_ZALGO_PROMISE: ('cross_domain_zalgo_promise' : 'cross_domain_zalgo_promise'),\n CROSS_DOMAIN_FUNCTION: ('cross_domain_function' : 'cross_domain_function'),\n CROSS_DOMAIN_WINDOW: ('cross_domain_window' : 'cross_domain_window')\n};\n","/* @flow */\n\nimport { type CrossDomainWindowType } from 'cross-domain-utils/src';\n\nimport { windowStore } from '../global';\n\nexport function markWindowKnown(win : CrossDomainWindowType) {\n const knownWindows = windowStore('knownWindows');\n knownWindows.set(win, true);\n}\n\nexport function isWindowKnown(win : CrossDomainWindowType) : boolean {\n const knownWindows = windowStore('knownWindows');\n return knownWindows.get(win, false);\n}\n","/* @flow */\n\nimport { TYPE } from './constants';\nimport type { CustomSerializedType } from './types';\n\nexport function isSerializedType(item : mixed) : boolean {\n return (typeof item === 'object' && item !== null && typeof item.__type__ === 'string');\n}\n\nexport function determineType(val : mixed) : $Values | void {\n if (typeof val === 'undefined') {\n return TYPE.UNDEFINED;\n }\n\n if (val === null) {\n return TYPE.NULL;\n }\n\n if (Array.isArray(val)) {\n return TYPE.ARRAY;\n }\n\n if (typeof val === 'function') {\n return TYPE.FUNCTION;\n }\n\n if (typeof val === 'object') {\n\n if (val instanceof Error) {\n return TYPE.ERROR;\n }\n\n if (typeof val.then === 'function') {\n return TYPE.PROMISE;\n }\n\n if (Object.prototype.toString.call(val) === '[object RegExp]') {\n return TYPE.REGEX;\n }\n\n if (Object.prototype.toString.call(val) === '[object Date]') {\n return TYPE.DATE;\n }\n\n return TYPE.OBJECT;\n }\n\n if (typeof val === 'string') {\n return TYPE.STRING;\n }\n\n if (typeof val === 'number') {\n return TYPE.NUMBER;\n }\n\n if (typeof val === 'boolean') {\n return TYPE.BOOLEAN;\n }\n}\n\nexport function serializeType(type : T, val : V) : CustomSerializedType {\n return {\n __type__: type,\n __val__: val\n };\n}\n","/* @flow */\n\nexport const TYPE = {\n FUNCTION: ('function' : 'function'),\n ERROR: ('error' : 'error'),\n PROMISE: ('promise' : 'promise'),\n REGEX: ('regex' : 'regex'),\n DATE: ('date' : 'date'),\n ARRAY: ('array' : 'array'),\n OBJECT: ('object' : 'object'),\n STRING: ('string' : 'string'),\n NUMBER: ('number' : 'number'),\n BOOLEAN: ('boolean' : 'boolean'),\n NULL: ('null' : 'null'),\n UNDEFINED: ('undefined' : 'undefined')\n};\n","/* @flow */\n\nimport { TYPE } from './constants';\nimport type { Thenable, CustomSerializedType, NativeSerializedType } from './types';\nimport { determineType, isSerializedType } from './common';\nimport {\n serializeFunction,\n serializeError, type SerializedError,\n serializePromise,\n serializeRegex, type SerializedRegex,\n serializeDate, type SerializedDate,\n serializeArray,\n serializeObject,\n serializeString,\n serializeNumber,\n serializeBoolean,\n serializeNull\n} from './serializers';\n\ntype NativeSerializer> = (value : V, key : string) => NativeSerializedType;\ntype CustomSerializer = (value : V, key : string) => CustomSerializedType;\ntype PrimitiveSerializer = (value : V, key : string) => S;\ntype CustomOrPrimitiveSerializer = CustomSerializer | PrimitiveSerializer;\ntype NativeOrCustomOrPrimitiveSerializer = NativeSerializer | CustomOrPrimitiveSerializer;\n\ntype Serializers = {|\n function? : CustomOrPrimitiveSerializer,\n error? : NativeOrCustomOrPrimitiveSerializer,\n promise? : CustomOrPrimitiveSerializer,\n regex? : NativeOrCustomOrPrimitiveSerializer,\n date? : NativeOrCustomOrPrimitiveSerializer,\n array? : CustomOrPrimitiveSerializer<$ReadOnlyArray, typeof TYPE.ARRAY>,\n object? : CustomOrPrimitiveSerializer,\n string? : CustomOrPrimitiveSerializer,\n number? : CustomOrPrimitiveSerializer,\n boolean? : CustomOrPrimitiveSerializer,\n null? : CustomOrPrimitiveSerializer\n|};\n\nconst SERIALIZER : Serializers = {\n [ TYPE.FUNCTION ]: serializeFunction,\n [ TYPE.ERROR ]: serializeError,\n [ TYPE.PROMISE ]: serializePromise,\n [ TYPE.REGEX ]: serializeRegex,\n [ TYPE.DATE ]: serializeDate,\n [ TYPE.ARRAY ]: serializeArray,\n [ TYPE.OBJECT ]: serializeObject,\n [ TYPE.STRING ]: serializeString,\n [ TYPE.NUMBER ]: serializeNumber,\n [ TYPE.BOOLEAN ]: serializeBoolean,\n [ TYPE.NULL ]: serializeNull\n};\n\n// $FlowFixMe\nconst defaultSerializers : Serializers = {};\n\nexport function serialize(obj : T, serializers : Serializers = defaultSerializers) : string {\n\n function replacer(key) : ?mixed {\n const val = this[key];\n\n if (isSerializedType(this)) {\n return val;\n }\n \n const type = determineType(val);\n\n if (!type) {\n return val;\n }\n\n // $FlowFixMe\n const serializer = serializers[type] || SERIALIZER[type];\n\n if (!serializer) {\n return val;\n }\n\n return serializer(val, key);\n }\n\n const result = JSON.stringify(obj, replacer);\n\n if (typeof result === 'undefined') {\n return TYPE.UNDEFINED;\n }\n\n return result;\n}\n","/* @flow */\n\nexport type SerializedFunction = void;\n\nexport function serializeFunction() : SerializedFunction {\n // pass\n}\n\nexport function deserializeFunction() {\n throw new Error(`Function serialization is not implemented; nothing to deserialize`);\n}\n","/* @flow */\n\nimport { serializeType } from '../common';\nimport { TYPE } from '../constants';\nimport type { NativeSerializedType } from '../types';\n\nimport { serializeObject } from './object';\n\nexport type SerializedError = {|\n message : string,\n stack : string,\n code : string | number | void,\n data : mixed\n|};\n\n// $FlowFixMe\nexport function serializeError({ message, stack, code, data } : Error) : NativeSerializedType {\n return serializeType(TYPE.ERROR, { message, stack, code, data });\n}\n\nexport function deserializeError({ message, stack, code, data } : SerializedError) : Error {\n const error = new Error(message);\n // $FlowFixMe\n error.code = code;\n\n if (data) {\n // $FlowFixMe\n error.data = serializeObject(data);\n }\n\n error.stack = `${ stack }\\n\\n${ error.stack }`;\n return error;\n}\n","/* @flow */\n\nexport type SerializedPromise = void;\n\nexport function serializePromise() : SerializedPromise {\n // pass\n}\n\nexport function deserializePromise() {\n throw new Error(`Promise serialization is not implemented; nothing to deserialize`);\n}\n","/* @flow */\n\nimport { serializeType } from '../common';\nimport { TYPE } from '../constants';\nimport type { NativeSerializedType } from '../types';\n\nexport type SerializedRegex = string;\n\nexport function serializeRegex(val : RegExp) : NativeSerializedType {\n return serializeType(TYPE.REGEX, val.source);\n}\n\nexport function deserializeRegex(val : string) : RegExp {\n // eslint-disable-next-line security/detect-non-literal-regexp\n return new RegExp(val);\n}\n","/* @flow */\n\nimport { serializeType } from '../common';\nimport { TYPE } from '../constants';\nimport type { NativeSerializedType } from '../types';\n\nexport type SerializedDate = string;\n\nexport function serializeDate(val : Date) : NativeSerializedType {\n return serializeType(TYPE.DATE, val.toJSON());\n}\n\nexport function deserializeDate(val : string) : Date {\n return new Date(val);\n}\n","/* @flow */\n\nexport type SerializedArray = $ReadOnlyArray;\n\nexport function serializeArray(val : $ReadOnlyArray) : SerializedArray {\n return val;\n}\n\nexport function deserializeArray(val : SerializedArray) : $ReadOnlyArray {\n return val;\n}\n","/* @flow */\n\nexport type SerializedObject = Object;\n\nexport function serializeObject(val : Object) : SerializedObject {\n return val;\n}\n\nexport function deserializeObject(val : SerializedObject) : Object {\n return val;\n}\n","/* @flow */\n\nexport type SerializedString = string;\n\nexport function serializeString(val : string) : SerializedString {\n return val;\n}\n\nexport function deserializeString(val : SerializedString) : string {\n return val;\n}\n","/* @flow */\n\nexport type SerializedNumber = number;\n\nexport function serializeNumber(val : number) : SerializedNumber {\n return val;\n}\n\nexport function deserializeNumber(val : SerializedNumber) : number {\n return val;\n}\n","/* @flow */\n\nexport type SerializedBoolean = boolean;\n\nexport function serializeBoolean(val : boolean) : SerializedBoolean {\n return val;\n}\n\nexport function deserializeBoolean(val : SerializedBoolean) : boolean {\n return val;\n}\n","/* @flow */\n\nexport type SerializedNull = null;\n\nexport function serializeNull(val : null) : SerializedNull {\n return val;\n}\n\nexport function deserializeNull(val : SerializedNull) : null {\n return val;\n}\n","/* @flow */\n\nimport type { Thenable } from './types';\nimport { TYPE } from './constants';\nimport { determineType, isSerializedType } from './common';\nimport {\n deserializeFunction,\n deserializeError, type SerializedError,\n deserializePromise,\n deserializeRegex, type SerializedRegex,\n deserializeDate, type SerializedDate,\n deserializeArray,\n deserializeObject,\n deserializeString,\n deserializeNumber,\n deserializeBoolean,\n deserializeNull\n} from './serializers';\n\ntype Deserializer = (serializedValue : S, key : string) => V;\ntype PrimitiveDeserializer = (serializedValue : S, key : string) => V;\n\ntype Deserializers = {\n function? : Deserializer,\n error? : Deserializer,\n promise? : Deserializer,\n regex? : Deserializer,\n date? : Deserializer,\n array? : PrimitiveDeserializer<$ReadOnlyArray>,\n object? : PrimitiveDeserializer,\n string? : PrimitiveDeserializer,\n number? : PrimitiveDeserializer,\n boolean? : PrimitiveDeserializer,\n null? : PrimitiveDeserializer,\n [string] : Deserializer\n};\n\n// $FlowFixMe\nconst DESERIALIZER : Deserializers = {\n [ TYPE.FUNCTION ]: deserializeFunction,\n [ TYPE.ERROR ]: deserializeError,\n [ TYPE.PROMISE ]: deserializePromise,\n [ TYPE.REGEX ]: deserializeRegex,\n [ TYPE.DATE ]: deserializeDate,\n [ TYPE.ARRAY ]: deserializeArray,\n [ TYPE.OBJECT ]: deserializeObject,\n [ TYPE.STRING ]: deserializeString,\n [ TYPE.NUMBER ]: deserializeNumber,\n [ TYPE.BOOLEAN ]: deserializeBoolean,\n [ TYPE.NULL ]: deserializeNull\n};\n\n// $FlowFixMe\nconst defaultDeserializers : Deserializers = {};\n\nexport function deserialize(str : string, deserializers : Deserializers = defaultDeserializers) : T {\n if (str === TYPE.UNDEFINED) {\n // $FlowFixMe\n return;\n }\n\n function replacer(key, val) : ?mixed {\n if (isSerializedType(this)) {\n return val;\n }\n\n let type;\n let value;\n\n if (isSerializedType(val)) {\n type = val.__type__;\n value = val.__val__;\n } else {\n type = determineType(val);\n value = val;\n }\n\n if (!type) {\n return value;\n }\n\n // $FlowFixMe\n const deserializer = deserializers[type] || DESERIALIZER[type];\n\n if (!deserializer) {\n return value;\n }\n\n return deserializer(value, key);\n }\n\n return JSON.parse(str, replacer);\n}\n","/* @flow */\n\nimport { isSameDomain, isWindowClosed, type CrossDomainWindowType, closeWindow,\n type DomainMatcher, getOpener, WINDOW_TYPE, isWindow, assertSameDomain, getFrameForWindow } from 'cross-domain-utils/src';\nimport { ZalgoPromise } from 'zalgo-promise/src';\nimport { uniqueID, memoizePromise, noop } from 'belter/src';\nimport { serializeType, type CustomSerializedType } from 'universal-serialize/src';\n\nimport { SERIALIZATION_TYPE } from '../conf';\nimport { windowStore, globalStore } from '../global';\nimport { getWindowInstanceID } from '../lib';\nimport { linkWindow } from '../bridge';\nimport type { SendType } from '../types';\n\nfunction cleanupProxyWindows() {\n const idToProxyWindow = globalStore('idToProxyWindow');\n for (const id of idToProxyWindow.keys()) {\n // $FlowFixMe\n if (idToProxyWindow.get(id).shouldClean()) {\n idToProxyWindow.del(id);\n }\n }\n}\n\ntype SerializedWindowType = {|\n id : string,\n getType : () => ZalgoPromise<$Values>,\n close : () => ZalgoPromise,\n focus : () => ZalgoPromise,\n isClosed : () => ZalgoPromise,\n setLocation : (string) => ZalgoPromise,\n getName : () => ZalgoPromise,\n setName : (string) => ZalgoPromise,\n getInstanceID : () => ZalgoPromise\n|};\n\nfunction getSerializedWindow(winPromise : ZalgoPromise, { send, id = uniqueID() } : {| send : SendType, id? : string |}) : SerializedWindowType {\n \n let windowNamePromise = winPromise.then(win => {\n if (isSameDomain(win)) {\n return assertSameDomain(win).name;\n }\n });\n \n const windowTypePromise = winPromise.then(window => {\n if (!isWindowClosed(window)) {\n return getOpener(window) ? WINDOW_TYPE.POPUP : WINDOW_TYPE.IFRAME;\n } else {\n throw new Error(`Window is closed, can not determine type`);\n }\n });\n\n windowNamePromise.catch(noop);\n windowTypePromise.catch(noop);\n\n return {\n id,\n getType: () => {\n return windowTypePromise;\n },\n getInstanceID: memoizePromise(() => winPromise.then(win => getWindowInstanceID(win, { send }))),\n close: () => winPromise.then(closeWindow),\n getName: () => winPromise.then(win => {\n if (isWindowClosed(win)) {\n return;\n }\n\n if (isSameDomain(win)) {\n return assertSameDomain(win).name;\n }\n\n return windowNamePromise;\n }),\n focus: () => winPromise.then(win => {\n win.focus();\n }),\n isClosed: () => winPromise.then(win => {\n return isWindowClosed(win);\n }),\n setLocation: (href) => winPromise.then(win => {\n const domain = `${ window.location.protocol }//${ window.location.host }`;\n\n if (href.indexOf('/') === 0) {\n href = `${ domain }${ href }`;\n } else if (!href.match(/^https?:\\/\\//) && href.indexOf(domain) !== 0) {\n throw new Error(`Expected url to be http or https url, or absolute path, got ${ JSON.stringify(href) }`);\n }\n\n if (isSameDomain(win)) {\n try {\n if (win.location && typeof win.location.replace === 'function') {\n // $FlowFixMe\n win.location.replace(href);\n return;\n }\n } catch (err) {\n // pass\n }\n }\n\n win.location = href;\n }),\n setName: (name) => winPromise.then(win => {\n if (__POST_ROBOT__.__IE_POPUP_SUPPORT__) {\n linkWindow({ win, name });\n }\n\n const sameDomain = isSameDomain(win);\n const frame = getFrameForWindow(win);\n\n if (!sameDomain) {\n throw new Error(`Can not set name for cross-domain window: ${ name }`);\n }\n\n assertSameDomain(win).name = name;\n if (frame) {\n frame.setAttribute('name', name);\n }\n\n windowNamePromise = ZalgoPromise.resolve(name);\n })\n };\n}\n\nexport class ProxyWindow {\n\n id : string\n isProxyWindow : true = true\n serializedWindow : SerializedWindowType\n actualWindow : ?CrossDomainWindowType\n actualWindowPromise : ZalgoPromise\n send : SendType\n name : string\n\n constructor({ send, win, serializedWindow } : {| win? : CrossDomainWindowType, serializedWindow? : SerializedWindowType, send : SendType |}) {\n this.actualWindowPromise = new ZalgoPromise();\n this.serializedWindow = serializedWindow || getSerializedWindow(this.actualWindowPromise, { send });\n \n globalStore('idToProxyWindow').set(this.getID(), this);\n if (win) {\n this.setWindow(win, { send });\n }\n }\n\n getID() : string {\n return this.serializedWindow.id;\n }\n\n getType() : ZalgoPromise<$Values> {\n return this.serializedWindow.getType();\n }\n\n isPopup() : ZalgoPromise {\n return this.getType().then(type => {\n return type === WINDOW_TYPE.POPUP;\n });\n }\n\n setLocation(href : string) : ZalgoPromise {\n return this.serializedWindow.setLocation(href).then(() => this);\n }\n\n getName() : ZalgoPromise {\n return this.serializedWindow.getName();\n }\n\n setName(name : string) : ZalgoPromise {\n return this.serializedWindow.setName(name).then(() => this);\n }\n\n close() : ZalgoPromise {\n return this.serializedWindow.close().then(() => this);\n }\n\n focus() : ZalgoPromise