@7x7cl/qwik
Version:
An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.
124 lines • 5.86 kB
JavaScript
(() => {
((doc, hasInitialized) => {
const win = window;
const events = new Set;
const querySelectorAll = query => doc.querySelectorAll(query);
const broadcast = (infix, ev, type = ev.type) => {
querySelectorAll("[on" + infix + "\\:" + type + "]").forEach((target => dispatch(target, infix, ev, type)));
};
const getAttribute = (el, name) => el.getAttribute(name);
const resolveContainer = containerEl => {
if (void 0 === containerEl._qwikjson_) {
let script = (containerEl === doc.documentElement ? doc.body : containerEl).lastElementChild;
while (script) {
if ("SCRIPT" === script.tagName && "qwik/json" === getAttribute(script, "type")) {
containerEl._qwikjson_ = JSON.parse(script.textContent.replace(/\\x3C(\/?script)/g, "<$1"));
break;
}
script = script.previousElementSibling;
}
}
};
const createEvent = (eventName, detail) => new CustomEvent(eventName, {
detail: detail
});
const dispatch = async (element, onPrefix, ev, eventName = ev.type) => {
const attrName = "on" + onPrefix + ":" + eventName;
element.hasAttribute("preventdefault:" + eventName) && ev.preventDefault();
const ctx = element._qc_;
const qrls = null == ctx ? void 0 : ctx.li.filter((li => li[0] === attrName));
if (qrls && qrls.length > 0) {
for (const q of qrls) {
await q[1].getFn([ element, ev ], (() => element.isConnected))(ev, element);
}
return;
}
const attrValue = getAttribute(element, attrName);
if (attrValue) {
const container = element.closest("[q\\:container]");
const base = new URL(getAttribute(container, "q:base"), doc.baseURI);
for (const qrl of attrValue.split("\n")) {
const url = new URL(qrl, base);
const symbolName = url.hash.replace(/^#?([^?[|]*).*$/, "$1") || "default";
const reqTime = performance.now();
const module = import(url.href.split("#")[0]);
resolveContainer(container);
const handler = (await module)[symbolName];
const previousCtx = doc.__q_context__;
if (element.isConnected) {
try {
doc.__q_context__ = [ element, ev, url ];
emitEvent("qsymbol", {
symbol: symbolName,
element: element,
reqTime: reqTime
});
await handler(ev, element);
} finally {
doc.__q_context__ = previousCtx;
}
}
}
}
};
const emitEvent = (eventName, detail) => {
doc.dispatchEvent(createEvent(eventName, detail));
};
const camelToKebab = str => str.replace(/([A-Z])/g, (a => "-" + a.toLowerCase()));
const processDocumentEvent = async ev => {
let type = camelToKebab(ev.type);
let element = ev.target;
broadcast("-document", ev, type);
while (element && element.getAttribute) {
await dispatch(element, "", ev, type);
element = ev.bubbles && !0 !== ev.cancelBubble ? element.parentElement : null;
}
};
const processWindowEvent = ev => {
broadcast("-window", ev, camelToKebab(ev.type));
};
const processReadyStateChange = () => {
var _a;
const readyState = doc.readyState;
if (!hasInitialized && ("interactive" == readyState || "complete" == readyState)) {
hasInitialized = 1;
emitEvent("qinit");
(null != (_a = win.requestIdleCallback) ? _a : win.setTimeout).bind(win)((() => emitEvent("qidle")));
if (events.has("qvisible")) {
const results = querySelectorAll("[on\\:qvisible]");
const observer = new IntersectionObserver((entries => {
for (const entry of entries) {
if (entry.isIntersecting) {
observer.unobserve(entry.target);
dispatch(entry.target, "", createEvent("qvisible", entry));
}
}
}));
results.forEach((el => observer.observe(el)));
}
}
};
const addEventListener = (el, eventName, handler, capture = !1) => el.addEventListener(eventName, handler, {
capture: capture,
passive: !1
});
const push = eventNames => {
for (const eventName of eventNames) {
if (!events.has(eventName)) {
addEventListener(doc, eventName, processDocumentEvent, !0);
addEventListener(win, eventName, processWindowEvent);
events.add(eventName);
}
}
};
if (!doc.qR) {
const qwikevents = win.qwikevents;
Array.isArray(qwikevents) && push(qwikevents);
win.qwikevents = {
push: (...e) => push(e)
};
addEventListener(doc, "readystatechange", processReadyStateChange);
processReadyStateChange();
}
})(document);
})();