-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsco-pe.min.js.map
7 lines (7 loc) · 44.4 KB
/
sco-pe.min.js.map
1
2
3
4
5
6
7
{
"version": 3,
"sources": ["src/Scope.js", "sco-pe.js"],
"sourcesContent": ["/**\n * @callback ConfirmCallback\n * @param {String} message\n * @returns {Promise}\n */\n\n/**\n * @callback LoadCallback\n * @param {Scope} scope\n * @returns {void}\n */\n\n/**\n * @callback StatusCallback\n * @param {String} message\n * @param {Number} statusCode\n * @returns {void}\n */\n\n/**\n * @typedef Script\n * @property {String} src\n * @property {String} type\n * @property {String} [id]\n */\n\n/**\n * @typedef InlineScript\n * @property {String} content\n * @property {String} type\n * @property {String} [id]\n */\n\n/**\n * @typedef ScopeConfig\n * @property {Boolean} debug\n * @property {Number} loadDelay\n * @property {String} activeClass\n * @property {String} fakeLocationHeader\n * @property {String} reloadHeader\n * @property {String} titleHeader\n * @property {String} styleHeader\n * @property {String} scriptHeader\n * @property {ConfirmCallback} confirmHandler\n * @property {String} statusHeader\n * @property {StatusCallback} statusHandler\n * @property {LoadCallback} onLoad\n * @property {LoadCallback} onScopeLoad\n */\nlet config = {\n debug: false,\n loadDelay: 300,\n activeClass: \"active\",\n fakeLocationHeader: \"X-Location\",\n reloadHeader: \"X-Reload\",\n titleHeader: \"X-Title\",\n cssHeader: \"X-Include-CSS\",\n jsHeader: \"X-include-JS\",\n confirmHandler: (message) => {\n return new Promise((resolve, reject) => {\n if (confirm(message)) {\n resolve();\n } else {\n reject();\n }\n });\n },\n statusHeader: \"X-Status\",\n statusHandler: (message, statusCode) => {\n alert(message);\n },\n progressHandler: (scope, step) => {},\n onLoad: (scope) => {},\n onScopeLoad: (scope) => {},\n};\n\n/**\n * @type {AbortController}\n */\nlet globalAbortController = null;\n\n/**\n * @type {Array<InlineScript>}\n */\nlet pendingInlineScripts = [];\n\n/**\n * @type {Boolean}\n */\nlet allScriptsLoaded = true;\n\n/**\n * @type {Array<Script>}\n */\nlet pendingExternalScripts = [];\n\n/**\n * @type {Boolean}\n */\nlet allScopesLoaded = false;\n\nlet scopesLoadingTimeout;\n\n/**\n * @param {HTMLElement} el\n * @returns {Array}\n */\nfunction getEvents(el) {\n if (el instanceof HTMLFormElement) {\n return [\"submit\"];\n }\n const ev = el.dataset.scopeOn || \"click\";\n return ev.split(\",\");\n}\n\n/**\n * @param {HTMLElement} el\n * @returns {String}\n */\nfunction getAction(el) {\n return el.getAttribute(\"action\") || el.dataset.scopeAction || el.getAttribute(\"href\");\n}\n\n/**\n * @param {HTMLElement} el\n * @returns {Boolean}\n */\nfunction ignoreElement(el) {\n const action = getAction(el);\n return !action || hasBlankTarget(el) || isExternalURL(action) || isAnchorURL(action);\n}\n\n/**\n * @param {Function} func\n * @param {number} timeout\n * @returns {Function}\n */\nfunction debounce(func, timeout = 300) {\n let timer;\n return (...args) => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n //@ts-ignore\n func.apply(this, args);\n }, timeout);\n };\n}\n\n/**\n * @param {Function} func\n * @param {number} timeFrame\n * @returns {Function}\n */\n// function throttle(func, timeFrame = 300) {\n// var lastTime = 0;\n// return (...args) => {\n// var now = Date.now();\n// if (now - lastTime >= timeFrame) {\n// //@ts-ignore\n// func.apply(this, args);\n// lastTime = now;\n// }\n// };\n// }\n\n/**\n * @param {*} v\n * @returns {Boolean}\n */\nfunction parseBool(v) {\n return [\"1\", \"true\", true, 1].includes(v);\n}\n\n/**\n * @param {HTMLElement} el\n * @param {HTMLElement} parentScope\n * @returns {Boolean}\n */\nfunction getHistory(el, parentScope = null) {\n let history = \"true\";\n if (el.dataset.scopeHistory) {\n history = el.dataset.scopeHistory;\n } else if (parentScope && parentScope.dataset.scopeHistory) {\n history = parentScope.dataset.scopeHistory;\n }\n return parseBool(history);\n}\n\n/**\n * @param {String} html\n * @return {Document}\n */\nfunction htmlToDocument(html) {\n const parser = new DOMParser();\n return parser.parseFromString(html, \"text/html\");\n}\n\n/**\n * @param {String} html\n * @return {DocumentFragment}\n */\nfunction htmlFragment(html) {\n const temp = document.createElement(\"template\");\n temp.innerHTML = html;\n return temp.content;\n}\n\n/**\n * @param {DocumentFragment|Document} fragment\n * @returns {String}\n */\nfunction fragmentToString(fragment) {\n const div = document.createElement(\"div\");\n div.appendChild(fragment);\n return div.innerHTML;\n}\n\n/**\n * @param {Element} node\n * @returns {Boolean}\n */\nfunction isNodeEmpty(node) {\n return node.textContent.trim() === \"\" && !node.firstElementChild;\n}\n\n/**\n * @param {String|URL} url\n * @returns {URL}\n */\nfunction expandURL(url) {\n const str = url ? url.toString() : \"#\";\n return new URL(str, document.baseURI);\n}\n\n/**\n * @param {String|URL} url\n * @returns {String}\n */\nfunction removeAnchorFromURL(url) {\n return expandURL(url).href.split(\"#\")[0];\n}\n\n/**\n * @param {String|URL} url\n * @returns {Boolean}\n */\nfunction isExternalURL(url) {\n if (!url) {\n return false;\n }\n return expandURL(url).origin !== location.origin;\n}\n\n/**\n * @param {HTMLElement} el\n * @returns {Boolean}\n */\nfunction hasBlankTarget(el) {\n return el.getAttribute(\"target\") === \"_blank\";\n}\n\n/**\n * @param {URL} url\n * @returns {String}\n */\nfunction getAnchor(url) {\n if (!url) {\n return null;\n }\n let anchorMatch;\n if (url.hash) {\n return url.hash.slice(1);\n } else if ((anchorMatch = url.href.match(/#(.*)$/))) {\n return anchorMatch[1];\n }\n return null;\n}\n\n/**\n * @param {String|URL} url\n * @returns {Boolean}\n */\nfunction isAnchorURL(url) {\n return getAnchor(expandURL(url)) !== null;\n}\n\n/**\n * @param {String} str\n * @returns {String}\n */\nfunction simpleHash(str) {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash &= hash; // Convert to 32bit integer\n }\n return new Uint32Array([hash])[0].toString(36);\n}\n\n/**\n * @param {HTMLElement} el\n * @returns {HTMLElement}\n */\nfunction getScrollParent(el) {\n if (el === null) {\n return null;\n }\n if (el.scrollHeight > el.clientHeight) {\n return el;\n }\n return getScrollParent(el.parentElement);\n}\n\n/**\n * @param {HTMLElement} el\n */\nfunction scrollIntoParentView(el) {\n const parent = getScrollParent(el);\n if (parent) {\n parent.scrollTop = 0;\n } else {\n el.scrollIntoView(true);\n }\n}\n\n/**\n * @param {String} message\n */\nfunction log(message) {\n if (config.debug) {\n console.log(`[sco-pe] ${message}`);\n }\n}\n\n/**\n * @param {HTMLElement} o\n * @param {HTMLElement} n\n * @returns {Boolean}\n */\nfunction hasDomChanged(o, n) {\n // filter out custom elements that most of the time inject their own logic, actives classes, spaces and styles\n const regex = new RegExp(`<[a-z]+-[a-z]+.*>.*<\\/[a-z]+-[a-z]+>|${config.activeClass}|\\\\s+|style=\".*?\"`, \"gmi\");\n const fo = o.innerHTML.replace(regex, \"\").trim();\n const fn = n.innerHTML.replace(regex, \"\").trim();\n return fo != fn;\n}\n\n/**\n * @param {HTMLElement} o\n * @param {HTMLElement} n\n */\nfunction replaceDom(o, n) {\n const fragments = o.querySelectorAll(\"[data-scope-fragment]\");\n // No fragments, replace the whole thing\n if (!fragments.length) {\n log(`Replacing ${o.id} content`);\n o.innerHTML = n.innerHTML;\n return;\n }\n // Replace only if changed\n fragments.forEach(\n /**\n * @param {HTMLElement} fragment\n */\n (fragment) => {\n const sel = fragment.id ? `#${fragment.id}` : `.${fragment.classList.item(0)}`;\n /**\n * @type {HTMLElement}\n */\n const nid = n.querySelector(sel);\n if (nid) {\n const v = fragment.dataset.scopeFragment;\n // You can use a hash value if your html has mutated and cannot be reliably compared with isEqualNode\n const isChanged = v.length > 0 ? v != nid.dataset.scopeFragment : !fragment.isEqualNode(nid);\n if (isChanged) {\n log(`Replacing ${sel} fragment`);\n fragment.innerHTML = nid.innerHTML;\n }\n } else if (!fragment.dataset.scopedFixed) {\n fragment.remove();\n }\n }\n );\n}\n\n/**\n * @param {RequestInfo | URL} url\n * @param {RequestInit} options\n * @returns {Promise<Response>}\n */\nfunction justFetch(url, options) {\n options = options || {};\n options.headers = options.headers || {};\n options.headers[\"X-Requested-With\"] = \"XMLHttpRequest\";\n if (!options.referrerPolicy) {\n options.referrerPolicy = \"no-referrer-when-downgrade\";\n }\n return fetch(url, options);\n}\n\n/**\n * @param {String} str\n * @returns {String}\n */\nfunction decodeURIPlus(str) {\n return decodeURI(str.replace(/\\+/g, \" \"));\n}\n\n// Restore state or make a full page load on back\nwindow.addEventListener(\"popstate\", async (event) => {\n let scopeNotFound = false;\n if (event.state) {\n const state = event.state.scope || null;\n if (state) {\n const id = state.id;\n const url = state.url;\n /**\n * @type {Scope}\n */\n const scope = document.querySelector(`sco-pe[id=\"${id}\"]`);\n if (scope) {\n log(`Restore location from history`);\n await scope.loadURL(url, {}, state.hint);\n return;\n } else {\n scopeNotFound = true;\n }\n }\n }\n\n // Do a full page load\n if (event.state === null || scopeNotFound) {\n window.location.replace(document.location.toString());\n }\n});\n\nclass Scope extends HTMLElement {\n constructor() {\n super();\n\n /**\n * @type {AbortController}\n */\n this.abortController = null;\n /**\n * @type {Boolean}\n */\n this.init = false;\n /**\n * @type {Array}\n */\n this.events = [\"click\", \"submit\"];\n /**\n * @type {Function}\n */\n this.loadFunc = debounce((trigger, ev) => {\n this.load(trigger, ev);\n }, config.loadDelay);\n }\n\n /**\n * @param {ScopeConfig|Object} data\n */\n static configure(data) {\n config = Object.assign(config, data);\n }\n\n handleEvent(ev) {\n // Check for nested scope\n if (ev.target.closest(\"sco-pe\") !== this) {\n return;\n }\n\n // Don't handle events if disabled\n if (parseBool(this.dataset.scopeDisabled)) {\n return;\n }\n\n /**\n * @type {HTMLElement}\n */\n let trigger = ev.target.closest(\"a,button,[data-scope-action]\");\n\n // A submit action means form submit\n if (ev.type === \"submit\") {\n trigger = ev.target;\n }\n\n if (trigger) {\n const events = getEvents(trigger);\n // Ignore events that we don't watch\n if (!events.includes(ev.type)) {\n return;\n }\n // Ignore empty, external and anchors links\n if (ignoreElement(trigger)) {\n return;\n }\n log(`Handling ${ev.type} on ${trigger.nodeName}`);\n ev.preventDefault();\n\n const debounced = [\"input\", \"scroll\", \"resize\", \"mousemove\", \"touchmove\", \"keyup\", \"keydown\"];\n const load = () => {\n if (debounced.includes(ev.type)) {\n this.loadFunc(trigger, ev);\n } else {\n this.load(trigger, ev);\n }\n };\n // Check confirm ?\n if (trigger.dataset.scopeConfirm) {\n config\n .confirmHandler(trigger.dataset.scopeConfirm)\n .then(load)\n .catch((err) => null);\n } else {\n load();\n }\n }\n }\n\n abortLoading() {\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /**\n * @param {HTMLElement} el\n * @param {SubmitEvent} ev\n */\n async load(el, ev) {\n // Build url\n let action = getAction(el);\n let url = expandURL(action).href;\n let urlWithParams = url;\n const isLink = el.nodeName === \"A\" || el.dataset.scopeLink; // a link or behave like a link\n /**\n * @type {HTMLButtonElement}\n */\n //@ts-ignore\n const submitter = ev.submitter || null;\n\n // helps to determine fetch target, this by default\n const hint = el.dataset.scopeHint || this.dataset.scopeHint;\n const method = (el.getAttribute(\"method\") || el.dataset.scopeMethod || \"GET\").toUpperCase();\n // Update history for links for named scopes\n let pushToHistory = isLink && getHistory(el, this) && this.hasAttribute(\"id\");\n let postBody;\n\n // Forms need some love\n if (submitter) {\n submitter.setAttribute(\"disabled\", \"\");\n }\n\n // Pass along current query string and params for elements with value\n const searchParams = new URLSearchParams(window.location.search);\n //@ts-ignore\n const elValue = el.value !== \"undefined\" ? el.value : el.dataset.scopeValue;\n if (typeof elValue !== \"undefined\") {\n searchParams.set(\"value\", elValue);\n urlWithParams = `${url}?${searchParams.toString()}`;\n postBody = searchParams;\n }\n\n // Pass form data\n if (el instanceof HTMLFormElement) {\n const formData = new FormData(el);\n // Pass clicked action\n if (submitter) {\n formData.append(submitter.name, submitter.value || \"true\");\n }\n // Track hash when submitting a form\n this._hash = formData.get(\"_hash\");\n postBody = formData;\n }\n\n // Do we target a specific scope ?\n // Always use GET request for sco-pe requests and delegate loading to instance\n const target = el.dataset.scopeTarget || this.dataset.scopeTarget;\n if (target && target !== \"_self\") {\n log(`Loading into targeted scope ${target}`);\n document.getElementById(target).setAttribute(\"src\", urlWithParams);\n return;\n }\n\n if (method === \"GET\") {\n url = urlWithParams;\n }\n const body = method === \"POST\" ? postBody : null;\n\n // Show progress bar\n config.progressHandler(this, \"start\");\n\n const result = await this.loadURL(\n url,\n {\n method,\n body,\n },\n hint\n );\n\n // Update AFTER loading otherwise you mess up the refer(r)er\n if (pushToHistory && !result.error) {\n const historyUrl = result.redirected || url;\n this.updateHistory(historyUrl, hint);\n }\n\n // Set active based on updated URL\n if (isLink) {\n this.removeActiveClass();\n this.setActive(el);\n this._markActive();\n }\n\n if (submitter) {\n submitter.removeAttribute(\"disabled\");\n }\n\n if (!result.aborted) {\n config.progressHandler(this, \"done\");\n }\n }\n\n updateHistory(url, hint) {\n // Don't push if same url\n if (history.state) {\n const prevUrl = history.state.scope && history.state.scope.url;\n if (removeAnchorFromURL(prevUrl) == removeAnchorFromURL(url)) {\n return;\n }\n }\n const id = this.getAttribute(\"id\");\n const state = {\n id,\n url,\n hint,\n };\n history.pushState(\n {\n scope: state,\n },\n null,\n url\n );\n }\n\n /**\n * @param {HTMLElement} el\n */\n setActive(el) {\n log(`Set active element`);\n el.classList.add(config.activeClass);\n }\n\n removeActiveClass() {\n this.querySelectorAll(`.${config.activeClass}`).forEach(\n /**\n * @param {HTMLElement} el\n */\n (el) => {\n if (ignoreElement(el)) {\n return;\n }\n if (el === document.activeElement) {\n el.blur();\n }\n el.classList.remove(config.activeClass);\n }\n );\n }\n\n /**\n * @param {String} url\n * @param {Object} fetchOptions\n * @param {String} hint\n * @returns {Promise<Object>}\n */\n async loadURL(url, fetchOptions = {}, hint = null) {\n if (!fetchOptions.signal) {\n log(`GET ${url}`);\n // If not targeting a specific scope, we use a global context\n if (globalAbortController) {\n globalAbortController.abort();\n }\n globalAbortController = new AbortController();\n fetchOptions.signal = globalAbortController.signal;\n }\n const options = Object.assign(\n {\n method: \"GET\",\n },\n fetchOptions\n );\n\n try {\n const response = await justFetch(url, options);\n\n // Get error message from headers or response\n if (!response.ok) {\n const message = response.headers.get(config.statusHeader) || response.statusText;\n config.statusHandler(message, response.status);\n return {\n error: message,\n };\n }\n\n this._processHeaders(response);\n // Fake redirect can read statuses\n if (config.fakeLocationHeader) {\n const location = response.headers.get(config.fakeLocationHeader);\n if (location) {\n await this.loadURL(location);\n return {\n redirected: location,\n };\n }\n }\n const data = await response.text();\n this._processResponse(data);\n\n if (response.redirected) {\n return {\n redirected: response.url,\n };\n }\n } catch (error) {\n // Deal with network errors\n //@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#aborting_a_fetch_with_timeout_or_explicit_abort\n if (error.name === \"AbortError\") {\n // The user knows he aborted, no notification\n } else {\n config.statusHandler(error.message);\n }\n return {\n error: error.message,\n aborted: error.name === \"AbortError\",\n };\n }\n return {};\n }\n\n /**\n * @param {Response} response\n */\n _processHeaders(response) {\n if (config.statusHeader) {\n const status = response.headers.get(config.statusHeader);\n if (status) {\n config.statusHandler(decodeURIPlus(status), response.status);\n }\n }\n if (config.titleHeader) {\n const title = response.headers.get(config.titleHeader);\n if (title) {\n document.title = decodeURIPlus(title);\n }\n }\n if (config.reloadHeader) {\n const reload = response.headers.get(config.reloadHeader);\n if (reload) {\n window.location.reload();\n }\n }\n if (config.jsHeader) {\n const js = response.headers.get(config.jsHeader);\n if (js) {\n js.split(\",\").forEach((src) => {\n this._loadScript(src);\n });\n }\n }\n if (config.cssHeader) {\n const css = response.headers.get(config.cssHeader);\n if (css) {\n css.split(\",\").forEach((src) => {\n this._loadStyle(src);\n });\n }\n }\n }\n\n /**\n * @param {HTMLHeadElement} head\n */\n _processHead(head) {\n log(`Process head`);\n\n // Update title\n const title = head.querySelector(\"title\");\n if (title) {\n document.title = title.textContent;\n }\n }\n\n /**\n * @param {HTMLBodyElement} body\n */\n _processBody(body) {\n document.body.style.cssText = body.style.cssText;\n const attrs = [\"class\"];\n attrs.forEach((attr) => {\n document.body.setAttribute(attr, body.getAttribute(attr) || \"\");\n });\n }\n /**\n * @param {Document} doc\n */\n _processDocument(doc) {\n const attrs = [\"class\"];\n attrs.forEach((attr) => {\n document.documentElement.setAttribute(attr, doc.documentElement.getAttribute(attr) || \"\");\n });\n\n for (const d in doc.documentElement.dataset) {\n document.documentElement.dataset[d] = doc.documentElement.dataset[d];\n }\n }\n\n /**\n * @param {String} src\n * @param {String} type\n * @returns {Boolean} Is a new script created?\n */\n _loadScript(src, type = \"text/javascript\") {\n const existingScript = document.querySelector(`script[src=\"${src}\"]`);\n if (existingScript) {\n return false;\n }\n log(`Loading script ${src}`);\n\n // This doesn't work\n // const prefetchLink = document.createElement(\"link\");\n // prefetchLink.rel = \"prefetch\";\n // prefetchLink.href = src;\n // document.head.appendChild(prefetchLink);\n\n pendingExternalScripts.push({\n type,\n src,\n });\n return true;\n }\n\n /**\n * Scripts needs to load sequentially to respect dependencies\n */\n _processScriptsQueue() {\n allScriptsLoaded = pendingExternalScripts.length === 0;\n const script = pendingExternalScripts.shift();\n if (allScriptsLoaded) {\n // We need to wait until all scopes are loaded\n if (allScopesLoaded) {\n this._processInlineScriptsQueue();\n }\n log(`All scripts loaded`);\n return;\n }\n const newScript = document.createElement(\"script\");\n newScript.setAttribute(\"type\", script.type);\n newScript.setAttribute(\"src\", script.src);\n newScript.onload = newScript.onerror = (ev) => {\n log(`Loaded script ${script.src}`);\n this._processScriptsQueue();\n };\n document.head.appendChild(newScript);\n }\n\n /**\n * @param {HTMLScriptElement} script\n * @returns\n */\n _loadInlineScript(script) {\n const hash = simpleHash(script.innerHTML);\n const type = script.type || \"text/javascript\";\n const id = script.getAttribute(\"id\") || `script-${hash}`;\n const existingInlineScript = document.querySelector(`script[id=\"${id}\"]`);\n // Inline scripts are always executed except unless they have their own id\n if (existingInlineScript && script.getAttribute(\"id\")) {\n return;\n }\n const content = script.innerHTML;\n // Inline module script are executed immediately and don't respect order, so we need to execute them later\n pendingInlineScripts.push({\n content,\n type,\n id,\n });\n }\n\n /**\n * This can be called either when:\n * - all scripts are loaded (and scopes are already loaded)\n * - all scopes are loaded (and scripts are already loaded)\n *\n * Note! there is no way to know when the inline scripts is executed\n * Therefore, your content cannot rely for example on inline imports\n * since we don't have a load callback\n */\n _processInlineScriptsQueue() {\n log(`Executing ${pendingInlineScripts.length} inline scripts`);\n pendingInlineScripts.forEach((script) => {\n log(`Executing inline script`);\n const inlineScript = document.createElement(\"script\");\n inlineScript.setAttribute(\"type\", script.type);\n inlineScript.setAttribute(\"id\", script.id);\n inlineScript.innerHTML = script.content;\n\n const existingInlineScript = document.querySelector(`script[id=\"${script.id}\"]`);\n // Scripts get executed each time on load\n if (existingInlineScript) {\n existingInlineScript.replaceWith(inlineScript);\n } else {\n document.head.appendChild(inlineScript);\n }\n });\n // Clear the list\n pendingInlineScripts = [];\n\n // Execute global onLoad. It must happen only once per \"load\" event,\n // which can be multiple scopes or only a partial scope\n log(`Calling global onload`);\n config.onLoad(this);\n }\n\n _loadStyle(href) {\n const existingStyle = document.querySelector(`link[href=\"${href}\"]`);\n if (existingStyle) {\n return;\n }\n log(`Loading style ${href}`);\n const newStyle = document.createElement(\"link\");\n newStyle.setAttribute(\"rel\", \"stylesheet\");\n newStyle.setAttribute(\"href\", href);\n document.head.appendChild(newStyle);\n }\n\n /**\n * @param {DocumentFragment} doc\n */\n _processScriptsAndStyles(doc) {\n // Make sure our existing inline scripts & styles have a custom id\n document.querySelectorAll(\"script:not([src]):not([id]),style:not([id])\").forEach(\n /**\n * @param {HTMLScriptElement|HTMLStyleElement} el\n */\n (el) => {\n const hash = simpleHash(el.innerHTML);\n const id = `${el.nodeName.toLowerCase()}-${hash}`;\n el.setAttribute(\"id\", id);\n }\n );\n\n // Append new styles and scripts\n let canTriggerImmediately = true;\n doc.querySelectorAll(\"script\").forEach((script) => {\n if (!script.hasAttribute(\"src\")) {\n this._loadInlineScript(script);\n } else {\n // Use actual attribute, and not .src to avoid changes in url\n const isNew = this._loadScript(script.getAttribute(\"src\"), script.type);\n if (isNew) {\n canTriggerImmediately = false;\n }\n }\n // Cleanup\n script.remove();\n });\n // We have new scripts to process\n if (!canTriggerImmediately) {\n this._processScriptsQueue();\n }\n log(`${pendingInlineScripts.length} pending inline scripts ${canTriggerImmediately ? \"(can trigger immediately)\" : \"\"}`);\n\n // Obviously order can get tricky here, namespace as needed to avoid collisions\n // or avoid scope pollution\n doc.querySelectorAll('style,link[rel=\"stylesheet\"]').forEach((style) => {\n const href = style.getAttribute(\"href\");\n if (!href) {\n // Inline styles get a unique hash based on their content to avoid loading them multiple times\n const hash = simpleHash(style.innerHTML);\n const id = style.getAttribute(\"id\") || `style-${hash}`;\n const existingInlineStyle = document.querySelector(`style[id=\"${id}\"]`);\n if (existingInlineStyle) {\n return;\n }\n log(`Loading inline style`);\n const inlineStyle = document.createElement(\"style\");\n inlineStyle.innerHTML = style.innerHTML;\n inlineStyle.setAttribute(\"id\", id);\n document.head.appendChild(inlineStyle);\n } else {\n this._loadStyle(href);\n }\n });\n }\n\n /**\n * @param {String} data\n */\n _processResponse(data) {\n // The response can be a full html document or a partial document\n const isFull = data.match(/<!doctype\\s+html[\\s>]/i);\n\n // It may contain one or more sco-pe to replace\n const containsScope = data.indexOf(\"<sco-pe\") !== -1;\n\n const tmp = isFull ? htmlToDocument(data) : htmlFragment(data);\n this._processScriptsAndStyles(tmp);\n\n if (isFull || containsScope) {\n log(`Loading scopes ${isFull ? \"(full)\" : \"(partial)\"}`);\n\n const head = tmp.querySelector(\"head\");\n if (head) {\n this._processHead(head);\n }\n const body = tmp.querySelector(\"body\");\n if (body) {\n this._processBody(body);\n }\n\n if (isFull && tmp instanceof Document) {\n this._processDocument(tmp);\n }\n\n const scopes = tmp.querySelectorAll(\"sco-pe\");\n\n // No scopes ? replace body\n if (!scopes.length) {\n document.body.innerHTML = data;\n\n this._checkScopesAreLoaded();\n }\n\n // Scopes are never replaced because maybe we have configured listeners on them\n // We expect that they get the same attributes except src that can change\n scopes.forEach(\n /**\n * @param {Scope} newScope\n */\n (newScope) => {\n const id = newScope.getAttribute(\"id\");\n if (!id) {\n log(`Scope without id`);\n return;\n }\n const src = newScope.getAttribute(\"src\");\n if (isNodeEmpty(newScope) && !src) {\n log(`Empty scope for ${id}`);\n return;\n }\n /**\n * @type {Scope}\n */\n //@ts-ignore\n const oldScope = document.getElementById(id);\n if (!oldScope) {\n log(`No matching scope for ${id}`);\n return;\n }\n if (src && expandURL(src).toString() === expandURL(oldScope.src).toString()) {\n log(`Url has not changed for ${id}`);\n return;\n }\n if (src && src != oldScope.src) {\n log(`Replacing ${id} src`);\n oldScope.src = src;\n // _afterLoad will happen automatically through connectedCallback\n } else {\n if (hasDomChanged(oldScope, newScope)) {\n replaceDom(oldScope, newScope);\n this._afterLoad();\n }\n }\n }\n );\n // Scroll top\n document.scrollingElement.scrollTo(0, 0);\n } else {\n log(`Loading partial document into self (${this.id})`);\n this.innerHTML = fragmentToString(tmp);\n this._afterLoad();\n scrollIntoParentView(this);\n }\n }\n\n /**\n * Load src. You can check if there is server provided content\n * to avoid a fetch request (only used in connectedCallback)\n *\n * @param {Boolean} check Check if there is existing content\n */\n async loadContent(check = false) {\n const fetchingClass = \"scope-fetching\";\n if (this.classList.contains(fetchingClass)) {\n return;\n }\n const src = this.src;\n const preventLoading = check && !isNodeEmpty(this);\n if (src && !preventLoading) {\n this.classList.remove(\"scope-loaded\");\n\n this.abortLoading();\n this.abortController = new AbortController();\n\n this.classList.add(fetchingClass);\n\n await this.loadURL(src, {\n signal: this.abortController.signal,\n });\n\n this.classList.remove(fetchingClass);\n } else {\n this._afterLoad();\n }\n this._markActive();\n }\n\n _markActive() {\n // Mark active class in any link matching href\n let isRemoved = false;\n const baseHref = removeAnchorFromURL(document.location.href).replace(/\\/$/, \"\");\n this.querySelectorAll(`a`).forEach((el) => {\n const href = el.getAttribute(\"href\");\n const url = expandURL(href);\n if (isAnchorURL(url)) {\n return;\n }\n if (url.toString().replace(/\\/$/, \"\") == baseHref) {\n // Only remove if we find another\n if (!isRemoved) {\n this.removeActiveClass();\n isRemoved = true;\n }\n this.setActive(el);\n }\n });\n }\n\n _afterLoad() {\n this._listenToEvents();\n this.classList.add(\"scope-loaded\");\n this.dispatchEvent(new CustomEvent(\"scope-loaded\"));\n config.onScopeLoad(this);\n\n // We have only one callback to avoid calling this multiple times\n this._checkScopesAreLoaded();\n }\n\n _checkScopesAreLoaded() {\n if (scopesLoadingTimeout) {\n clearTimeout(scopesLoadingTimeout);\n }\n scopesLoadingTimeout = setTimeout(() => {\n allScopesLoaded = document.querySelectorAll(\"sco-pe:not(.scope-loaded)\").length === 0;\n if (allScopesLoaded && allScriptsLoaded) {\n this._processInlineScriptsQueue();\n log(`All scripts loaded (no scripts to load)`);\n }\n });\n }\n\n _listenToEvents() {\n // Intercept all relevant events\n this.querySelectorAll(\"[data-scope-on]\").forEach(\n /**\n * @param {HTMLElement} el\n */\n (el) => {\n this.events = this.events.concat(getEvents(el));\n }\n );\n\n this.events.forEach((event) => {\n this.addEventListener(event, this);\n });\n }\n\n static get observedAttributes() {\n return [\"src\"];\n }\n\n set src(v) {\n this.setAttribute(\"src\", v);\n }\n\n get src() {\n return this.getAttribute(\"src\");\n }\n\n attributeChangedCallback(attr, oldVal, newVal) {\n if (!this.init) {\n return;\n }\n switch (attr) {\n case \"src\":\n this.loadContent();\n break;\n }\n }\n\n connectedCallback() {\n // delay execution until the Event Loop is done and all DOM is parsed\n // @link https://stackoverflow.com/questions/70949141/web-components-accessing-innerhtml-in-connectedcallback/75402874\n setTimeout(async () => {\n log(`Scope init ${this.id || \"(no id)\"}`);\n // content can be provided by server rendering, in this case, don't load\n await this.loadContent(true);\n this.init = true;\n log(`Scope created ${this.id || \"(no id)\"}`);\n });\n }\n\n disconnectedCallback() {\n this.events.forEach((event) => {\n this.removeEventListener(event, this);\n });\n log(`Scope destroyed ${this.id || \"(no id)\"}`);\n }\n}\n\nexport default Scope;\n", "import Scope from \"./src/Scope.js\";\n\ncustomElements.define(\"sco-pe\", Scope);\n"],
"mappings": "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",
"names": []
}