UNPKG

enlink

Version:

web-portals

2,176 lines 87.5 kB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

/*! *****************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */

var extendStatics = function(d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
    return extendStatics(d, b);
};

function __extends(d, b) {
    if (typeof b !== "function" && b !== null)
        throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

function __generator(thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
}

function __spreadArray(to, from) {
    for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
        to[j] = from[i];
    return to;
}

var ModuleProptey = /** @class */ (function () {
    function ModuleProptey(id, model, application) {
        this.param = {};
        this.events = {
            transformStart: function () { return undefined; },
            transformEnd: function () { return undefined; },
            start: function () { return undefined; },
            load: function () { return undefined; },
            loadError: function () { return undefined; },
            preload: function () { return undefined; },
            destroy: function () { return undefined; }
        };
        this.createTime = Date.now();
        this.transient = false;
        this.shadowView = null;
        this.shadowViewType = null;
        this.status = {
            init: false,
            preload: false,
            prefetch: false,
            prerender: false
        };
        this.config = {
            title: '',
            rel: 'module',
            level: 0,
            source: {},
            prerender: [],
            apply: ['smart-setTimeout', 'link-in-new-window', ['tap-highlight', 'tap-highlight data-appeared']],
            free: true,
            background: 'auto'
        };
        this.resources = {
            script: [],
            image: [],
            worker: [],
            video: [],
            audio: [],
            font: [],
            style: []
        };
        this.elements = {
            container: document.body
        };
        this.id = id;
        this.param = {};
        this.application = application;
        var _a = this.setDefaultConfig(model), config = _a.config, resources = _a.resources, events = _a.events;
        Object.assign(this.config, config);
        Object.assign(this.resources, resources);
        Object.assign(this.events, events);
    }
    ModuleProptey.prototype.setDefaultConfig = function (manifest) {
        var _a, _b, _c;
        if (((_a = manifest.config) === null || _a === void 0 ? void 0 : _a.rel) === 'frameworks') ;
        if ((_b = manifest.config) === null || _b === void 0 ? void 0 : _b.portal) {
            if (!manifest.config.free) {
                console.error('Module.config[free & portal] conflit!');
            }
        }
        if (isNaN((_c = manifest.config) === null || _c === void 0 ? void 0 : _c.level)) {
            manifest.config.level = 0;
        }
        if (manifest.config.level > 10000) {
            console.error('Module.confi.level <= 9999!');
        }
        return manifest;
    };
    return ModuleProptey;
}());

var ModuleState = /** @class */ (function (_super) {
    __extends(ModuleState, _super);
    function ModuleState(id, model, application) {
        return _super.call(this, id, model, application) || this;
    }
    Object.defineProperty(ModuleState.prototype, "sameOrigin", {
        get: function () {
            if (!this.uri)
                return true;
            var link = document.createElement('a');
            link.href = this.uri;
            var isSameOrigin = link.host === location.host;
            return isSameOrigin;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModuleState.prototype, "level", {
        get: function () {
            var _a;
            var level = this.config.level || (((_a = this.application.activeModule) === null || _a === void 0 ? void 0 : _a.config.level) || 1) + 1;
            var baseLevel = this.config.free ? 20000 : 10000;
            return baseLevel + level;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModuleState.prototype, "rel", {
        get: function () {
            if (this.id === 'system')
                return 'system';
            if (this.id === 'frameworks')
                return 'frameworks';
            return this.config.rel || 'module';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModuleState.prototype, "uri", {
        get: function () {
            var _a, _b;
            return ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.source) === null || _b === void 0 ? void 0 : _b.src) || '';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModuleState.prototype, "viewType", {
        get: function () {
            var _a;
            if (this.rel !== 'module')
                return 'shadow';
            if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.portal) || !this.uri)
                return 'iframe';
            if (!this.shadowViewType) {
                var type = ('HTMLPortalElement' in window) && this.sameOrigin ? 'portal' : 'iframe';
                this.shadowViewType = type;
            }
            return this.shadowViewType;
        },
        enumerable: false,
        configurable: true
    });
    return ModuleState;
}(ModuleProptey));

var ModuleMount = /** @class */ (function (_super) {
    __extends(ModuleMount, _super);
    function ModuleMount(id, model, application) {
        return _super.call(this, id, model, application) || this;
    }
    ModuleMount.prototype.timeTick = function () {
        if (Date.now() - this.createTime > (this.config.timeout || 3600000)) {
            if (this.shadowView)
                this.destroy();
        }
    };
    ModuleMount.prototype.show = function () {
        if (this.viewType !== 'iframe')
            return;
        var sandbox = this.shadowView;
        var contentWindow = sandbox === null || sandbox === void 0 ? void 0 : sandbox.contentWindow;
        if (contentWindow) {
            contentWindow.window.postMessage('module-visible', '*');
            if (this.sameOrigin) {
                contentWindow.window['moduleVisibilityState'] = 'visible';
            }
        }
    };
    ModuleMount.prototype.hide = function () {
        var _a;
        if (this.viewType !== 'iframe')
            return;
        var sandbox = this.shadowView;
        var contentWindow = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.contentWindow) === null || _a === void 0 ? void 0 : _a.window;
        if (contentWindow) {
            contentWindow.postMessage('module-hidden', '*');
            if (this.sameOrigin) {
                contentWindow['moduleVisibilityState'] = 'visible';
            }
        }
    };
    ModuleMount.prototype.destroy = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            var _a, _b, _c;
            if (_this.rel !== 'module')
                return reject();
            if (((_a = _this.application.transform) === null || _a === void 0 ? void 0 : _a.id) === _this.id)
                return reject();
            if (_this.viewType === 'iframe')
                _this.unload().catch(reject);
            (_b = _this.elements.container.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(_this.elements.container);
            _this.status.prefetch = _this.status.preload = _this.status.prerender = false;
            _this.shadowView = null;
            _this.status.init = false;
            (_c = _this.events) === null || _c === void 0 ? void 0 : _c.destroy.bind(_this)();
            resolve();
        });
    };
    ModuleMount.prototype.fate = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            var _a;
            if (_this.rel !== 'module')
                return reject();
            if (_this.config.background === false)
                return resolve();
            if (_this.viewType !== 'iframe')
                return resolve();
            if (_this.sameOrigin === false)
                return resolve();
            var sandbox = _this.shadowView;
            if (!sandbox)
                return;
            try {
                var contentDocumentElement = (_a = sandbox.contentDocument) === null || _a === void 0 ? void 0 : _a.documentElement;
                if (document.getElementsByTagName('video')[0])
                    return resolve();
                if (document.getElementsByTagName('source')[0])
                    return resolve();
                if (document.getElementsByTagName('object')[0])
                    return resolve();
                if (document.getElementsByTagName('audio')[0])
                    return resolve();
                if (document.getElementsByTagName('embed')[0])
                    return resolve();
                if (document.getElementsByTagName('applet')[0])
                    return resolve();
                if (document.getElementsByTagName('iframe')[0])
                    return resolve();
                if (contentDocumentElement) {
                    var counter_1 = {
                        times: 0
                    };
                    _this.mutationObserver = new MutationObserver(function () {
                        counter_1.times++;
                        if (counter_1.times > 1000) {
                            resolve();
                            _this.mutationObserver.disconnect();
                        }
                    });
                    _this.mutationObserver.observe(contentDocumentElement, {
                        subtree: true,
                        attributes: true,
                        childList: true,
                        characterData: true,
                        attributeOldValue: true,
                        characterDataOldValue: true
                    });
                    setTimeout(function () {
                        if (counter_1.times > 10)
                            resolve();
                    }, 3000);
                }
                else {
                    reject();
                }
            }
            catch (error) {
                reject();
            }
        });
    };
    ModuleMount.prototype.unfate = function () {
        var _a;
        (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
    };
    ModuleMount.prototype.unload = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            var _a, _b;
            _this.unfate();
            var sandbox = _this.shadowView;
            if (!sandbox)
                return resolve();
            sandbox.style.display = 'none';
            sandbox.src = 'about:blank';
            try {
                var contentWindow = (_a = sandbox.contentWindow) === null || _a === void 0 ? void 0 : _a.window;
                var contentDocument = sandbox.contentDocument;
                contentWindow === null || contentWindow === void 0 ? void 0 : contentWindow.location.reload();
                contentDocument === null || contentDocument === void 0 ? void 0 : contentDocument.open();
                contentDocument === null || contentDocument === void 0 ? void 0 : contentDocument.write('');
                contentDocument === null || contentDocument === void 0 ? void 0 : contentDocument.close();
            }
            catch (error) {
                reject();
            }
            (_b = sandbox.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(sandbox);
            resolve();
        });
    };
    return ModuleMount;
}(ModuleState));

