UNPKG

pages-cook

Version:

web-portals

1,358 lines (1,333 loc) 71.1 kB
class ModuleProptey { constructor(id, model, application) { this.param = {}; this.events = { transformStart: () => undefined, transformEnd: () => undefined, start: () => undefined, load: () => undefined, loadError: () => undefined, preload: () => undefined, destroy: () => 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; const { config, resources, events } = this.setDefaultConfig(model); Object.assign(this.config, config); Object.assign(this.resources, resources); Object.assign(this.events, events); } setDefaultConfig(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; } } class ModuleState extends ModuleProptey { constructor(id, model, application) { super(id, model, application); } get sameOrigin() { if (!this.uri) return true; const link = document.createElement('a'); link.href = this.uri; const isSameOrigin = link.host === location.host; return isSameOrigin; } get level() { var _a; const level = this.config.level || (((_a = this.application.activeModule) === null || _a === void 0 ? void 0 : _a.config.level) || 1) + 1; const baseLevel = this.config.free ? 20000 : 10000; return baseLevel + level; } get rel() { if (this.id === 'system') return 'system'; if (this.id === 'frameworks') return 'frameworks'; return this.config.rel || 'module'; } get uri() { var _a, _b; return ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.source) === null || _b === void 0 ? void 0 : _b.src) || ''; } get viewType() { 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) { const type = ('HTMLPortalElement' in window) && this.sameOrigin ? 'portal' : 'iframe'; this.shadowViewType = type; } return this.shadowViewType; } } class ModuleMount extends ModuleState { constructor(id, model, application) { super(id, model, application); } timeTick() { if (Date.now() - this.createTime > (this.config.timeout || 3600000)) { if (this.shadowView) this.destroy(); } } show() { if (this.viewType !== 'iframe') return; const sandbox = this.shadowView; const contentWindow = sandbox === null || sandbox === void 0 ? void 0 : sandbox.contentWindow; if (contentWindow) { contentWindow.window.postMessage('module-visible', '*'); if (this.sameOrigin) { contentWindow.window['moduleVisibilityState'] = 'visible'; } } } hide() { var _a; if (this.viewType !== 'iframe') return; const sandbox = this.shadowView; const 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'; } } } destroy() { return new Promise((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(); }); } fate() { return new Promise((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(); const sandbox = this.shadowView; if (!sandbox) return; try { const 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) { const counter = { times: 0 }; this.mutationObserver = new MutationObserver(() => { counter.times++; if (counter.times > 1000) { resolve(); this.mutationObserver.disconnect(); } }); this.mutationObserver.observe(contentDocumentElement, { subtree: true, attributes: true, childList: true, characterData: true, attributeOldValue: true, characterDataOldValue: true }); setTimeout(() => { if (counter.times > 10) resolve(); }, 3000); } else { reject(); } } catch (error) { reject(); } }); } unfate() { var _a; (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); } unload() { return new Promise((resolve, reject) => { var _a, _b; this.unfate(); const sandbox = this.shadowView; if (!sandbox) return resolve(); sandbox.style.display = 'none'; sandbox.src = 'about:blank'; try { const contentWindow = (_a = sandbox.contentWindow) === null || _a === void 0 ? void 0 : _a.window; const 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(); }); } } class ModulePrefetch extends ModuleMount { constructor(id, model, application) { super(id, model, application); } prefetch() { return new Promise((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(() => { this.status.prefetch = true; resolve(true); }).catch(reject); }); } prefetchStatic(list = [], as = 'script') { return new Promise((resolve, reject) => { Promise.all([].concat(list).map(url => this.beforehandLink(url, 'preload', as))).then(resolve).catch(reject); }); } beforehandLink(url, rel = 'preload', as = 'worker | video | audio | font | script | style | image | document') { if (!url) return Promise.reject(); return new Promise((resolve, reject) => { var _a; const 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); }); } } var windowOpen = (moduleWindow, application) => { const realOpen = moduleWindow.open; moduleWindow.addEventListener('click', (event) => { const path = event['path'] || []; const anchor = (() => { for (const el of path) { if (el.tagName === 'A') return el; } })(); if ((anchor === null || anchor === void 0 ? void 0 : anchor.target) === '_bank') { const href = anchor.href; const title = anchor.title || ''; const preset = anchor.getAttribute('preset'); if (href) { application.pushWindow(href, title, preset).catch(() => { realOpen(href); }); event.stopPropagation(); event.preventDefault(); } } }); moduleWindow.open = (url, target, features) => { if (typeof url !== 'string' || target || features) { return realOpen(url, target, features); } if (typeof url === 'string') { application.pushWindow(url, '').catch(() => { realOpen(url); }); } return null; }; }; const getTimerHandler = (handler, moduleWindow) => { return (..._args) => { if (moduleWindow['moduleVisibilityState'] === 'visible') { if (typeof handler === 'function') { handler(..._args); } else if (typeof handler === 'string') { const evalHander = new moduleWindow['Function'](`return ${handler}`); evalHander(..._args); } } }; }; const smartSetTimeout = (moduleWindow) => { const realSetTimeout = moduleWindow.setTimeout; moduleWindow.setInterval = (handler, timeout, ...args) => { const fn = getTimerHandler(handler, moduleWindow); const intervalId = realSetTimeout(fn, timeout, ...args); return intervalId; }; }; const smartSetInterval = (moduleWindow) => { const realSetInterval = moduleWindow.setInterval; moduleWindow.setInterval = (handler, timeout, ...args) => { const fn = getTimerHandler(handler, moduleWindow); const intervalId = realSetInterval(fn, timeout, ...args); return intervalId; }; }; var tapHighlight = (moduleWindow, capture) => { const touchActive = { element: null, oldStyle: '' }; const addHighlight = (event) => { const captureList = capture ? typeof capture === 'string' ? capture.split(' ') : capture : null; const path = event['path'] || event.composedPath() || []; path.splice(-3); const anchor = (() => { var _a, _b, _c; for (const el of path) { if (!((_a = el.children) === null || _a === void 0 ? void 0 : _a.length)) continue; if (el.tagName === 'A') return el; if (captureList) { for (const attr of captureList) { 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(() => { if (touchActive.element === anchor) anchor.style.filter = touchActive.oldStyle + ' brightness(.8)'; const continueCheck = () => { setTimeout(() => { if (touchActive.element !== anchor) { anchor.style.filter = touchActive.oldStyle; } else { continueCheck(); } }, 600); }; continueCheck(); }, 60); }; const cancelHighlight = () => { 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 = ''; }; const delayCancelHighlight = () => { setTimeout(() => { 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 = (moduleWindow, config, application) => { const apply = config.apply || []; if (Array.isArray(apply)) { for (const item of apply) { 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); } }; class ModuleView extends ModulePrefetch { constructor(id, model, application) { super(id, model, application); } rigesterElement(name, element) { this.elements[name] = element; if (name === 'container' && element) { this.status.init = true; } } createSandbox(uri, config) { const sandbox = document.createElement('iframe'); if (config !== undefined) sandbox.setAttribute('sandbox', config); if (uri) sandbox.src = uri; return sandbox; } writeSandbox(sandbox, container) { var _a, _b; sandbox.src = 'about:blank'; sandbox.setAttribute('seamless', 'seamless'); container.appendChild(sandbox); const contentDocument = sandbox.contentDocument; const 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); } } createShadowbox(render) { const shadowbox = document.createElement('div'); const shadowboxInner = document.createElement('div'); shadowbox === null || shadowbox === void 0 ? void 0 : shadowbox.attachShadow({ mode: 'open' }); const shadowRoot = shadowbox.shadowRoot ? shadowbox.shadowRoot : shadowbox; shadowRoot.appendChild(shadowboxInner); render(shadowboxInner); this.elements.container.appendChild(shadowbox); return shadowbox; } createPortals(uri) { const portal = document.createElement('portal'); portal.src = uri; return portal; } createShadowView() { 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); } loadShadowView() { const container = this.elements.container; const shadowView = this.shadowView; if (!shadowView) return; switch (this.viewType) { case 'portal': container.appendChild(shadowView); break; case 'iframe': default: if (this.uri) { container.appendChild(shadowView); const 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; } } create(prepare = true) { this.unfate(); this.timeTick(); if (this.status.prerender) { return Promise.resolve('prerender'); } return new Promise((resolve, reject) => { this.createTime = Date.now(); const shadowView = this.createShadowView(); if (!shadowView) { return resolve('null'); } if (this.viewType === 'shadow') { return resolve('shadow'); } shadowView.style.cssText = ` position: absolute; z-index: 0; width: 100%; height: 100%; border: 0; transform: translate3d(0, 0, 0); `; shadowView.onload = (e) => { var _a; this.status.prerender = true; (_a = this.events) === null || _a === void 0 ? void 0 : _a.load.bind(this)(); resolve(e); }; shadowView.onerror = (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(() => { resolve('timeout'); }, this.status.preload ? 800 : 200); }); } preload() { return new Promise((resolve, reject) => { const uri = this.uri; const head = document.head; const sandbox = this.createSandbox('', ''); sandbox.style.display = 'none'; sandbox.onload = (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 = (e) => { head.removeChild(sandbox); reject(e); }; if (uri) { sandbox.src = this.uri; head.appendChild(sandbox); } else { this.writeSandbox(sandbox, head); } }); } prerender() { if (this.status.preload || this.status.prerender) { return Promise.resolve(); } return new Promise((resolve, reject) => { this.preload().then(resolve).catch(reject); this.beforehandLink(this.uri, 'prerender', 'document'); }); } } class Module extends ModuleView { constructor(id, model, application) { super(id, model, application); this.events.start.bind(this)(); } } /*! ***************************************************************************** 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. ***************************************************************************** */ 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()); }); } 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)' }; class EventProvider { constructor() { this._events = {}; } on(type, fn) { const types = type.split(' '); types.forEach((typ) => { if (!this._events[typ]) { this._events[typ] = [fn]; } else { this._events[typ].push(fn); } }); return this; } one(type, fn) { const once = (...args) => { fn.apply(null, args); this.off(type, once); }; const types = type.split(' '); types.forEach((typ) => { if (!this._events[typ]) { this._events[typ] = [once]; } else { this._events[typ].push(once); } }); return this; } off(type, fn) { const types = type.split(' '); types.forEach((typ) => { if (!this._events[typ]) return; const index = this._events[typ].indexOf(fn); if (index > -1) { this._events[typ].splice(index, 1); } }); return this; } trigger(type, ...args) { if (!this._events[type]) return; this._events[type].forEach(fn => { try { fn.apply(null, args); } catch (e) { this.off(type, fn); this.trigger('error', `Error by event[${type}]`); } }); return this; } } const rAF = requestAnimationFrame; const gCS = getComputedStyle; /* Animate */ class Animate extends EventProvider { constructor(el) { super(); 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.el = el; this.el.style.setProperty('transition-duration', '0ms'); } transform(transform) { this.transition('transform'); const propName = (transform.match(/\w+\b/) || [])[0]; if (propName) this._transforms[propName] = transform; return this; } skew(x, y) { return this.transform('skew(' + x + 'deg, ' + (y || 0) + 'deg)'); } skewX(n) { return this.transform('skewX(' + n + 'deg)'); } skewY(n) { return this.transform('skewY(' + n + 'deg)'); } to(x = 0, y = 0, z = 0) { // 3d set this.transform('translate3d(' + (x ? x + 'px' : 0) + ',' + (y ? y + 'px' : 0) + ',' + (z ? z + 'px' : 0) + ')'); return this; } x(n) { return this.transform('translateX(' + n + 'px)'); } y(n) { return this.transform('translateY(' + n + 'px)'); } z(z) { return this.transform('translateZ(' + z + 'px)'); } scale(x, y) { return this.transform('scale(' + x + ', ' + (y || x) + ')'); } opacity(o) { this.transition('opacity'); return this.style('opacity', o); } scaleX(n) { return this.transform('scaleX(' + n + ')'); } matrix(m11, m12, m21, m22, m31, m32) { return this.transform('matrix(' + [m11, m12, m21, m22, m31, m32].join(',') + ')'); } scaleY(n) { return this.transform('scaleY(' + n + ')'); } rotate(n) { return this.transform('rotate(' + n + 'deg)'); } rotateX(n) { return this.transform('rotateX(' + n + 'deg)'); } rotateY(n) { return this.transform('rotateY(' + n + 'deg)'); } rotateZ(n) { return this.transform('rotateZ(' + n + 'deg)'); } rotate3d(x, y, z, d) { return this.transform('rotate3d(' + x + ', ' + y + ',' + z + ',' + d + 'deg)'); } perspective(z) { const box = this.el.parentElement; if (box) { box.style.setProperty('transform-style', 'preserve-3d'); box.style.setProperty('perspective', z + 'px'); } return this; } backface(visibility = true) { return this.style('backface-visibility', visibility ? 'visible' : 'hidden'); } ease(s) { s = ease[s] || s || 'ease'; return this.style('transition-timing-function', s); } animate(name, props) { for (const i in props) { if (props.hasOwnProperty(i)) { this.style('animation-' + i, props[i]); } } return this.style('animation-name', name); } duration(n) { n = 'string' === typeof n ? parseFloat(n) * 1000 : n; return this.style('transition-duration', n + 'ms'); } getDuration() { return !!parseFloat(gCS(this.el).transitionDuration); } delay(n) { n = 'string' === typeof n ? parseFloat(n) * 1000 : n; return this.style('transition-delay', n + 'ms'); } origin(x, y) { let 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); } width(val) { this.transition('width'); return this.style('width', val === undefined ? '' : val + 'px'); } height(val) { this.transition('height'); return this.style('height', val === undefined ? '' : val + 'px'); } add(prop, val) { return this.on('start', () => { const curr = parseInt(this.current(prop), 10); this.style(prop, curr + val + 'px'); }); } subc(prop, val) { return this.on('start', () => { const curr = parseInt(this.current(prop), 10); this.style(prop, curr - val + 'px'); }); } current(prop) { return gCS(this.el).getPropertyValue(prop); } transition(prop) { if (this._transitionProps.indexOf(prop) === -1) this._transitionProps.push(prop); return this; } filter(val) { this.style('filter', val); this.transition('filter'); return this; } style(prop, val) { this._props[prop] = val === undefined ? '' : val; return this; } _transitionend(fn) { if (!this.getDuration()) return setTimeout(fn, 0); const onec = (e) => { if (e.target !== this.el) return false; fn(e); this.el.removeEventListener('transitionend', onec, false); }; this.el.addEventListener('transitionend', onec, false); } _applyTransform() { const transform = []; if (!this._transforms['translate3d'] && !this._transforms['translateZ']) { this._transforms['translateZ'] = 'translateZ(0)'; } for (const i in this._transforms) { transform.push(this._transforms[i]); } if (transform.length) { this.style('transform', transform.join(' ')); } return this; } applyProperties() { const prop = this._proper.shift(); this._transforming = true; for (const name in prop) { this.el.style.setProperty(name, prop[name]); } this._transitionend(() => { this.clear(); this.next(); }); return this; } next() { if (this._caller.length) { const fn = this._caller.shift(); fn && fn(); } if (this._caller.length === 0) { this.init(); } else { rAF(() => { this.applyProperties(); }); } } clear() { this._transforms = {}; } init() { if (this.getDuration()) { this.el.style.setProperty('transition-duration', '0ms'); } this.clear(); this._transforming = false; return this; } then(fn) { this._applyTransform(); this.style('transition-property', this._transitionProps.join(', ')); this._proper.push(this._props); this._props = {}; this._caller.push(() => fn && fn.call(this)); return this; } end(fn) { this.then(fn); if (this._transforming) return this; rAF(() => { this.applyProperties(); }); return this; } } var flip = (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(() => { e.out.duration(400).ease('ease-out-expo').perspective(1000).rotate3d(0, 1, 0, -90 * e.direction).scale(.92).end(() => { 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(() => { e.in.duration(400).rotate3d(0, 1, 0, 0).end(() => { e.callback(false); }); }); }); }); }; var fade = (type) => { return (e) => { let 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 = (type) => { return (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(() => { e.out.origin(type === 1 ? e.attach : e.origin).ease('ease-in-expo').duration(0).to(0, 0, 0).opacity(1).scale(1).end(() => { 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(() => { e.callback(false); }); }); }); }; }; var slide = (type) => { return (e) => { let inX = 0; let outX = 0; let inY = 0; let 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(() => { 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(() => { e.callback(false); }); }); } else { e.in.duration(0).to(inX, inY, 0).end(() => { e.in.duration(767).ease('ease-out-expo').to(0, 0, 0).end(() => { e.callback(false); }); e.out.duration(767).filter('brightness(0.5)').to(outX * .5, outY * .5, 0).end(); }); } }; }; var effectTypes = { flip, fade, zoom, slide }; class TransformProptey { constructor(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(); } setupViewport() { 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); } resetViewport() { 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'; } } class TransformAnimation extends TransformProptey { constructor(app) { super(app); } getAnimationGroup() { if (!this.modulu || this.modulu.rel !== 'module') return false; let animationFunction; let 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; } getAnimationOneSide(backset) { const 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; } getAnimationByName(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; } } } class TransformHistory extends TransformAnimation { constructor(app) { super(app); this.backoutCount = 0; this.bindHistoryState(); } bindHistoryState() { addEventListener('popstate', this.popstate.bind(this)); } popstate(event) { this.back(event); } pushState(id = '', title = '', search = location.search, param = '') { id = encodeURIComponent(id); history.pushState({ id, title, time: Date.now(), search, historyIndex: history.length }, title, location.pathname + search + '#' + id + '/' + param); } replaceState(id = '', title = '', search = location.search, param = '') { id = encodeURIComponent(id); history.replaceState({ id, title, time: Date.now(), search, historyIndex: history.length }, title, location.pathname + search + '#' + id + '/' + param); } back(event) { return __awaiter(this, void 0, void 0, function* () { const options = this.options; const route = event.state || this.app.route; const id = decodeURIComponent(route.id) || options.index || 'frameworks'; const search = route.search; const module = yield this.app.get(id); if (!module) return; /** * 如果设置了单向锁,且回退时模块层级为 0 时 * 阻止返回,并发送事件 */ if (this.checkSingleLock()) { this.backoutCount++; this.pushState(id, module.config.title, search); this.app.trigger('exit', { backoutCount: this.backoutCount }); return; } else { this.backoutCount = 0; } if (options.singleFlow && module.config.level !== 0 && module.config.level >= this.module.config.level) { return history.back(); } this.app.transform.to(id, search, -1); this.app.trigger('back', { id, module }); }); } checkSingleLock() { return this.options.singleLock && this.module.config.level === 0 ? true : false; } } class TransformSwitch extends TransformHistory { constructor(app) { super(app); this.windowSet = []; this.promiseQueue = []; this.promiseParamQueue = []; } checkSingleLock() { return this.options.singleLock && this.module.config.level === 0 ? true : false; } createContainer(module) { if (module.status.init) return; const 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); } resetContainer(module, situ = false) { const config = module.config; const container = module.elements.container; const systemLevel = ['frameworks', 'system'].includes(module.rel); const isDarkModel = this.app.properties.darkTheme; container.style.cssText = ''; if (!systemLevel) { container.style.cssText = ` position: absolute; z-index: ${(Number(module.level) || 0) + 1}; width: 100%; height: 100%; background: ${config.color || (isDarkModel ? '#000' : '#fff')}; transform: ${situ ? 'translate3d(0, 0, 0)' : 'translate3d(200%, 200%, 0)'}; contain: strict; `; } } getViewport(module = this.module) { return module.rel === 'system' ? this.fixedViewport : module.config.free === false ? (this.relativeViewport.shadowRoot || this.relativeViewport) : (this.absoluteViewport.shadowRoot || this.absoluteViewport); } checkSwitchover(modulu = this.modulu, module = this.module) { return (modulu === null || modulu === void 0 ? void 0 : modulu.rel) === 'module' && module.config.free !== modulu.config.free ? true : false; } to(...args) { return __awaiter(this, void 0, void 0, function* () { return this.pushPromise(this.next() || this.promise(...args), args); }); } prev() { return this.promiseQueue[0]; } next() { const prev = this.prev(); if (prev) { return new Promise((resolve, reject) => { prev.then(() => { if (this.promiseParamQueue[0]) { this.promise(...this.promiseParamQueue[0]).then(resolve).catch(reject); } });