@huluvu424242/honey-papercss-style
Version:
styles to apply with honey webcomponents.
643 lines (640 loc) • 22.9 kB
JavaScript
const NAMESPACE = 'honey-papercss-style';
let isSvgMode = false;
let queuePending = false;
const win = typeof window !== 'undefined' ? window : {};
const doc = win.document || { head: {} };
const plt = {
$flags$: 0,
$resourcesUrl$: '',
jmp: (h) => h(),
raf: (h) => requestAnimationFrame(h),
ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
ce: (eventName, opts) => new CustomEvent(eventName, opts),
};
const promiseResolve = (v) => Promise.resolve(v);
const HYDRATED_CSS = '{visibility:hidden}.hydrated{visibility:inherit}';
const createTime = (fnName, tagName = '') => {
{
return () => {
return;
};
}
};
const uniqueTime = (key, measureText) => {
{
return () => {
return;
};
}
};
/**
* Default style mode id
*/
/**
* Reusable empty obj/array
* Don't add values to these!!
*/
const EMPTY_OBJ = {};
const isComplexType = (o) => {
// https://jsperf.com/typeof-fn-object/5
o = typeof o;
return o === 'object' || o === 'function';
};
/**
* Production h() function based on Preact by
* Jason Miller (@developit)
* Licensed under the MIT License
* https://github.com/developit/preact/blob/master/LICENSE
*
* Modified for Stencil's compiler and vdom
*/
// const stack: any[] = [];
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, child?: d.ChildType): d.VNode;
// export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
const h = (nodeName, vnodeData, ...children) => {
let child = null;
let simple = false;
let lastSimple = false;
let vNodeChildren = [];
const walk = (c) => {
for (let i = 0; i < c.length; i++) {
child = c[i];
if (Array.isArray(child)) {
walk(child);
}
else if (child != null && typeof child !== 'boolean') {
if ((simple = typeof nodeName !== 'function' && !isComplexType(child))) {
child = String(child);
}
if (simple && lastSimple) {
// If the previous child was simple (string), we merge both
vNodeChildren[vNodeChildren.length - 1].$text$ += child;
}
else {
// Append a new vNode, if it's text, we create a text vNode
vNodeChildren.push(simple ? newVNode(null, child) : child);
}
lastSimple = simple;
}
}
};
walk(children);
const vnode = newVNode(nodeName, null);
vnode.$attrs$ = vnodeData;
if (vNodeChildren.length > 0) {
vnode.$children$ = vNodeChildren;
}
return vnode;
};
const newVNode = (tag, text) => {
const vnode = {
$flags$: 0,
$tag$: tag,
$text$: text,
$elm$: null,
$children$: null,
};
{
vnode.$attrs$ = null;
}
return vnode;
};
const Host = {};
const isHost = (node) => node && node.$tag$ === Host;
/**
* Production setAccessor() function based on Preact by
* Jason Miller (@developit)
* Licensed under the MIT License
* https://github.com/developit/preact/blob/master/LICENSE
*
* Modified for Stencil's compiler and vdom
*/
const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
if (oldValue !== newValue) {
let isProp = isMemberInElement(elm, memberName);
memberName.toLowerCase();
{
// Set property if it exists and it's not a SVG
const isComplex = isComplexType(newValue);
if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
try {
if (!elm.tagName.includes('-')) {
let n = newValue == null ? '' : newValue;
// Workaround for Safari, moving the <input> caret when re-assigning the same valued
if (memberName === 'list') {
isProp = false;
// tslint:disable-next-line: triple-equals
}
else if (oldValue == null || elm[memberName] != n) {
elm[memberName] = n;
}
}
else {
elm[memberName] = newValue;
}
}
catch (e) { }
}
if (newValue == null || newValue === false) {
if (newValue !== false || elm.getAttribute(memberName) === '') {
{
elm.removeAttribute(memberName);
}
}
}
else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
newValue = newValue === true ? '' : newValue;
{
elm.setAttribute(memberName, newValue);
}
}
}
}
};
const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
// if the element passed in is a shadow root, which is a document fragment
// then we want to be adding attrs/props to the shadow root's "host" element
// if it's not a shadow root, then we add attrs/props to the same element
const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host
? newVnode.$elm$.host
: newVnode.$elm$;
const oldVnodeAttrs = (oldVnode && oldVnode.$attrs$) || EMPTY_OBJ;
const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
// add new & update changed attributes
for (memberName in newVnodeAttrs) {
setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode, newVnode.$flags$);
}
};
const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
// tslint:disable-next-line: prefer-const
let newVNode = newParentVNode.$children$[childIndex];
let i = 0;
let elm;
let childNode;
{
// create element
elm = newVNode.$elm$ = (doc.createElement(newVNode.$tag$));
// add css classes, attrs, props, listeners, etc.
{
updateElement(null, newVNode, isSvgMode);
}
if (newVNode.$children$) {
for (i = 0; i < newVNode.$children$.length; ++i) {
// create the node
childNode = createElm(oldParentVNode, newVNode, i);
// return node could have been null
if (childNode) {
// append our new node
elm.appendChild(childNode);
}
}
}
}
return elm;
};
const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
let containerElm = (parentElm);
let childNode;
for (; startIdx <= endIdx; ++startIdx) {
if (vnodes[startIdx]) {
childNode = createElm(null, parentVNode, startIdx);
if (childNode) {
vnodes[startIdx].$elm$ = childNode;
containerElm.insertBefore(childNode, before);
}
}
}
};
const patch = (oldVNode, newVNode) => {
const elm = (newVNode.$elm$ = oldVNode.$elm$);
const newChildren = newVNode.$children$;
{
// element node
{
{
// either this is the first render of an element OR it's an update
// AND we already know it's possible it could have changed
// this updates the element's css classes, attrs, props, listeners, etc.
updateElement(oldVNode, newVNode, isSvgMode);
}
}
if (newChildren !== null) {
// add the new vnode children
addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
}
else ;
}
};
const renderVdom = (hostRef, renderFnResults) => {
const hostElm = hostRef.$hostElement$;
const oldVNode = hostRef.$vnode$ || newVNode(null, null);
const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
rootVnode.$tag$ = null;
rootVnode.$flags$ |= 4 /* isHost */;
hostRef.$vnode$ = rootVnode;
rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
// synchronous patch
patch(oldVNode, rootVnode);
};
const emitEvent = (elm, name, opts) => {
const ev = plt.ce(name, opts);
elm.dispatchEvent(ev);
return ev;
};
const attachToAncestor = (hostRef, ancestorComponent) => {
if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent['s-p']) {
ancestorComponent['s-p'].push(new Promise((r) => (hostRef.$onRenderResolve$ = r)));
}
};
const scheduleUpdate = (hostRef, isInitialLoad) => {
if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
hostRef.$flags$ |= 512 /* needsRerender */;
return;
}
attachToAncestor(hostRef, hostRef.$ancestorComponent$);
// there is no ancestor component or the ancestor component
// has already fired off its lifecycle update then
// fire off the initial update
const dispatch = () => dispatchHooks(hostRef);
return writeTask(dispatch) ;
};
const dispatchHooks = (hostRef, isInitialLoad) => {
const endSchedule = createTime('scheduleUpdate', hostRef.$cmpMeta$.$tagName$);
const instance = hostRef.$lazyInstance$ ;
let promise;
endSchedule();
return then(promise, () => updateComponent(hostRef, instance));
};
const updateComponent = async (hostRef, instance, isInitialLoad) => {
// updateComponent
const elm = hostRef.$hostElement$;
const endUpdate = createTime('update', hostRef.$cmpMeta$.$tagName$);
const rc = elm['s-rc'];
const endRender = createTime('render', hostRef.$cmpMeta$.$tagName$);
{
callRender(hostRef, instance);
}
if (rc) {
// ok, so turns out there are some child host elements
// waiting on this parent element to load
// let's fire off all update callbacks waiting
rc.map((cb) => cb());
elm['s-rc'] = undefined;
}
endRender();
endUpdate();
{
const childrenPromises = elm['s-p'];
const postUpdate = () => postUpdateComponent(hostRef);
if (childrenPromises.length === 0) {
postUpdate();
}
else {
Promise.all(childrenPromises).then(postUpdate);
hostRef.$flags$ |= 4 /* isWaitingForChildren */;
childrenPromises.length = 0;
}
}
};
const callRender = (hostRef, instance, elm) => {
try {
instance = instance.render() ;
{
hostRef.$flags$ |= 2 /* hasRendered */;
}
{
{
// looks like we've got child nodes to render into this host element
// or we need to update the css class/attrs on the host element
// DOM WRITE!
{
renderVdom(hostRef, instance);
}
}
}
}
catch (e) {
consoleError(e, hostRef.$hostElement$);
}
return null;
};
const postUpdateComponent = (hostRef) => {
const tagName = hostRef.$cmpMeta$.$tagName$;
const elm = hostRef.$hostElement$;
const endPostUpdate = createTime('postUpdate', tagName);
const ancestorComponent = hostRef.$ancestorComponent$;
if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
hostRef.$flags$ |= 64 /* hasLoadedComponent */;
{
// DOM WRITE!
addHydratedFlag(elm);
}
endPostUpdate();
{
hostRef.$onReadyResolve$(elm);
if (!ancestorComponent) {
appDidLoad();
}
}
}
else {
endPostUpdate();
}
// load events fire from bottom to top
// the deepest elements load first then bubbles up
{
if (hostRef.$onRenderResolve$) {
hostRef.$onRenderResolve$();
hostRef.$onRenderResolve$ = undefined;
}
if (hostRef.$flags$ & 512 /* needsRerender */) {
nextTick(() => scheduleUpdate(hostRef));
}
hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
}
// ( •_•)
// ( •_•)>⌐■-■
// (⌐■_■)
};
const appDidLoad = (who) => {
// on appload
// we have finish the first big initial render
{
addHydratedFlag(doc.documentElement);
}
nextTick(() => emitEvent(win, 'appload', { detail: { namespace: NAMESPACE } }));
};
const safeCall = (instance, method, arg) => {
if (instance && instance[method]) {
try {
return instance[method](arg);
}
catch (e) {
consoleError(e);
}
}
return undefined;
};
const then = (promise, thenFn) => {
return promise && promise.then ? promise.then(thenFn) : thenFn();
};
const addHydratedFlag = (elm) => elm.classList.add('hydrated')
;
const proxyComponent = (Cstr, cmpMeta, flags) => {
return Cstr;
};
const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId, Cstr) => {
// initializeComponent
if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
{
// we haven't initialized this element yet
hostRef.$flags$ |= 32 /* hasInitializedComponent */;
// lazy loaded components
// request the component's implementation to be
// wired up with the host element
Cstr = loadModule(cmpMeta);
if (Cstr.then) {
// Await creates a micro-task avoid if possible
const endLoad = uniqueTime();
Cstr = await Cstr;
endLoad();
}
const endNewInstance = createTime('createInstance', cmpMeta.$tagName$);
// construct the lazy-loaded component implementation
// passing the hostRef is very important during
// construction in order to directly wire together the
// host element and the lazy-loaded instance
try {
new Cstr(hostRef);
}
catch (e) {
consoleError(e);
}
endNewInstance();
fireConnectedCallback(hostRef.$lazyInstance$);
}
}
// we've successfully created a lazy instance
const ancestorComponent = hostRef.$ancestorComponent$;
const schedule = () => scheduleUpdate(hostRef);
if (ancestorComponent && ancestorComponent['s-rc']) {
// this is the intial load and this component it has an ancestor component
// but the ancestor component has NOT fired its will update lifecycle yet
// so let's just cool our jets and wait for the ancestor to continue first
// this will get fired off when the ancestor component
// finally gets around to rendering its lazy self
// fire off the initial update
ancestorComponent['s-rc'].push(schedule);
}
else {
schedule();
}
};
const fireConnectedCallback = (instance) => {
{
safeCall(instance, 'connectedCallback');
}
};
const connectedCallback = (elm) => {
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
const hostRef = getHostRef(elm);
const cmpMeta = hostRef.$cmpMeta$;
const endConnected = createTime('connectedCallback', cmpMeta.$tagName$);
if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
// first time this component has connected
hostRef.$flags$ |= 1 /* hasConnected */;
{
// find the first ancestor component (if there is one) and register
// this component as one of the actively loading child components for its ancestor
let ancestorComponent = elm;
while ((ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host)) {
// climb up the ancestors looking for the first
// component that hasn't finished its lifecycle update yet
if (ancestorComponent['s-p']) {
// we found this components first ancestor component
// keep a reference to this component's ancestor component
attachToAncestor(hostRef, (hostRef.$ancestorComponent$ = ancestorComponent));
break;
}
}
}
{
initializeComponent(elm, hostRef, cmpMeta);
}
}
else {
// fire off connectedCallback() on component instance
fireConnectedCallback(hostRef.$lazyInstance$);
}
endConnected();
}
};
const disconnectedCallback = (elm) => {
if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
const hostRef = getHostRef(elm);
const instance = hostRef.$lazyInstance$ ;
{
safeCall(instance, 'disconnectedCallback');
}
}
};
const bootstrapLazy = (lazyBundles, options = {}) => {
const endBootstrap = createTime();
const cmpTags = [];
const exclude = options.exclude || [];
const customElements = win.customElements;
const head = doc.head;
const metaCharset = /*@__PURE__*/ head.querySelector('meta[charset]');
const visibilityStyle = /*@__PURE__*/ doc.createElement('style');
const deferredConnectedCallbacks = [];
let appLoadFallback;
let isBootstrapping = true;
Object.assign(plt, options);
plt.$resourcesUrl$ = new URL(options.resourcesUrl || './', doc.baseURI).href;
lazyBundles.map((lazyBundle) => lazyBundle[1].map((compactMeta) => {
const cmpMeta = {
$flags$: compactMeta[0],
$tagName$: compactMeta[1],
$members$: compactMeta[2],
$listeners$: compactMeta[3],
};
const tagName = cmpMeta.$tagName$;
const HostElement = class extends HTMLElement {
// StencilLazyHost
constructor(self) {
// @ts-ignore
super(self);
self = this;
registerHost(self, cmpMeta);
}
connectedCallback() {
if (appLoadFallback) {
clearTimeout(appLoadFallback);
appLoadFallback = null;
}
if (isBootstrapping) {
// connectedCallback will be processed once all components have been registered
deferredConnectedCallbacks.push(this);
}
else {
plt.jmp(() => connectedCallback(this));
}
}
disconnectedCallback() {
plt.jmp(() => disconnectedCallback(this));
}
componentOnReady() {
return getHostRef(this).$onReadyPromise$;
}
};
cmpMeta.$lazyBundleId$ = lazyBundle[0];
if (!exclude.includes(tagName) && !customElements.get(tagName)) {
cmpTags.push(tagName);
customElements.define(tagName, proxyComponent(HostElement));
}
}));
{
visibilityStyle.innerHTML = cmpTags + HYDRATED_CSS;
visibilityStyle.setAttribute('data-styles', '');
head.insertBefore(visibilityStyle, metaCharset ? metaCharset.nextSibling : head.firstChild);
}
// Process deferred connectedCallbacks now all components have been registered
isBootstrapping = false;
if (deferredConnectedCallbacks.length) {
deferredConnectedCallbacks.map((host) => host.connectedCallback());
}
else {
{
plt.jmp(() => (appLoadFallback = setTimeout(appDidLoad, 30)));
}
}
// Fallback appLoad event
endBootstrap();
};
const getAssetPath = (path) => {
const assetUrl = new URL(path, plt.$resourcesUrl$);
return assetUrl.origin !== win.location.origin ? assetUrl.href : assetUrl.pathname;
};
const hostRefs = new WeakMap();
const getHostRef = (ref) => hostRefs.get(ref);
const registerInstance = (lazyInstance, hostRef) => hostRefs.set((hostRef.$lazyInstance$ = lazyInstance), hostRef);
const registerHost = (elm, cmpMeta) => {
const hostRef = {
$flags$: 0,
$hostElement$: elm,
$cmpMeta$: cmpMeta,
$instanceValues$: new Map(),
};
{
hostRef.$onReadyPromise$ = new Promise((r) => (hostRef.$onReadyResolve$ = r));
elm['s-p'] = [];
elm['s-rc'] = [];
}
return hostRefs.set(elm, hostRef);
};
const isMemberInElement = (elm, memberName) => memberName in elm;
const consoleError = (e, el) => (0, console.error)(e, el);
const cmpModules = /*@__PURE__*/ new Map();
const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
// loadModuleImport
const exportName = cmpMeta.$tagName$.replace(/-/g, '_');
const bundleId = cmpMeta.$lazyBundleId$;
const module = cmpModules.get(bundleId) ;
if (module) {
return module[exportName];
}
return import(
/* webpackInclude: /\.entry\.js$/ */
/* webpackExclude: /\.system\.entry\.js$/ */
/* webpackMode: "lazy" */
`./${bundleId}.entry.js${''}`).then((importedModule) => {
{
cmpModules.set(bundleId, importedModule);
}
return importedModule[exportName];
}, consoleError);
};
const queueDomReads = [];
const queueDomWrites = [];
const queueTask = (queue, write) => (cb) => {
queue.push(cb);
if (!queuePending) {
queuePending = true;
if (write && plt.$flags$ & 4 /* queueSync */) {
nextTick(flush);
}
else {
plt.raf(flush);
}
}
};
const consume = (queue) => {
for (let i = 0; i < queue.length; i++) {
try {
queue[i](performance.now());
}
catch (e) {
consoleError(e);
}
}
queue.length = 0;
};
const flush = () => {
// always force a bunch of medium callbacks to run, but still have
// a throttle on how many can run in a certain time
// DOM READS!!!
consume(queueDomReads);
// DOM WRITES!!!
{
consume(queueDomWrites);
if ((queuePending = queueDomReads.length > 0)) {
// still more to do yet, but we've run out of time
// let's let this thing cool off and try again in the next tick
plt.raf(flush);
}
}
};
const nextTick = /*@__PURE__*/ (cb) => promiseResolve().then(cb);
const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
export { bootstrapLazy as b, getAssetPath as g, h, promiseResolve as p, registerInstance as r };