var ModulePrefetch = /** @class */ (function (_super) {
    __extends(ModulePrefetch, _super);
    function ModulePrefetch(id, model, application) {
        return _super.call(this, id, model, application) || this;
    }
    ModulePrefetch.prototype.prefetch = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            Promise.all([
                _this.prefetchStatic(_this.resources.script, 'script'),
                _this.prefetchStatic(_this.resources.image, 'image'),
                _this.prefetchStatic(_this.resources.worker, 'worker'),
                _this.prefetchStatic(_this.resources.video, 'video'),
                _this.prefetchStatic(_this.resources.audio, 'audio'),
                _this.prefetchStatic(_this.resources.font, 'font'),
                _this.prefetchStatic(_this.resources.style, 'style')
            ]).then(function () {
                _this.status.prefetch = true;
                resolve(true);
            }).catch(reject);
        });
    };
    ModulePrefetch.prototype.prefetchStatic = function (list, as) {
        var _this = this;
        if (list === void 0) { list = []; }
        if (as === void 0) { as = 'script'; }
        return new Promise(function (resolve, reject) {
            Promise.all([].concat(list).map(function (url) { return _this.beforehandLink(url, 'preload', as); })).then(resolve).catch(reject);
        });
    };
    ModulePrefetch.prototype.beforehandLink = function (url, rel, as) {
        if (rel === void 0) { rel = 'preload'; }
        if (as === void 0) { as = 'worker | video | audio | font | script | style | image | document'; }
        if (!url)
            return Promise.reject();
        return new Promise(function (resolve, reject) {
            var _a;
            var link = document.createElement('link');
            link.rel = rel;
            link.href = url;
            link.as = as;
            link.onload = resolve;
            link.onerror = reject;
            if (!((_a = link.relList) === null || _a === void 0 ? void 0 : _a.supports(rel))) {
                reject();
            }
            document.getElementsByTagName('head')[0].appendChild(link);
        });
    };
    return ModulePrefetch;
}(ModuleMount));

var windowOpen = (function (moduleWindow, application) {
    var realOpen = moduleWindow.open;
    moduleWindow.addEventListener('click', function (event) {
        var path = event['path'] || [];
        var anchor = (function () {
            for (var _i = 0, path_1 = path; _i < path_1.length; _i++) {
                var el = path_1[_i];
                if (el.tagName === 'A')
                    return el;
            }
        })();
        if ((anchor === null || anchor === void 0 ? void 0 : anchor.target) === '_bank') {
            var href_1 = anchor.href;
            var title = anchor.title || '';
            var preset = anchor.getAttribute('preset');
            if (href_1) {
                application.pushWindow(href_1, title, preset).catch(function () {
                    realOpen(href_1);
                });
                event.stopPropagation();
                event.preventDefault();
            }
        }
    });
    moduleWindow.open = function (url, target, features) {
        if (typeof url !== 'string' || target || features) {
            return realOpen(url, target, features);
        }
        if (typeof url === 'string') {
            application.pushWindow(url, '').catch(function () {
                realOpen(url);
            });
        }
        return null;
    };
});

var getTimerHandler = function (handler, moduleWindow) {
    return function () {
        var _args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            _args[_i] = arguments[_i];
        }
        if (moduleWindow['moduleVisibilityState'] === 'visible') {
            if (typeof handler === 'function') {
                handler.apply(void 0, _args);
            }
            else if (typeof handler === 'string') {
                var evalHander = new moduleWindow['Function']("return " + handler);
                evalHander.apply(void 0, _args);
            }
        }
    };
};
var smartSetTimeout = function (moduleWindow) {
    var realSetTimeout = moduleWindow.setTimeout;
    moduleWindow.setInterval = function (handler, timeout) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        var fn = getTimerHandler(handler, moduleWindow);
        var intervalId = realSetTimeout.apply(void 0, __spreadArray([fn, timeout], args));
        return intervalId;
    };
};
var smartSetInterval = function (moduleWindow) {
    var realSetInterval = moduleWindow.setInterval;
    moduleWindow.setInterval = function (handler, timeout) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        var fn = getTimerHandler(handler, moduleWindow);
        var intervalId = realSetInterval.apply(void 0, __spreadArray([fn, timeout], args));
        return intervalId;
    };
};

