@nent/core
Version:
199 lines (193 loc) • 6.02 kB
JavaScript
/*!
* NENT 2022
*/
import { proxyCustomElement, HTMLElement, createEvent } from '@stencil/core/internal/client';
import { w as warn } from './logging.js';
import { M as Mutex } from './mutex.js';
import { c as createStore } from './index3.js';
var ReferenceType;
(function (ReferenceType) {
ReferenceType["script"] = "script";
ReferenceType["styles"] = "styles";
})(ReferenceType || (ReferenceType = {}));
/* istanbul ignore file */
class StateModel {
}
const store = createStore({
references: [],
cache: {},
});
const { state, onChange, reset, dispose } = store;
const collectionMutex = new Mutex();
/**
* It returns true if the given url is in the list of references
* @param {string} url - The URL of the reference to check for.
* @returns A boolean value.
*/
async function hasReference(url) {
return await collectionMutex.dispatch(async () => {
return state.references.includes(url);
});
}
/**
* It takes a URL, adds it to the list of references, and returns a promise that resolves when the
* operation is complete
* @param {string} url - The URL of the reference to mark.
* @returns A promise that resolves to the result of the function passed to dispatch.
*/
async function markReference(url) {
return await collectionMutex.dispatch(async () => {
state.references = [
...new Set([...state.references, url]),
];
});
}
/**
* It clears the references to the objects in the `references` array.
*/
async function clearReferences() {
return await collectionMutex.dispatch(async () => {
state.references = [];
});
}
const ContentReference = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.reference = createEvent(this, "referenced", 6);
/**
* Import the script file as a module.
*/
this.module = false;
/**
* Declare the script only for use when
* modules aren't supported
*/
this.noModule = false;
/**
* When inline the link/script tags are rendered in-place
* rather than added to the head.
*/
this.inline = false;
/**
* If set, disables auto-rendering of this instance.
* To fetch the contents change to false or remove
* attribute.
*/
this.deferLoad = false;
/**
* Timeout (in milliseconds) to wait for the references
* to load.
*/
this.timeout = 1000;
}
/**
* Force the 'load' event of the script or link element.
* This is meant for testing.
*
*/
async forceLoad() {
var _a, _b;
(_a = this.scriptElement) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new CustomEvent('load'));
(_b = this.linkElement) === null || _b === void 0 ? void 0 : _b.dispatchEvent(new CustomEvent('load'));
}
registered(type, loaded) {
this.reference.emit({ type, loaded });
}
async getStylePromise(element) {
const url = this.styleSrc;
return new Promise(async (resolve) => {
if (url == undefined) {
return resolve(false);
}
const reffed = await hasReference(url);
if (reffed) {
return resolve(true);
}
this.linkElement = this.el.ownerDocument.createElement('link');
this.linkElement.href = url;
this.linkElement.rel = 'stylesheet';
let loaded = false;
this.linkElement.addEventListener('load', async () => {
loaded = true;
return resolve(loaded);
});
element.append(this.linkElement);
await markReference(url);
setTimeout(() => {
if (!loaded) {
warn(`Stylesheet '${url}' did not load before the ${this.timeout} timeout.`);
resolve(false);
}
}, this.timeout);
});
}
getScriptPromise(element) {
const url = this.scriptSrc;
return new Promise(async (resolve) => {
if (url == undefined) {
return resolve(false);
}
const reffed = await hasReference(url);
if (reffed) {
return resolve(true);
}
this.scriptElement =
this.el.ownerDocument.createElement('script');
this.scriptElement.src = url;
let loaded = false;
if (this.module) {
this.scriptElement.type = 'module';
}
else if (this.noModule) {
this.scriptElement.setAttribute('nomodule', '');
}
this.scriptElement.addEventListener('load', async () => {
loaded = true;
await markReference(url);
return resolve(loaded);
});
element.append(this.scriptElement);
await markReference(url);
setTimeout(() => {
if (!loaded) {
warn(`Script '${url}' did not load before the ${this.timeout} timeout.`);
resolve(false);
}
}, this.timeout);
});
}
async componentWillRender() {
if (this.deferLoad) {
return;
}
const element = this.inline ? this.el : this.el.ownerDocument.head;
await this.getStylePromise(element).then(loaded => this.registered(ReferenceType.styles, loaded));
await this.getScriptPromise(element).then(loaded => this.registered(ReferenceType.script, loaded));
}
disconnectedCallback() { }
get el() { return this; }
}, [0, "n-content-reference", {
"styleSrc": [1, "style-src"],
"scriptSrc": [1, "script-src"],
"module": [4],
"noModule": [4, "no-module"],
"inline": [4],
"deferLoad": [1028, "defer-load"],
"timeout": [2],
"forceLoad": [64]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["n-content-reference"];
components.forEach(tagName => { switch (tagName) {
case "n-content-reference":
if (!customElements.get(tagName)) {
customElements.define(tagName, ContentReference);
}
break;
} });
}
export { ContentReference as C, ReferenceType as R, StateModel as S, state as a, defineCustomElement as b, clearReferences as c, dispose as d, hasReference as h, markReference as m, onChange as o, reset as r, store as s };