var tapHighlight = (function (moduleWindow, capture) {
    var touchActive = {
        element: null,
        oldStyle: ''
    };
    var addHighlight = function (event) {
        var captureList = capture ? typeof capture === 'string' ? capture.split(' ') : capture : null;
        var path = event['path'] || event.composedPath() || [];
        path.splice(-3);
        var anchor = (function () {
            var _a, _b, _c;
            for (var _i = 0, path_1 = path; _i < path_1.length; _i++) {
                var el = path_1[_i];
                if (!((_a = el.children) === null || _a === void 0 ? void 0 : _a.length))
                    continue;
                if (el.tagName === 'A')
                    return el;
                if (captureList) {
                    for (var _d = 0, captureList_1 = captureList; _d < captureList_1.length; _d++) {
                        var attr = captureList_1[_d];
                        if (el === null || el === void 0 ? void 0 : el.getAttribute(attr))
                            return el;
                    }
                }
            }
            return (((_c = (_b = path[0]) === null || _b === void 0 ? void 0 : _b.children) === null || _c === void 0 ? void 0 : _c.length) ? path[0] : path[1]) || event.target;
        })();
        if (!anchor)
            return;
        touchActive.element = anchor;
        touchActive.oldStyle = anchor.style.filter;
        setTimeout(function () {
            if (touchActive.element === anchor)
                anchor.style.filter = touchActive.oldStyle + ' brightness(.8)';
            var continueCheck = function () {
                setTimeout(function () {
                    if (touchActive.element !== anchor) {
                        anchor.style.filter = touchActive.oldStyle;
                    }
                    else {
                        continueCheck();
                    }
                }, 600);
            };
            continueCheck();
        }, 60);
    };
    var cancelHighlight = function () {
        var _a, _b;
        if ((_b = (_a = touchActive.element) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.filter) {
            touchActive.element.style.filter = touchActive.oldStyle;
        }
        touchActive.element = null;
        touchActive.oldStyle = '';
    };
    var delayCancelHighlight = function () {
        setTimeout(function () {
            cancelHighlight();
        }, 600);
    };
    moduleWindow.document.addEventListener('touchstart', addHighlight);
    moduleWindow.addEventListener('touchstart', addHighlight);
    moduleWindow.addEventListener('touchmove', cancelHighlight);
    moduleWindow.addEventListener('touchcancel', cancelHighlight);
    moduleWindow.addEventListener('touchend', delayCancelHighlight);
});

var inject = (function (moduleWindow, config, application) {
    var apply = config.apply || [];
    if (Array.isArray(apply)) {
        for (var _i = 0, apply_1 = apply; _i < apply_1.length; _i++) {
            var item = apply_1[_i];
            switch (item) {
                case 'link-in-new-window':
                    windowOpen(moduleWindow, application);
                    break;
                case 'smart-setTimeout':
                    smartSetTimeout(moduleWindow);
                    break;
                case 'smart-setInterval':
                    smartSetInterval(moduleWindow);
                    break;
                case 'tap-highlight':
                    tapHighlight(moduleWindow);
                    break;
                default:
                    if (Array.isArray(item)) {
                        switch (item[0]) {
                            case 'tap-highlight':
                                tapHighlight(moduleWindow, item[1]);
                                break;
                        }
                    }
                    break;
            }
        }
    }
    if (typeof config.inject === 'function') {
        config.inject(moduleWindow, config, application);
    }
});

var ModuleView = /** @class */ (function (_super) {
    __extends(ModuleView, _super);
    function ModuleView(id, model, application) {
        return _super.call(this, id, model, application) || this;
    }
    ModuleView.prototype.rigesterElement = function (name, element) {
        this.elements[name] = element;
        if (name === 'container' && element) {
            this.status.init = true;
        }
    };
    ModuleView.prototype.createSandbox = function (uri, config) {
        var sandbox = document.createElement('iframe');
        if (config !== undefined)
            sandbox.setAttribute('sandbox', config);
        if (uri)
            sandbox.src = uri;
        return sandbox;
    };
    ModuleView.prototype.writeSandbox = function (sandbox, container) {
        var _a, _b;
        sandbox.src = 'about:blank';
        sandbox.setAttribute('seamless', 'seamless');
        container.appendChild(sandbox);
        var contentDocument = sandbox.contentDocument;
        var contentWindow = sandbox.contentWindow;
        if (contentWindow && contentDocument) {
            contentDocument.open();
            contentDocument.write(((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.source) === null || _b === void 0 ? void 0 : _b.html) || '<head><meta charset="utf-8"></head>');
            contentDocument.close();
            inject(contentWindow === null || contentWindow === void 0 ? void 0 : contentWindow.window, this.config, this.application);
        }
    };
    ModuleView.prototype.createShadowbox = function (render) {
        var shadowbox = document.createElement('div');
        var shadowboxInner = document.createElement('div');
        shadowbox === null || shadowbox === void 0 ? void 0 : shadowbox.attachShadow({ mode: 'open' });
        var shadowRoot = shadowbox.shadowRoot ? shadowbox.shadowRoot : shadowbox;
        shadowRoot.appendChild(shadowboxInner);
        render(shadowboxInner);
        this.elements.container.appendChild(shadowbox);
        return shadowbox;
    };
    ModuleView.prototype.createPortals = function (uri) {
        var portal = document.createElement('portal');
        portal.src = uri;
        return portal;
    };
    ModuleView.prototype.createShadowView = function () {
        if (this.shadowView)
            return this.shadowView;
        if (this.config.render) {
            return this.shadowView = this.createShadowbox(this.config.render);
        }
        if (this.rel !== 'module')
            return;
        return this.shadowView = this.viewType === 'portal' ? this.createPortals(this.uri) : this.createSandbox(this.uri, this.config.sandbox);
    };
    ModuleView.prototype.loadShadowView = function () {
        var container = this.elements.container;
        var shadowView = this.shadowView;
        if (!shadowView)
            return;
        switch (this.viewType) {
            case 'portal':
                container.appendChild(shadowView);
                break;
            case 'iframe':
            default:
                if (this.uri) {
                    container.appendChild(shadowView);
                    var contentWindow = shadowView.contentWindow;
                    if (contentWindow && this.sameOrigin) {
                        inject(contentWindow === null || contentWindow === void 0 ? void 0 : contentWindow.window, this.config, this.application);
                        contentWindow === null || contentWindow === void 0 ? void 0 : contentWindow.window.postMessage('container-ready', '*');
                    }
                }
                else {
                    this.writeSandbox(shadowView, container);
                }
                break;
        }
    };
    ModuleView.prototype.create = function (prepare) {
        var _this = this;
        if (prepare === void 0) { prepare = true; }
        this.unfate();
        this.timeTick();
        if (this.status.prerender) {
            return Promise.resolve('prerender');
        }
        return new Promise(function (resolve, reject) {
            _this.createTime = Date.now();
            var shadowView = _this.createShadowView();
            if (!shadowView) {
                return resolve('null');
            }
            if (_this.viewType === 'shadow') {
                return resolve('shadow');
            }
            shadowView.style.cssText = "\n        position: absolute;\n        z-index: 0;\n        width: 100%;\n        height: 100%;\n        border: 0;\n        transform: translate3d(0, 0, 0);\n      ";
            shadowView.onload = function (e) {
                var _a;
                _this.status.prerender = true;
                (_a = _this.events) === null || _a === void 0 ? void 0 : _a.load.bind(_this)();
                resolve(e);
            };
            shadowView.onerror = function (e) {
                var _a;
                (_a = _this.events) === null || _a === void 0 ? void 0 : _a.loadError.bind(_this)();
                reject(e);
            };
            _this.loadShadowView();
            if (prepare === false || _this.config.animation === false) {
                return resolve('instant');
            }
            setTimeout(function () {
                resolve('timeout');
            }, _this.status.preload ? 800 : 200);
        });
    };
    ModuleView.prototype.preload = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            var uri = _this.uri;
            var head = document.head;
            var sandbox = _this.createSandbox('', '');
            sandbox.style.display = 'none';
            sandbox.onload = function (e) {
                var _a;
                _this.status.preload = true;
                head.removeChild(sandbox);
                (_a = _this.events) === null || _a === void 0 ? void 0 : _a.preload.bind(_this)();
                resolve(e);
            };
            sandbox.onerror = function (e) {
                head.removeChild(sandbox);
                reject(e);
            };
            if (uri) {
                sandbox.src = _this.uri;
                head.appendChild(sandbox);
            }
            else {
                _this.writeSandbox(sandbox, head);
            }
        });
    };
    ModuleView.prototype.prerender = function () {
        var _this = this;
        if (this.status.preload || this.status.prerender) {
            return Promise.resolve();
        }
        return new Promise(function (resolve, reject) {
            _this.preload().then(resolve).catch(reject);
            _this.beforehandLink(_this.uri, 'prerender', 'document');
        });
    };
    return ModuleView;
}(ModulePrefetch));

var Module = /** @class */ (function (_super) {
    __extends(Module, _super);
    function Module(id, model, application) {
        var _this = _super.call(this, id, model, application) || this;
        _this.events.start.bind(_this)();
        return _this;
    }
    return Module;
}(ModuleView));

var ease = {
    'in': 'ease-in',
    'out': 'ease-out',
    'in-out': 'ease-in-out',
    'snap': 'cubic-bezier(0, 1, .5, 1)',
    'linear': 'cubic-bezier(0.250, 0.250, 0.750, 0.750)',
    'ease-in-quad': 'cubic-bezier(0.550, 0.085, 0.680, 0.530)',
    'ease-in-cubic': 'cubic-bezier(0.550, 0.055, 0.675, 0.190)',
    'ease-in-quart': 'cubic-bezier(0.895, 0.030, 0.685, 0.220)',
    'ease-in-quint': 'cubic-bezier(0.755, 0.050, 0.855, 0.060)',
    'ease-in-sine': 'cubic-bezier(0.470, 0.000, 0.745, 0.715)',
    'ease-in-expo': 'cubic-bezier(0.950, 0.050, 0.795, 0.035)',
    'ease-in-circ': 'cubic-bezier(0.600, 0.040, 0.980, 0.335)',
    'ease-in-back': 'cubic-bezier(0.600, -0.280, 0.735, 0.045)',
    'ease-out-quad': 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
    'ease-out-cubic': 'cubic-bezier(0.215, 0.610, 0.355, 1.000)',
    'ease-out-quart': 'cubic-bezier(0.165, 0.840, 0.440, 1.000)',
    'ease-out-quint': 'cubic-bezier(0.230, 1.000, 0.320, 1.000)',
    'ease-out-sine': 'cubic-bezier(0.390, 0.575, 0.565, 1.000)',
    'ease-out-expo': 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',
    'ease-out-circ': 'cubic-bezier(0.075, 0.820, 0.165, 1.000)',
    'ease-out-back': 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',
    'ease-in-out-quad': 'cubic-bezier(0.455, 0.030, 0.515, 0.955)',
    'ease-in-out-cubic': 'cubic-bezier(0.645, 0.045, 0.355, 1.000)',
    'ease-in-out-quart': 'cubic-bezier(0.770, 0.000, 0.175, 1.000)',
    'ease-in-out-quint': 'cubic-bezier(0.860, 0.000, 0.070, 1.000)',
    'ease-in-out-sine': 'cubic-bezier(0.445, 0.050, 0.550, 0.950)',
    'ease-in-out-expo': 'cubic-bezier(1.000, 0.000, 0.000, 1.000)',
    'ease-in-out-circ': 'cubic-bezier(0.785, 0.135, 0.150, 0.860)',
    'ease-in-out-back': 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'
};

var EventProvider = /** @class */ (function () {
    function EventProvider() {
        this._events = {};
    }
    EventProvider.prototype.on = function (type, fn) {
        var _this = this;
        var types = type.split(' ');
        types.forEach(function (typ) {
            if (!_this._events[typ]) {
                _this._events[typ] = [fn];
            }
            else {
                _this._events[typ].push(fn);
            }
        });
        return this;
    };
    EventProvider.prototype.one = function (type, fn) {
        var _this = this;
        var once = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            fn.apply(null, args);
            _this.off(type, once);
        };
        var types = type.split(' ');
        types.forEach(function (typ) {
            if (!_this._events[typ]) {
                _this._events[typ] = [once];
            }
            else {
                _this._events[typ].push(once);
            }
        });
        return this;
    };
    EventProvider.prototype.off = function (type, fn) {
        var _this = this;
        var types = type.split(' ');
        types.forEach(function (typ) {
            if (!_this._events[typ])
                return;
            var index = _this._events[typ].indexOf(fn);
            if (index > -1) {
                _this._events[typ].splice(index, 1);
            }
        });
        return this;
    };
    EventProvider.prototype.trigger = function (type) {
        var _this = this;
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        if (!this._events[type])
            return;
        this._events[type].forEach(function (fn) {
            try {
                fn.apply(null, args);
            }
            catch (e) {
                _this.off(type, fn);
                _this.trigger('error', "Error by event[" + type + "]");
            }
        });
        return this;
    };
    return EventProvider;
}());

var rAF = requestAnimationFrame;
var gCS = getComputedStyle;
/* Animate */
var Animate = /** @class */ (function (_super) {
    __extends(Animate, _super);
    function Animate(el) {
        var _this = _super.call(this) || this;
        _this._props = {};
        _this._transforms = {};
        _this._transforming = false;
        _this._proper = [];
        _this._caller = [];
        _this._transitionProps = [];
        _this.translate = _this.to;
        _this.translate3d = _this.to;
        _this.translateX = _this.x;
        _this.translateY = _this.y;
        _this.translateZ = _this.z;
        if (!el)
            return _this;
        _this.el = el;
        _this.el.style.setProperty('transition-duration', '0ms');
        return _this;
    }
    Animate.prototype.transform = function (transform) {
        this.transition('transform');
        var propName = (transform.match(/\w+\b/) || [])[0];
        if (propName)
            this._transforms[propName] = transform;
        return this;
    };
    Animate.prototype.skew = function (x, y) {
        return this.transform('skew(' + x + 'deg, ' + (y || 0) + 'deg)');
    };
    Animate.prototype.skewX = function (n) {
        return this.transform('skewX(' + n + 'deg)');
    };
    Animate.prototype.skewY = function (n) {
        return this.transform('skewY(' + n + 'deg)');
    };
    Animate.prototype.to = function (x, y, z) {
        if (x === void 0) { x = 0; }
        if (y === void 0) { y = 0; }
        if (z === void 0) { z = 0; }
        // 3d set
        this.transform('translate3d(' + (x ? x + 'px' : 0) + ',' + (y ? y + 'px' : 0) + ',' + (z ? z + 'px' : 0) + ')');
        return this;
    };
    Animate.prototype.x = function (n) {
        return this.transform('translateX(' + n + 'px)');
    };
    Animate.prototype.y = function (n) {
        return this.transform('translateY(' + n + 'px)');
    };
    Animate.prototype.z = function (z) {
        return this.transform('translateZ(' + z + 'px)');
    };
    Animate.prototype.scale = function (x, y) {
        return this.transform('scale(' +
            x + ', ' +
            (y || x) +
            ')');
    };
    Animate.prototype.opacity = function (o) {
        this.transition('opacity');
        return this.style('opacity', o);
    };
    Animate.prototype.scaleX = function (n) {
        return this.transform('scaleX(' + n + ')');
    };
    Animate.prototype.matrix = function (m11, m12, m21, m22, m31, m32) {
        return this.transform('matrix(' + [m11, m12, m21, m22, m31, m32].join(',') + ')');
    };
    Animate.prototype.scaleY = function (n) {
        return this.transform('scaleY(' + n + ')');
    };
    Animate.prototype.rotate = function (n) {
        return this.transform('rotate(' + n + 'deg)');
    };
    Animate.prototype.rotateX = function (n) {
        return this.transform('rotateX(' + n + 'deg)');
    };
    Animate.prototype.rotateY = function (n) {
        return this.transform('rotateY(' + n + 'deg)');
    };
    Animate.prototype.rotateZ = function (n) {
        return this.transform('rotateZ(' + n + 'deg)');
    };
    Animate.prototype.rotate3d = function (x, y, z, d) {
        return this.transform('rotate3d(' + x + ', ' + y + ',' + z + ',' + d + 'deg)');
    };
    Animate.prototype.perspective = function (z) {
        var box = this.el.parentElement;
        if (box) {
            box.style.setProperty('transform-style', 'preserve-3d');
            box.style.setProperty('perspective', z + 'px');
        }
        return this;
    };
    Animate.prototype.backface = function (visibility) {
        if (visibility === void 0) { visibility = true; }
        return this.style('backface-visibility', visibility ? 'visible' : 'hidden');
    };
    Animate.prototype.ease = function (s) {
        s = ease[s] || s || 'ease';
        return this.style('transition-timing-function', s);
    };
    Animate.prototype.animate = function (name, props) {
        for (var i in props) {
            if (props.hasOwnProperty(i)) {
                this.style('animation-' + i, props[i]);
            }
        }
        return this.style('animation-name', name);
    };
    Animate.prototype.duration = function (n) {
        n = 'string' === typeof n ?
            parseFloat(n) * 1000 :
            n;
        return this.style('transition-duration', n + 'ms');
    };
    Animate.prototype.getDuration = function () {
        return !!parseFloat(gCS(this.el).transitionDuration);
    };
    Animate.prototype.delay = function (n) {
        n = 'string' === typeof n ?
            parseFloat(n) * 1000 :
            n;
        return this.style('transition-delay', n + 'ms');
    };
    Animate.prototype.origin = function (x, y) {
        var n = 'center';
        if (typeof x === 'object') {
            y = x[1] || 0;
            x = x[0] || 0;
        }
        if (!isNaN(x) && !isNaN(y)) {
            n = x + 'px' + ' ' + y + 'px';
        }
        else if (y) {
            n = x + ' ' + y;
        }
        return this.style('transform-origin', n);
    };
    Animate.prototype.width = function (val) {
        this.transition('width');
        return this.style('width', val === undefined ? '' : val + 'px');
    };
    Animate.prototype.height = function (val) {
        this.transition('height');
        return this.style('height', val === undefined ? '' : val + 'px');
    };
    Animate.prototype.add = function (prop, val) {
        var _this = this;
        return this.on('start', function () {
            var curr = parseInt(_this.current(prop), 10);
            _this.style(prop, curr + val + 'px');
        });
    };
    Animate.prototype.subc = function (prop, val) {
        var _this = this;
        return this.on('start', function () {
            var curr = parseInt(_this.current(prop), 10);
            _this.style(prop, curr - val + 'px');
        });
    };
    Animate.prototype.current = function (prop) {
        return gCS(this.el).getPropertyValue(prop);
    };
    Animate.prototype.transition = function (prop) {
        if (this._transitionProps.indexOf(prop) === -1)
            this._transitionProps.push(prop);
        return this;
    };
    Animate.prototype.filter = function (val) {
        this.style('filter', val);
        this.transition('filter');
        return this;
    };
    Animate.prototype.style = function (prop, val) {
        this._props[prop] = val === undefined ? '' : val;
        return this;
    };
    Animate.prototype._transitionend = function (fn) {
        var _this = this;
        if (!this.getDuration())
            return setTimeout(fn, 0);
        var onec = function (e) {
            if (e.target !== _this.el)
                return false;
            fn(e);
            _this.el.removeEventListener('transitionend', onec, false);
        };
        this.el.addEventListener('transitionend', onec, false);
    };
    Animate.prototype._applyTransform = function () {
        var transform = [];
        if (!this._transforms['translate3d'] && !this._transforms['translateZ']) {
            this._transforms['translateZ'] = 'translateZ(0)';
        }
        for (var i in this._transforms) {
            transform.push(this._transforms[i]);
        }
        if (transform.length) {
            this.style('transform', transform.join(' '));
        }
        return this;
    };
    Animate.prototype.applyProperties = function () {
        var _this = this;
        var prop = this._proper.shift();
        this._transforming = true;
        for (var name_1 in prop) {
            this.el.style.setProperty(name_1, prop[name_1]);
        }
        this._transitionend(function () {
            _this.clear();
            _this.next();
        });
        return this;
    };
    Animate.prototype.next = function () {
        var _this = this;
        if (this._caller.length) {
            var fn = this._caller.shift();
            fn && fn();
        }
        if (this._caller.length === 0) {
            this.init();
        }
        else {
            rAF(function () { _this.applyProperties(); });
        }
    };
    Animate.prototype.clear = function () {
        this._transforms = {};
    };
    Animate.prototype.init = function () {
        if (this.getDuration()) {
            this.el.style.setProperty('transition-duration', '0ms');
        }
        this.clear();
        this._transforming = false;
        return this;
    };
    Animate.prototype.then = function (fn) {
        var _this = this;
        this._applyTransform();
        this.style('transition-property', this._transitionProps.join(', '));
        this._proper.push(this._props);
        this._props = {};
        this._caller.push(function () { return fn && fn.call(_this); });
        return this;
    };
    Animate.prototype.end = function (fn) {
        var _this = this;
        this.then(fn);
        if (this._transforming)
            return this;
        rAF(function () { _this.applyProperties(); });
        return this;
    };
    return Animate;
}(EventProvider));

var flip = (function (e) {
    e.in.duration(0).ease('ease-out-expo').perspective(1000).to(0, 0, 0).opacity(0).rotate3d(0, 1, 0, 90 * e.direction).scale(.92).end(function () {
        e.out.duration(400).ease('ease-out-expo').perspective(1000).rotate3d(0, 1, 0, -90 * e.direction).scale(.92).end(function () {
            e.out.duration(0).opacity(0).end();
            e.in.duration(0).to(0, 0, 0).opacity(1).rotate3d(0, 1, 0, 90 * e.direction).scale(1).end(function () {
                e.in.duration(400).rotate3d(0, 1, 0, 0).end(function () {
                    e.callback(false);
                });
            });
        });
    });
});

var fade = (function (type) {
    return function (e) {
        var inO, outO, inV, outV;
        switch (type) {
            case 0:
                inO = 1;
                outO = 0;
                inV = e.in;
                outV = e.out;
                break;
            case 1:
            default:
                inO = 0;
                outO = 1;
                inV = outV = e.in;
        }
        inV.duration(0).ease('ease-out-expo').to(0, 0, 0).opacity(inO).end(function () {
            outV.duration(300).opacity(outO).end(function () {
                e.callback(false);
            });
        });
    };
});

var zoom = (function (type) {
    return function (e) {
        e.in.origin(type === 0 ? e.attach : e.origin).ease('ease-out-expo').duration(0).to(0, 0, 0).scale(type === 0 ? 2.5 : 0).end(function () {
            e.out.origin(type === 1 ? e.attach : e.origin).ease('ease-in-expo').duration(0).to(0, 0, 0).opacity(1).scale(1).end(function () {
                e.in.duration(767).to(0, 0, 0).scale(1).end();
                e.out.duration(400).opacity(type === 0 ? 0 : 1).scale(type === 0 ? 0 : 2.5).end(function () {
                    e.callback(false);
                });
            });
        });
    };
});

var slide = (function (type) {
    return function (e) {
        var inX = 0;
        var outX = 0;
        var inY = 0;
        var outY = 0;
        switch (type) {
            case 0:
                outY = e.height;
                inY = -outY;
                inX = outX = 0;
                break;
            case 1:
                inX = e.width;
                outX = -inX;
                inY = outY = 0;
                break;
            case 2:
                inY = e.height;
                outY = -inY;
                inX = outX = 0;
                break;
            case 3:
                outX = e.width;
                inX = -outX;
                inY = outY = 0;
                break;
        }
        if (e.reverse) {
            e.in.duration(0).filter('brightness(0.5)').to(inX * .1, inY * .1, 0).end(function () {
                e.out.duration(767).ease('ease-out-expo').to(outX, outY, 0).end();
                e.in.duration(767).filter('brightness(1)').to(0, 0, 0).end(function () {
                    e.callback(false);
                });
            });
        }
        else {
            e.in.duration(0).to(inX, inY, 0).end(function () {
                e.in.duration(767).ease('ease-out-expo').to(0, 0, 0).end(function () {
                    e.callback(false);
                });
                e.out.duration(767).filter('brightness(0.5)').to(outX * .5, outY * .5, 0).end();
            });
        }
    };
});

var effectTypes = {
    flip: flip,
    fade: fade,
    zoom: zoom,
    slide: slide
};

var TransformProptey = /** @class */ (function () {
    function TransformProptey(app) {
        this.id = '';
        this.od = '';
        this.ids = [];
        this.param = '';
        this.history = 0;
        this.animation = false;
        this.switchover = false;
        this.relativeViewport = document.createElement('relative-windows');
        this.absoluteViewport = document.createElement('absolute-windows');
        this.fixedViewport = document.createElement('fixed-windows');
        this.target = this.relativeViewport;
        this.app = app;
        this.setupViewport();
    }
    TransformProptey.prototype.setupViewport = function () {
        var _a, _b;
        this.relativeViewport.id = 'relative-viewport';
        (_a = this.relativeViewport) === null || _a === void 0 ? void 0 : _a.attachShadow({ mode: 'open' });
        this.absoluteViewport.id = 'absolute-viewport';
        (_b = this.absoluteViewport) === null || _b === void 0 ? void 0 : _b.attachShadow({ mode: 'open' });
        this.resetViewport();
        this.fixedViewport.id = 'fixed-viewport';
        this.fixedViewport.style.position = 'fixed';
        this.fixedViewport.style.zIndex = '3';
        this.fixedViewport.style.width = '100%';
        this.fixedViewport.style.height = '0';
        this.fixedViewport.style.contain = 'strict';
        this.fixedViewport.style.overflow = 'visible';
        document.body.appendChild(this.relativeViewport);
        document.body.appendChild(this.absoluteViewport);
        document.body.appendChild(this.fixedViewport);
    };
    TransformProptey.prototype.resetViewport = function () {
        this.relativeViewport.style.cssText = '';
        this.relativeViewport.style.position = 'absolute';
        this.relativeViewport.style.zIndex = '1';
        this.relativeViewport.style.width = this.relativeViewport.style.height = '100%';
        this.relativeViewport.style.overflow = 'hidden';
        this.relativeViewport.style.contain = 'strict';
        this.absoluteViewport.style.cssText = '';
        this.absoluteViewport.style.position = 'absolute';
        this.absoluteViewport.style.zIndex = '2';
        this.absoluteViewport.style.width = this.absoluteViewport.style.height = '100%';
        this.absoluteViewport.style.overflow = 'visible';
        this.absoluteViewport.style.contain = 'strict';
    };
    return TransformProptey;
}());

var TransformAnimation = /** @class */ (function (_super) {
    __extends(TransformAnimation, _super);
    function TransformAnimation(app) {
        return _super.call(this, app) || this;
    }
    TransformAnimation.prototype.getAnimationGroup = function () {
        if (!this.modulu || this.modulu.rel !== 'module')
            return false;
        var animationFunction;
        var animationNames = this[this.history === -1 ? 'modulu' : 'module'].config.animation;
        if (animationNames === true || animationNames === 'inherit') {
            animationNames = this.options.defaultAnimation;
        }
        if (typeof animationNames === 'string') {
            animationFunction = this.getAnimationByName(animationNames);
        }
        else if (typeof (animationNames === null || animationNames === void 0 ? void 0 : animationNames[0]) !== 'function') {
            return animationNames;
        }
        if (typeof (animationFunction === null || animationFunction === void 0 ? void 0 : animationFunction[0]) !== 'function') {
            return false;
        }
        return animationFunction;
    };
    TransformAnimation.prototype.getAnimationOneSide = function (backset) {
        var animationGroup = this.animation;
        if (backset >= 0) {
            switch (typeof animationGroup) {
                case 'function':
                    return animationGroup;
                case 'object':
                    return animationGroup[animationGroup.length === 2 ? backset : 0];
                default:
                    return;
            }
        }
        return;
    };
    TransformAnimation.prototype.getAnimationByName = function (type) {
        switch (type) {
            case 'flip':
                return [effectTypes.flip, effectTypes.flip];
            case 'fade':
                return [effectTypes.fade(1), effectTypes.fade(0)];
            case 'zoom':
                return [effectTypes.zoom(1), effectTypes.zoom(0)];
            case 'slide':
            case 'slideLeft':
            case 'slideleft':
            case 'slide-left':
                return [effectTypes.slide(1), effectTypes.slide(3)];
            case 'slideRight':
            case 'slideright':
            case 'slide-right':
                return [effectTypes.slide(3), effectTypes.slide(1)];
            case 'slideUp':
            case 'slideup':
            case 'slide-up':
                return [effectTypes.slide(0), effectTypes.slide(2)];
            case 'slideDown':
            case 'slidedown':
            case 'slide-down':
                return [effectTypes.slide(2), effectTypes.slide(0)];
            default:
                return;
        }
    };
    return TransformAnimation;
}(TransformProptey));

var TransformHistory = /** @class */ (function (_super) {
    __extends(TransformHistory, _super);
    function TransformHistory(app) {
        var _this = _super.call(this, app) || this;
        _this.backoutCount = 0;
        _this.bindHistoryState();
        return _this;
    }
    TransformHistory.prototype.bindHistoryState = function () {
        addEventListener('popstate', this.popstate.bind(this));
    };
    TransformHistory.prototype.popstate = function (event) {
        this.back(event);
    };
    TransformHistory.prototype.pushState = function (id, title, search, param) {
        if (id === void 0) { id = ''; }
        if (title === void 0) { title = ''; }
        if (search === void 0) { search = location.search; }
        if (param === void 0) { param = ''; }
        id = encodeURIComponent(id);
        history.pushState({
            id: id,
            title: title,
            time: Date.now(),
            search: search,
            historyIndex: history.length
        }, title, location.pathname + search + '#' + id + '/' + param);
    };
    TransformHistory.prototype.replaceState = function (id, title, search, param) {
        if (id === void 0) { id = ''; }
        if (title === void 0) { title = ''; }
        if (search === void 0) { search = location.search; }
        if (param === void 0) { param = ''; }
        id = encodeURIComponent(id);
        history.replaceState({
            id: id,
            title: title,
            time: Date.now(),
            search: search,
            historyIndex: history.length
        }, title, location.pathname + search + '#' + id + '/' + param);
    };
    TransformHistory.prototype.back = function (event) {
        return __awaiter(this, void 0, void 0, function () {
            var options, route, id, search, module;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        options = this.options;
                        route = event.state || this.app.route;
                        id = decodeURIComponent(route.id) || options.index || 'frameworks';
                        search = route.search;
                        return [4 /*yield*/, this.app.get(id)];
                    case 1:
                        module = _a.sent();
                        if (!module)
                            return [2 /*return*/];
                        /**
                         * 如果设置了单向锁,且回退时模块层级为 0 时
                         * 阻止返回,并发送事件
                         */
                        if (this.checkSingleLock()) {
                            this.backoutCount++;
                            this.pushState(id, module.config.title, search);
                            this.app.trigger('exit', {
                                backoutCount: this.backoutCount
                            });
                            return [2 /*return*/];
                        }
                        else {
                            this.backoutCount = 0;
                        }
                        if (options.singleFlow && module.config.level !== 0 && module.config.level >= this.module.config.level) {
                            return [2 /*return*/, history.back()];
                        }
                        this.app.transform.to(id, search, -1);
                        this.app.trigger('back', {
                            id: id,
                            module: module
                        });
                        return [2 /*return*/];
                }
            });
        });
    };
    TransformHistory.prototype.checkSingleLock = function () {
        return this.options.singleLock && this.module.config.level === 0 ? true : false;
    };
    return TransformHistory;
}(TransformAnimation));

var TransformSwitch = /** @class */ (function (_super) {
    __extends(TransformSwitch, _super);
    function TransformSwitch(app) {
        var _this = _super.call(this, app) || this;
        _this.windowSet = [];
        _this.promiseQueue = [];
        _this.promiseParamQueue = [];
        return _this;
    }
    TransformSwitch.prototype.checkSingleLock = function () {
        return this.options.singleLock && this.module.config.level === 0 ? true : false;
    };
    TransformSwitch.prototype.createContainer = function (module) {
        if (module.status.init)
            return;
        var container = document.createElement('module-container');
        container.setAttribute('name', this.id);
        container.setAttribute('type', ['frameworks', 'system'].indexOf(this.id) !== -1 ? this.id : 'module');
        module.rigesterElement('container', container);
        this.resetContainer(module, this.switchover || !this.animation);
        this.getViewport(module).appendChild(container);
    };
    TransformSwitch.prototype.resetContainer = function (module, situ) {
        if (situ === void 0) { situ = false; }
        var config = module.config;
        var container = module.elements.container;
        var systemLevel = ['frameworks', 'system'].includes(module.rel);
        var isDarkModel = this.app.properties.darkTheme;
        container.style.cssText = '';
        if (!systemLevel) {
            container.style.cssText = "\n        position: absolute;\n        z-index: " + ((Number(module.level) || 0) + 1) + ";\n        width: 100%;\n        height: 100%;\n        background: " + (config.color || (isDarkModel ? '#000' : '#fff')) + ";\n        transform: " + (situ ? 'translate3d(0, 0, 0)' : 'translate3d(200%, 200%, 0)') + ";\n        contain: strict;\n      ";
        }
    };
    TransformSwitch.prototype.getViewport = function (module) {
        if (module === void 0) { module = this.module; }
        return module.rel === 'system' ? this.fixedViewport : module.config.free === false ? (this.relativeViewport.shadowRoot || this.relativeViewport) : (this.absoluteViewport.shadowRoot || this.absoluteViewport);
    };
    TransformSwitch.prototype.checkSwitchover = function (modulu, module) {
        if (modulu === void 0) { modulu = this.modulu; }
        if (module === void 0) { module = this.module; }
        return (modulu === null || modulu === void 0 ? void 0 : modulu.rel) === 'module' && module.config.free !== modulu.config.free ? true : false;
    };
    TransformSwitch.prototype.to = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, this.pushPromise(this.next() || this.promise.apply(this, args), args)];
            });
        });
    };
    TransformSwitch.prototype.prev = function () {
        return this.promiseQueue[0];
    };
    TransformSwitch.prototype.next = function () {
        var _this = this;
        var prev = this.prev();
        if (prev) {
            return new Promise(function (resolve, reject) {
                prev.then(function () {
                    if (_this.promiseParamQueue[0]) {
                        _this.promise.apply(_this, _this.promiseParamQueue[0]).then(resolve).catch(reject);
                    }
                });
            });
        }
        return;
    };
    TransformSwitch.prototype.pushPromise = function (promise, param) {
        this.promiseParamQueue.push(param);
        this.promiseQueue.push(promise);
        return promise;
    };
    TransformSwitch.prototype.shiftPromise = function () {
        this.promiseParamQueue.shift();
        this.promiseQueue.shift();
    };
    TransformSwitch.prototype.limit = function (id) {
        var _a, _b;
        var limit = Math.max(((_a = this === null || this === void 0 ? void 0 : this.options) === null || _a === void 0 ? void 0 : _a.limit) || 3, 2);
        var index = this.windowSet.indexOf(id);
        if (this.module.rel !== 'module' || this.module.config.background === true)
            return;
        if (index !== -1)
            this.windowSet.splice(index, 1);
        this.windowSet.push(id);
        if (this.windowSet.length > limit) {
            (_b = this.app.modules[this.windowSet.splice(0, 1)[0]]) === null || _b === void 0 ? void 0 : _b.destroy();
        }
    };
    TransformSwitch.prototype.destroy = function (module) {
        var _this = this;
        if (module.transient && this.history === -1) {
            this.app.del(module).then(function () {
                var index = _this.windowSet.indexOf(module.id);
                _this.windowSet.splice(index, 1);
            });
        }
        else {
            module.fate().then(function () {
                module.destroy().then(function () {
                    var index = _this.windowSet.indexOf(module.id);
                    _this.windowSet.splice(index, 1);
                });
            });
        }
    };
    TransformSwitch.prototype.beforehandDependencies = function (dependencies) {
        var _this = this;
        if (dependencies === void 0) { dependencies = []; }
        var allPromise = [];
        var _loop_1 = function (dep) {
            allPromise.push(new Promise(function (resolve, reject) {
                _this.app.get(dep).then(function (module) {
                    module.prerender().then(resolve).catch(resolve);
                }).catch(reject);
            }));
        };
        for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
            var dep = dependencies_1[_i];
            _loop_1(dep);
        }
        return new Promise(function (resolve, reject) {
            Promise.all(allPromise).then(resolve).catch(reject);
        });
    };
    TransformSwitch.prototype.checkPushState = function () {
        return this.history !== -1 && this.module.viewType !== 'portal';
    };
    TransformSwitch.prototype.promise = function (id, param, history, touches) {
        var _this = this;
        if (param === void 0) { param = location.search; }
        if (history === void 0) { history = 1; }
        return new Promise(function (resolve, reject) {
            var od = _this.od;
            var ids = od ? [id, od] : [id];
            var module = _this.app.modules[id];
            var modulu = _this.app.modules[od];
            var moduli = od ? [module, modulu] : [module];
            if (!module) {
                return _this.app.get(id).then(function () {
                    _this.promise(id, param, history).then(function () {
                        _this.shiftPromise();
                        resolve();
                    }).catch(function () {
                        reject();
                    });
                });
            }
            _this.id = id;
            _this.ids = ids;
            _this.param = param;
            _this.module = module;
            _this.modulu = modulu;
            _this.moduli = moduli;
            _this.history = history;
            _this.touches = touches;
            _this.animation = _this.getAnimationGroup();
            _this.switchover = _this.checkSwitchover();
            _this.target = _this.getViewport();
            _this.createContainer(module);
            _this.start().then(function () {
                _this.hintWillTrans(_this.viewport);
                if (_this.checkPushState() === true) {
                    _this.pushState(id, module.config.title, param);
                }
                module.create(!!_this.animation).then(function () {
                    var _a;
                    document.title = module.config.title;
                    _this.transform().then(function (stillness) {
                        _this.od = id;
                        _this.end(stillness);
                        _this.shiftPromise();
                        _this.limit(_this.id);
                        resolve();
                    });
                    _this.beforehandDependencies((_a = module.config) === null || _a === void 0 ? void 0 : _a.prerender).then(function () {
                        _this.app.trigger('prerenderComplete');
                    });
                });
            });
        });
    };
    TransformSwitch.prototype.pos = function () {
        var x = 0;
        var y = 0;
        var attach = 'center';
        var origin = 'center';
        var width = this.relativeViewport.offsetWidth;
        var height = this.relativeViewport.offsetHeight;
        var event = this.touches ? this.touches['srcEvent'] : {};
        if (event.changedTouches) {
            x = event.changedTouches[0].pageX;
            y = event.changedTouches[0].pageY;
        }
        else {
            x = event.x;
            y = event.y;
        }
        if (x && y) {
            origin = [x, y];
            if (x < width / 4) {
                x = 0;
            }
            else if (x > width * 3 / 4) {
                x = width;
            }
            if (y < height / 4) {
                y = 0;
            }
            else if (y > height * 3 / 4) {
                y = height;
            }
            attach = [x, y];
        }
        return {
            x: x,
            y: y,
            width: width,
            height: height,
            attach: attach,
            origin: origin
        };
    };
    Object.defineProperty(TransformSwitch.prototype, "backsetState", {
        get: function () {
            return (this.moduli.length === 1 || this.module.level === this.modulu.level) ? -1 : (this.module.level > this.modulu.level ? 0 : 1);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(TransformSwitch.prototype, "viewport", {
        get: function () {
            var _a, _b;
            return this.switchover ? [
                this.module.config.free === false ? this.relativeViewport : this.absoluteViewport,
                ((_a = this.modulu) === null || _a === void 0 ? void 0 : _a.config.free) === false ? this.relativeViewport : this.absoluteViewport
            ] : [
                this.module.elements.container,
                (_b = this.modulu) === null || _b === void 0 ? void 0 : _b.elements.container
            ];
        },
        enumerable: false,
        configurable: true
    });
    TransformSwitch.prototype.modulation = function (callback) {
        var viewport = this.viewport;
        var backset = this.backsetState;
        var reverse = backset === 0 ? false : true;
        var pos = this.pos();
        var animateEvent = {
            x: pos.x,
            y: pos.y,
            in: new Animate(viewport[0]),
            out: new Animate(viewport[1]),
            view: viewport,
            width: pos.width,
            height: pos.height,
            viewport: [this.relativeViewport, this.absoluteViewport],
            modules: this.moduli,
            reverse: reverse,
            direction: reverse ? -1 : 1,
            backset: backset,
            origin: origin,
            attach: pos.attach,
            touches: this.touches,
            callback: callback
        };
        return animateEvent;
    };
    TransformSwitch.prototype.transform = function () {
        var _this = this;
        return new Promise(function (resolve) {
            if (!_this.animation) {
                _this.switchViewport();
                resolve(true);
                return;
            }
            var backset = _this.backsetState;
            var animation = _this.getAnimationOneSide(backset);
            var end = function (stillness) { return resolve(stillness); };
            if (!animation)
                return end(true);
            var prosise = animation(_this.modulation(end));
            if (prosise instanceof Promise)
                prosise.then(end);
        });
    };
    TransformSwitch.prototype.hintWillTrans = function (viewport) {
        viewport[0].style.willChange = 'transform, opacity';
        if (viewport[1]) {
            viewport[1].style.willChange = 'transform, opacity';
        }
    };
    TransformSwitch.prototype.removeTransHint = function (viewport) {
        viewport[0].style.willChange = 'auto';
        if (viewport[1]) {
            viewport[1].style.willChange = 'auto';
        }
    };
    TransformSwitch.prototype.start = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this.app.trigger('transformStart', _this.moduli);
            var transformStart = _this.module.events.transformStart;
            if (typeof transformStart === 'function') {
                if (transformStart.call(_this.module) === false)
                    return reject();
            }
            if (!_this.animation || _this.switchover) {
                _this.module.elements.container.style.transform = 'translate3d(0, 0, 0)';
            }
            resolve();
        });
    };
    TransformSwitch.prototype.end = function (stillness) {
        if (stillness === void 0) { stillness = false; }
        var transformEnd = this.module.events.transformEnd;
        this.removeTransHint(this.viewport);
        if (this.switchover) {
            this.switchViewport();
        }
        if (this.modulu) {
            if (!this.animation || !stillness) {
                if (this.modulu.rel === 'module') {
                    this.modulu.elements.container.style.transform = 'translate3d(200%, 200%, 0)';
                }
                this.resetContainer(this.module, true);
            }
            this.modulu.elements.container.style.transitionDuration = '0ms';
            if (this.modulu.config.background === true) {
                this.modulu.hide();
            }
            else {
                this.destroy(this.modulu);
            }
        }
        this.module.show();
        if (typeof transformEnd === 'function') {
            transformEnd.call(this.module);
        }
        this.app.trigger('transformEnd', this.moduli);
    };
    TransformSwitch.prototype.switchViewport = function () {
        var _a, _b;
        this.resetViewport();
        if (((_b = (_a = this.module) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.free) === false) {
            this.absoluteViewport.style.transform = 'translate3d(200%, 200%, 0)';
            this.relativeViewport.style.transform = 'translate3d(0, 0, 0)';
        }
        else {
            this.relativeViewport.style.transform = 'translate3d(200%, 200%, 0)';
            this.absoluteViewport.style.transform = 'translate3d(0, 0, 0)';
        }
    };
    return TransformSwitch;
}(TransformHistory));

var Transform = /** @class */ (function (_super) {
    __extends(Transform, _super);
    function Transform(app) {
        return _super.call(this, app) || this;
    }
    Transform.prototype.setup = function (options) {
        this.options = options;
    };
    return Transform;
}(TransformSwitch));

var ApplicationProptey = /** @class */ (function (_super) {
    __extends(ApplicationProptey, _super);
    function ApplicationProptey() {
        var _this = _super.call(this) || this;
        _this.modules = {};
        _this.historyNodeLocation = history.length;
        _this.routerRegExp = /([^#\/]+)(.+)?/;
        _this.options = {
            modules: {}
        };
        return _this;
    }
    ApplicationProptey.prototype.setting = function (options) {
        this.options = options;
    };
    return ApplicationProptey;
}(EventProvider));

var BASE_CSS = "\n* { box-sizing: border-box; margin: 0; padding: 0; text-size-adjust: 100%; tap-highlight-color: rgba(0, 0, 0, 0)  } \n\nhtml, body { position: absolute; width: 100%; height: 100%; background: #fff; overflow: hidden; overscroll-behavior: none } \n\nmodule-mask, module-view { position: absolute; width: 100%; height: 100%; overflow: hidden } \n\nmodule-container[type=module] { display: block; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100% } \n\niframe { width: 100%; height: 100%; border: 0 } \n\n";

var ApplicationBase = /** @class */ (function (_super) {
    __extends(ApplicationBase, _super);
    function ApplicationBase() {
        var _a, _b;
        var _this = _super.call(this) || this;
        _this.properties = {
            darkTheme: (_b = (_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, '(prefers-color-scheme: dark)')) === null || _b === void 0 ? void 0 : _b.matches
        };
        _this.console = {
            echo: function (type, pre, mid, suf) {
                console[type]('%c ' +
                    (pre[0] ? pre[0] + ' ' : '') +
                    '%c ' + (mid[0] ? mid[0] + ' ' : '') +
                    '%c ' + (suf[0] ? suf[0] + ' ' : ''), 'color: #ffffff; background:' + pre[1], 'color: #ffffff; background:' + mid[1], 'color: #ffffff; background:' + (suf[0] ? suf[1] : mid[1]));
            },
            log: function (message, title, description) {
                _this.console.echo('log', [title, '#999'], [message, '#333'], [description, '#666']);
            },
            info: function (message, title, description) {
                _this.console.echo('info', [title, '#0cf'], [message, '#06c'], [description, '#0c0']);
            },
            warn: function (message, title, description) {
                _this.console.echo('warn', [title, '#f60'], [message, '#f30'], [description, '#f90']);
            },
            error: function (message, title, description) {
                _this.console.echo('warn', [title, '#f06'], [message, '#903'], [description, '#993']);
            }
        };
        _this.setBaseCSS();
        return _this;
    }
    Object.defineProperty(ApplicationBase.prototype, "route", {
        get: function () {
            var router = this.routerRegExp.exec(location.hash) || [];
            var id = router[1];
            var param = router[2];
            var search = location.search;
            return {
                id: id ? decodeURIComponent(id) : '',
                param: param ? decodeURIComponent(param) : '',
                search: search
            };
        },
        enumerable: false,
        configurable: true
    });
    ApplicationBase.prototype.setBaseCSS = function () {
        var style = document.createElement('style');
        style.innerHTML = BASE_CSS;
        document.getElementsByTagName('head')[0].appendChild(style);
    };
    ApplicationBase.prototype.resolveURL = function (url) {
        var link = document.createElement('a');
        link.href = url;
        var path = link.origin + link.pathname;
        return {
            path: path,
            origin: link.origin,
            host: link.host,
            search: link.search
        };
    };
    ApplicationBase.prototype.promiseModule = function (promise) {
        var _this = this;
        return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
            var _a, error_1;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _b.trys.push([0, 2, , 3]);
                        _a = resolve;
                        return [4 /*yield*/, promise()];
                    case 1:
                        _a.apply(void 0, [_b.sent()]);
                        return [3 /*break*/, 3];
                    case 2:
                        error_1 = _b.sent();
                        reject(error_1);
                        return [3 /*break*/, 3];
                    case 3: return [2 /*return*/];
                }
            });
        }); });
    };
    ApplicationBase.prototype.moduleSrcVerify = function (url) {
        var allowHosts = this.config.allowHosts;
        if (!Array.isArray(allowHosts)) {
            this.console.warn('Module.config.allowHosts is not defined', 'Security risks exist: ', '');
            return true;
        }
        var link = document.createElement('a');
        link.href = decodeURIComponent(url);
        var linkHost = link.host;
        for (var _i = 0, allowHosts_1 = allowHosts; _i < allowHosts_1.length; _i++) {
            var host = allowHosts_1[_i];
            if (linkHost === host)
                return true;
        }
        return false;
    };
    ApplicationBase.prototype.getModuleByURL = function (url) {
        var modules = this.modules;
        var resolve = this.resolveURL(url);
        var path = resolve.path;
        for (var id in modules) {
            var module_1 = modules[id];
            var capture = module_1.config.capture;
            if (typeof capture === 'string') {
                if (capture === path)
                    return module_1;
            }
            else if (typeof capture === 'function') {
                if (capture(resolve, url))
                    return module_1;
            }
            if (module_1.uri === path)
                return module_1;
        }
        return;
    };
    ApplicationBase.prototype.setExists = function () {
        return new Promise(function (resolve, reject) {
            try {
                sessionStorage.setItem('__EXISTS', String(history.length));
                resolve();
            }
            catch (e) {
                reject();
            }
        });
    };
    Object.defineProperty(ApplicationBase.prototype, "exists", {
        get: function () {
            try {
                return parseInt(sessionStorage.getItem('__EXISTS') || '-1', 10) === history.length;
            }
            catch (e) {
                return false;
            }
        },
        enumerable: false,
        configurable: true
    });
    return ApplicationBase;
}(ApplicationProptey));

var provider = (function (app) {
    window.addEventListener('message', function (event) {
        var data = event.data;
        var action = data.action;
        switch (action) {
            case 'to':
                app.transform.to(data.module, data.query, data.history);
                break;
            case 'back':
                history.back();
                break;
            case 'forward':
                history.forward();
                break;
        }
    });
    return;
});

var Application = /** @class */ (function (_super) {
    __extends(Application, _super);
    function Application() {
        var _this = _super.call(this) || this;
        _this.transform = new Transform(_this);
        provider(_this);
        return _this;
    }
    Object.defineProperty(Application.prototype, "activeModule", {
        get: function () {
            var id = this.transform.id;
            var module = this.modules[id];
            return module;
        },
        enumerable: false,
        configurable: true
    });
    Application.prototype.add = function (id, manifest) {
        return this.modules[id] = new Module(id, manifest, this);
    };
    Application.prototype.del = function (module) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            delete _this.modules[module.id];
            if (module.status.init) {
                module.destroy().then(resolve).catch(reject);
            }
            else {
                resolve();
            }
        });
    };
    Application.prototype.get = function (id) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            if (!id)
                return reject();
            if (typeof _this.modules[id] === 'object')
                return resolve(_this.modules[id]);
            var modulePromise = _this.options.modules[id];
            switch (typeof modulePromise) {
                case 'function':
                    _this.promiseModule(modulePromise).then(function (manifest) {
                        resolve(_this.add(id, manifest));
                    }).catch(reject);
                    break;
                case 'object':
                    resolve(_this.add(id, modulePromise));
                    break;
                default:
                    var url = id;
                    if (!_this.moduleSrcVerify(url)) {
                        reject();
                        break;
                    }
                    var module_1 = _this.createModuleByURL(url);
                    if (module_1) {
                        resolve(module_1);
                    }
                    else {
                        reject();
                    }
                    break;
            }
        });
    };
    Application.prototype.createModuleByURL = function (url, config) {
        var _a, _b;
        var newModuleId = decodeURIComponent(url);
        var modules = this.modules;
        if (modules[newModuleId])
            return modules[newModuleId];
        var sameModule = this.getModuleByURL(url);
        if (sameModule)
            return sameModule;
        return this.add(newModuleId, {
            config: Object.assign({
                title: '',
                rel: 'module',
                level: ((_b = (_a = this.activeModule) === null || _a === void 0 ? void 0 : _a.config.level) !== null && _b !== void 0 ? _b : 0) + 1,
                free: true,
                source: {
                    src: url
                },
                background: 'auto',
                timeout: 0,
                animation: 'inherit',
                transient: true
            }, config)
        });
    };
    Application.prototype.pushWindow = function (url, title, preset) {
        var _this = this;
        if (title === void 0) { title = ''; }
        if (preset === void 0) { preset = 'slide'; }
        var resolve = this.resolveURL(url);
        var search = resolve.search;
        if (!this.moduleSrcVerify(url)) {
            return Promise.reject('Illegal');
        }
        return new Promise(function (resolve, reject) {
            var module = _this.createModuleByURL(url, {
                title: title,
                animation: preset
            });
            if (module) {
                _this.transform.to(module.id, module.config.source.html ? search : '').then(resolve).catch(reject);
            }
        });
    };
    Application.prototype.mountSystem = function () {
        var _this = this;
        if (this.options.modules['system']) {
            this.get('system').then(function () {
                _this.transform.to('system', undefined, -1).then(function () {
                    _this.trigger('systemDidMount');
                });
            });
        }
    };
    Application.prototype.mountFramework = function () {
        var _this = this;
        this.get('frameworks').then(function (module) {
            var route = _this.route;
            var index = module.config.index || '';
            var id = route.id || index;
            var config = module.config;
            _this.config = config;
            _this.transform.setup({
                singleFlow: config.singleFlow,
                index: index,
                defaultIndex: id,
                notFound: config.notFind,
                limit: Math.max(config.limit || 7, 2),
                exists: _this.exists,
                defaultAnimation: config.animation
            });
            _this.transform.to('frameworks', undefined, -1).then(function () {
                _this.trigger('frameworksDidMount');
            });
            if (id !== index) {
                _this.transform.pushState(index);
                if (id)
                    _this.transform.to(id);
                return;
            }
            if (id)
                _this.transform.to(id);
        }).catch(function () {
            _this.console.error('Module frameworks must be included!', 'Serious!', '');
        });
    };
    Application.prototype.start = function () {
        this.setExists();
        this.mountFramework();
        this.mountSystem();
    };
    return Application;
}(ApplicationBase));

var application = new Application();

exports.Application = Application;
exports.application = application;