@optionfactory/ful 0.47.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ful.iife.js +53 -40
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +51 -40
- package/dist/ful.mjs.map +1 -1
- package/package.json +1 -1
package/dist/ful.min.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ful.min.mjs","sources":["../src/encodings.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/timing.mjs","../src/events.mjs","../src/elements/elements.mjs","../src/elements/form.mjs","../src/elements/input.mjs","../src/elements/select.mjs","../src/elements/radio.mjs","../src/elements/spinner.mjs","../src/elements/wizard.mjs","../src/elements/definitions.mjs"],"sourcesContent":["\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","class ContextInterceptor {\n constructor() {\n const context = document.querySelector(\"meta[name='context']\").getAttribute(\"content\");\n this.context = context.endsWith(\"/\") ? context.substring(0, context.length - 1) : context;\n }\n async intercept(request, chain){\n const separator = request.resource.startsWith(\"/\") ? \"\" : \"/\";\n request.resource = this.context + separator + request.resource;\n return await chain.proceed(request);\n }\n}\n\nclass CsrfTokenInterceptor {\n constructor() {\n this.k = document.querySelector(\"meta[name='_csrf_header']\").getAttribute(\"content\");\n this.v = document.querySelector(\"meta[name='_csrf']\").getAttribute(\"content\");\n }\n async intercept(request, chain){\n const headers = new Headers(request.options.headers);\n headers.set(this.k, this.v);\n request.options.headers = headers;\n return await chain.proceed(request);\n }\n}\n\nclass RedirectOnUnauthorizedInterceptor {\n constructor(redirectUri) {\n this.redirectUri = redirectUri;\n }\n async intercept(request, chain){\n const response = await chain.proceed(request);\n if (response.status !== 401) {\n return response;\n }\n window.location.href = this.redirectUri;\n }\n}\n\nclass Failure extends Error {\n static parseProblems(status, text) {\n const def = [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: `${status}: ${text}`,\n details: null\n }];\n try {\n return text ? JSON.parse(text) : def;\n } catch (e) {\n return def;\n }\n }\n static fromResponse(status, text) {\n return new Failure(status, Failure.parseProblems(status, text));\n }\n constructor(status, problems) {\n super(JSON.stringify(problems));\n this.name = `Failure:${status}`;\n this.status = status;\n this.problems = problems;\n }\n}\n\nclass HttpClientBuilder {\n constructor() {\n this.interceptors = [];\n }\n withContext() {\n this.interceptors.push(new ContextInterceptor());\n return this;\n }\n withCsrfToken() {\n this.interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n withInterceptors(...interceptors) {\n this.interceptors.push(...interceptors);\n return this;\n }\n build() {\n const interceptors = this.interceptors;\n return new HttpClient({interceptors});\n }\n}\n\nclass HttpCall {\n async intercept(request, chain){\n return await fetch(request.resource, request.options);\n } \n}\n\nclass HttpInterceptorChain {\n constructor(interceptors, current){\n this.interceptors = interceptors;\n this.current = current;\n }\n async proceed(request){\n const interceptor = this.interceptors[this.current];\n return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));\n }\n}\n\n\nclass HttpClient {\n static builder() {\n return new HttpClientBuilder();\n }\n constructor({interceptors}){\n this.interceptors = interceptors || [];\n }\n async exchange(resource, options) {\n const opts = options || {};\n const interceptors = [...this.interceptors, ...opts.interceptors || [], new HttpCall()];\n const chain = new HttpInterceptorChain(interceptors, 0);\n return await chain.proceed({resource, options: opts});\n }\n async fetch(resource, options) {\n const response = await this.exchange(resource, options);\n if (!response.ok) {\n const message = await response.text();\n throw Failure.fromResponse(response.status, message);\n } \n return response;\n }\n async json(resource, options) {\n try {\n const response = await this.fetch(resource, options);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } catch (e) {\n if (e instanceof Failure) {\n throw e;\n }\n throw new Failure(0, [{\n type: \"CONNECTION_PROBLEM\",\n context: null,\n reason: e.message,\n details: null\n }]);\n }\n }\n}\n\nfunction jsonRequest(method, body, headers){\n return {\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers\n },\n method: method,\n body: JSON.stringify(body) \n }\n}\nfunction jsonPost(body, headers){\n return jsonRequest('POST', body, headers);\n}\nfunction jsonPut(body, headers){\n return jsonRequest('PUT', body, headers);\n}\nfunction jsonPatch(body, headers){\n return jsonRequest('PATCH', body, headers);\n}\n\n\nexport { HttpClient, Failure, jsonRequest, jsonPost, jsonPut, jsonPatch };\n","\nclass Storage {\n constructor(prefix, storage) {\n this.prefix = prefix;\n this.storage = storage;\n }\n save(k, v) {\n this.storage.setItem(`${this.prefix}-${k}`, JSON.stringify(v));\n }\n load(k) {\n const got = this.storage.getItem(`${this.prefix}-${k}`);\n return got === undefined ? undefined : JSON.parse(got);\n }\n remove(k) {\n this.storage.removeItem(`${this.prefix}-${k}`);\n }\n pop(k) {\n const decoded = this.load(k);\n this.remove(k);\n return decoded;\n }\n}\n\nclass LocalStorage extends Storage {\n constructor(prefix) {\n super(prefix, localStorage);\n }\n}\n\nclass SessionStorage extends Storage {\n constructor(prefix) {\n super(prefix, sessionStorage);\n }\n}\n\nclass VersionedStorage {\n constructor(storage, key, dataSupplier){\n this.storage = storage;\n this.key = key;\n this.dataSupplier = dataSupplier;\n this.cache = null;\n \n }\n async load(revision){\n const saved = this.storage.load(this.key);\n if (!!saved && saved.revision === revision) {\n this.cache = saved.value;\n return;\n }\n const freshData = await this.dataSupplier(revision, this.key);\n this.storage.save(this.key, {\n revision: revision,\n value: freshData\n });\n this.cache = freshData;\n }\n data(){\n return this.cache;\n }\n}\n\n\n\nexport {LocalStorage, SessionStorage, VersionedStorage};","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri){\n const scope = \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, {\n auth: new URL(\"protocol/openid-connect/auth\", realmBaseUrl),\n token: new URL(\"protocol/openid-connect/token\", realmBaseUrl),\n logout: new URL(\"protocol/openid-connect/logout\", realmBaseUrl),\n registration: new URL(\"protocol/openid-connect/registrations\", realmBaseUrl),\n redirect: redirectUri\n }); \n }\n constructor(clientId, scope, {auth, token, registration, logout, redirect}) {\n this.storage = new SessionStorage(clientId);\n this.clientId = clientId;\n this.scope = scope;\n this.uri = {auth, token, registration, logout, redirect};\n }\n async action(uri, additionalParams){\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n this.storage.save(AuthorizationCodeFlow.PKCE_AND_STATE_KEY, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(uri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n Object.entries(additionalParams || {}).forEach(kv => {\n url.searchParams.set(kv[0], kv[1]);\n });\n window.location = url;\n }\n async registration(additionalParams){\n await this.action(this.uri.registration, additionalParams);\n }\n async applicationInitiatedAction(kcAction){\n await this.action(this.uri.auth, {\n kc_action: kcAction\n });\n }\n async _tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.uri.redirect);\n const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.uri.redirect]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this._tokenExchange(code, state);\n }\n //if not authorized\n await this.action(this.uri.auth, {});\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n const ut8decoder = new TextDecoder(\"utf-8\");\n return {\n header: JSON.parse(ut8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),\n payload: JSON.parse(ut8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),\n signature: signature\n };\n } \n constructor(clientId, t, {token, logout, redirect}) {\n this.clientId = clientId;\n this.token = t;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);\n this.uri = { token, logout, redirect }\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n throw new Error(\"Error:\" + response.status + \": \" + response.text());\n }\n const token = await response.json();\n this.token = token;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.uri.logout);\n url.searchParams.set(\"post_logout_redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location = url;\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n \n interceptor(gracePeriodBefore, gracePeriodAfter){\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter); \n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.session = session;\n this.gracePeriodBefore = gracePeriodBefore || 2000;\n this.gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async intercept(request, chain) {\n await this.session.refreshIf(this.gracePeriodBefore);\n const headers = new Headers(request.options.headers);\n headers.set(\"Authorization\", this.session.bearerToken());\n request.options.headers = headers;\n const response = await chain.proceed(request);\n await this.session.refreshIf(this.gracePeriodAfter);\n return response;\n }\n}\n\n\nexport {AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","\nconst timing = {\n sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n DEBOUNCE_DEFAULT: 0,\n DEBOUNCE_IMMEDIATE: 1,\n debounce(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.DEBOUNCE_DEFAULT;\n\n const later = () => {\n const elapsed = new Date().getTime() - previousTimestamp;\n if (timeoutMs > elapsed) {\n tid = setTimeout(later, timeoutMs - elapsed);\n return;\n }\n tid = null;\n if (opts !== timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n // This check is needed because `func` can recursively invoke `debounced`.\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n args = arguments;\n previousTimestamp = new Date().getTime();\n if (tid === null) {\n tid = setTimeout(later, timeoutMs);\n if (opts === timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n }\n };\n },\n THROTTLE_DEFAULT: 0,\n THROTTLE_NO_LEADING: 1,\n THROTTLE_NO_TRAILING: 2,\n throttle(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.THROTTLE_DEFAULT;\n\n const later = () => {\n previousTimestamp = (opts & timing.THROTTLE_NO_LEADING) ? 0 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = timeoutMs - (now - previousTimestamp);\n args = arguments;\n if (remaining <= 0 || remaining > timeoutMs) {\n if (tid !== null) {\n clearTimeout(tid);\n tid = null;\n }\n previousTimestamp = now;\n func(...args);\n if (tid === null) {\n args = [];\n }\n } else if (tid === null && !(opts & timing.THROTTLE_NO_TRAILING)) {\n tid = setTimeout(later, remaining);\n }\n };\n\n }\n};\n\n\nexport { timing };","\n\n// SyncEvent.on($0, 'asd', async e => { await ful.timing.sleep(10_000); return 3; })\n// const [success, results] = await new SyncEvent(\"asd\").dispatchTo($0);\nclass SyncEvent extends CustomEvent {\n #results;\n constructor(type, options) {\n super(type, options);\n this.#results = [];\n }\n\n async dispatchTo(el) {\n // unlike \"native\" events, which are fired by the browser and invoke \n // event handlers asynchronously via the event loop, dispatchEvent() \n // invokes event handlers synchronously. \n // see: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent\n const success = el.dispatchEvent(this);\n const results = await Promise.all(this.#results);\n return [success, results];\n }\n\n static on(el, type, h, useCapture) {\n el.addEventListener(type, e => {\n //e *must* be an async event\n e.#results.push(h(e));\n }, useCapture);\n }\n}\n\n\nexport { SyncEvent }\n","import { SyncEvent } from \"../events.mjs\";\n\n\nclass Fragments {\n static fromHtml(...html) {\n const el = document.createElement(\"div\");\n el.innerHTML = html.join(\"\");\n const fragment = new DocumentFragment();\n fragment.append(...el.childNodes);\n return fragment;\n }\n static toHtml(fragment) {\n var r = document.createElement(\"div\");\n r.appendChild(fragment);\n return r.innerHTML;\n }\n static from(...nodes) {\n const fragment = new DocumentFragment();\n fragment.append(...nodes);\n return fragment;\n }\n static fromChildNodes(el) {\n const fragment = new DocumentFragment();\n fragment.append(...el.childNodes);\n return fragment;\n }\n}\n\nclass Attributes {\n static id = 0;\n static uid(prefix) {\n return `${prefix}-${++Attributes.id}`;\n }\n static asBoolean(value) {\n return value !== null && value !== undefined && value !== false;\n }\n static defaultValue(el, k, v) {\n if (!el.hasAttribute(k)) {\n el.setAttribute(k, v);\n }\n return el.getAttribute(k);\n }\n static forward(prefix, from, to) {\n from.getAttributeNames()\n .filter(a => a.startsWith(prefix))\n .forEach(a => {\n const target = a.substring(prefix.length);\n if (target === 'class') {\n to.classList.add(...from.getAttribute(prefix + \"class\").split(\" \").filter(a => a.length));\n return;\n }\n to.setAttribute(target, from.getAttribute(a))\n });\n }\n}\n\nclass Slots {\n static from(el) {\n const namedSlots = Array.from(el.childNodes)\n .filter(el => el.matches && el.matches('[slot]'))\n .map(el => {\n el.remove();\n const slot = el.getAttribute(\"slot\");\n el.removeAttribute(\"slot\");\n return [slot, el];\n });\n const slotted = Object.fromEntries(namedSlots);\n slotted.default = new DocumentFragment();\n slotted.default.append(...el.childNodes);\n return slotted;\n }\n}\n\nclass Nodes {\n static isParsed(el) {\n for (var c = el; c; c = c.parentNode) {\n if (c.nextSibling) {\n return true;\n }\n }\n return false;\n }\n}\n\nclass UpgradeQueue {\n #q = [];\n constructor() {\n document.addEventListener('DOMContentLoaded', this.dequeue.bind(this));\n }\n enqueue(el) {\n if (!this.#q.length) {\n requestAnimationFrame(this.dequeue.bind(this));\n }\n this.#q.push(el);\n }\n dequeue() {\n this.#q.splice(0).forEach(el => el.upgrade());\n }\n}\n\nconst upgradeQueue = new UpgradeQueue();\n\nconst ParsedElement = (flags, others) => {\n\n const observed_flags = flags || [];\n const observed_others = others || []; \n const observed = [].concat(observed_flags).concat(observed_others);\n\n const k = class extends HTMLElement {\n static get observedAttributes() {\n return observed;\n }\n #parsed;\n #internals;\n constructor(...args) {\n super(...args);\n this.#internals = this.attachInternals();\n }\n get internals() {\n return this.#internals;\n }\n connectedCallback() {\n if (this.#parsed) {\n return;\n }\n if (this.ownerDocument.readyState === 'complete' || Nodes.isParsed(this)) {\n upgradeQueue.enqueue(this);\n return;\n }\n this.ownerDocument.addEventListener('DOMContentLoaded', () => {\n observer.disconnect();\n upgradeQueue.enqueue(this);\n });\n const observer = new MutationObserver(() => {\n if (!Nodes.isParsed(this)) {\n return;\n }\n observer.disconnect();\n upgradeQueue.enqueue(this);\n });\n observer.observe(this.parentNode, { childList: true, subtree: true });\n }\n attributeChangedCallback(name, oldValue, newValue) {\n if (!this.#parsed || oldValue === newValue) {\n return;\n }\n this[name] = newValue;\n }\n async upgrade() {\n if (this.#parsed) {\n return;\n }\n this.#parsed = true;\n await this.render();\n for (const flag of observed_flags) {\n if(this.hasAttribute(flag)){\n this[flag] = true;\n }\n }\n for (const other of observed_others) {\n if(this.hasAttribute(other)){\n this[other] = this.getAttribute(other);\n }\n }\n } \n };\n\n for (const flag of observed_flags) {\n Object.defineProperty(k.prototype, flag, {\n enumerable: true,\n configurable: true,\n get() {\n return this.internals.states.has(`--${flag}`);\n },\n set(value) {\n //see https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#using_double_dash_prefixed_idents\n if (Attributes.asBoolean(value)) {\n this.internals.states.add(`--${flag}`);\n return;\n }\n this.internals.states.delete(`--${flag}`);\n }\n });\n }\n\n return k;\n}\n\nexport { Fragments, Attributes, Slots, Nodes, ParsedElement };\n","/* global Infinity, CSS */\n\nimport { Failure } from \"../http-client.mjs\";\nimport { ParsedElement } from \"./elements.mjs\"\n\nfunction flatten(obj, prefix) {\n return Object.keys(obj).reduce((acc, k) => {\n const pre = prefix.length ? prefix + '.' : '';\n if (typeof obj[k] === 'object' && obj[k] !== null) {\n Object.assign(acc, flatten(obj[k], pre + k));\n } else {\n acc[pre + k] = obj[k];\n }\n return acc;\n }, {});\n}\n\nfunction providePath(result, path, value) {\n const keys = path.split(\".\").map((k) => k.match(/^[0-9]+$/) ? +k : k);\n let current = result;\n let previous = null;\n for (let i = 0; ; ++i) {\n const ckey = keys[i];\n const pkey = keys[i - 1];\n if (Number.isInteger(ckey) && !Array.isArray(current)) {\n if (previous !== null) {\n previous[pkey] = current = [];\n } else {\n result = current = [];\n }\n }\n if (i === keys.length - 1) {\n //when value is undefined we only want to define the property if it's not defined \n current[ckey] = value !== undefined ? value : (ckey in current ? current[ckey] : null);\n return result;\n }\n if (current[ckey] === undefined) {\n current[ckey] = {};\n }\n previous = current;\n current = current[ckey];\n }\n}\n\nfunction extract(el) {\n if (el.getAttribute('type') === 'radio') {\n if (!el.checked) {\n return undefined;\n }\n return el.dataset['fulBindType'] === 'boolean' ? el.value === 'true' : el.value;\n }\n if (el.getAttribute('type') === 'checkbox') {\n return el.checked;\n }\n if (el.dataset['fulBindType'] === 'boolean') {\n return !el.value ? null : el.value === 'true';\n }\n return el.value || null;\n}\n\nfunction mutate(el, raw) {\n if (el.getAttribute('type') === 'radio') {\n el.checked = el.getAttribute('value') === raw;\n return;\n }\n if (el.getAttribute('type') === 'checkbox') {\n el.checked = raw;\n return;\n }\n el.value = raw;\n}\n\nclass Form extends ParsedElement() {\n static IGNORED_CHILDREN_SELECTOR = '.d-none, [hidden]';\n static SCROLL_OFFSET = 50;\n render() {\n const form = document.createElement('form');\n form.replaceChildren(...this.childNodes);\n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n this.spinner(true);\n try {\n if (this.submitter) {\n await this.submitter(this.values, this);\n }\n } catch (e) {\n if (e instanceof Failure) {\n this.errors = e.problems;\n return;\n }\n throw e;\n } finally {\n this.spinner(false)\n }\n })\n this.replaceChildren(form);\n }\n spinner(spin) {\n this.querySelectorAll('ful-spinner').forEach(el => el.hidden = !spin)\n this.querySelectorAll('[type=submit],[type=reset]').forEach(el => el.disabled = spin)\n }\n set values(vs) {\n for (const [flattenedKey, value] of Object.entries(flatten(vs, ''))) {\n this.querySelectorAll(`[name='${CSS.escape(flattenedKey)}']`).forEach(el => mutate(el, value));\n }\n }\n get values() {\n return Array.from(this.querySelectorAll('[name]'))\n .filter((el) => {\n if (el.dataset['fulBindInclude'] === 'never') {\n return false;\n }\n return el.dataset['fulBindInclude'] === 'always' || el.closest(Form.IGNORED_CHILDREN_SELECTOR) === null;\n })\n .reduce((result, el) => {\n return providePath(result, el.getAttribute('name'), extract(el));\n }, {});\n }\n set errors(es) {\n const fieldErrors = es.filter((e) => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT');\n const globalErrors = es.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');\n this.querySelectorAll('.is-invalid').forEach(el => el.classList.remove('is-invalid'));\n this.querySelectorAll(\"ful-errors\").forEach(el => {\n el.replaceChildren();\n el.setAttribute('hidden', '');\n });\n fieldErrors.forEach((e) => {\n const name = e.context.replace(\"[\", \".\").replace(\"].\", \".\");\n const validationTargetsSelector = `[name='${CSS.escape(name)}'] [ful-validation-target],[name='${CSS.escape(name)}']:not(:has([ful-validation-target]))`;\n this.querySelectorAll(validationTargetsSelector).forEach(input => input.classList.add('is-invalid'));\n const fieldErrorsSelector = `ful-field-error[field='${CSS.escape(name)}']`;\n this.querySelectorAll(fieldErrorsSelector).forEach(el => el.innerText = e.reason);\n });\n this.querySelectorAll(\"ful-errors\").forEach(el => {\n el.innerText = globalErrors.map(e => e.reason).join(\"\\n\");\n if (globalErrors.length !== 0) {\n el.removeAttribute('hidden');\n }\n });\n if (!this.hasAttribute('scroll-on-error')) {\n return;\n }\n const ys = Array.from(this.querySelectorAll('ful-field-error'))\n .map(el => el.parentElement ? el.parentElement : el)\n .map(el => el.getBoundingClientRect().y + window.scrollY);\n const miny = Math.min(...ys);\n if (miny !== Infinity) {\n window.scroll(window.scrollX, miny > Form.SCROLL_OFFSET ? miny - Form.SCROLL_OFFSET : 0);\n }\n }\n}\n\nexport { Form };\n","import { Attributes, Slots, ParsedElement } from \"./elements.mjs\"\n\nconst ful_input_ec = globalThis.ec || ftl.EvaluationContext.configure({\n\n});\n\nconst template = globalThis.ful_input_template || ftl.Template.fromHtml(`\n <label data-tpl-for=\"id\" class=\"form-label\">{{{{ slotted.default }}}}</label>\n <div class=\"input-group\">\n <span data-tpl-if=\"slotted.ibefore\" class=\"input-group-text\">{{{{ slotted.ibefore }}}}</span>\n <div data-tpl-if=\"slotted.before\" data-tpl-remove=\"tag\">{{{{ slotted.before }}}}</div>\n {{{{ slotted.input }}}} \n <div data-tpl-if=\"slotted.after\" data-tpl-remove=\"tag\">{{{{ slotted.after }}}}</div>\n <span data-tpl-if=\"slotted.iafter\" class=\"input-group-text\">{{{{ slotted.iafter }}}}</span>\n </div>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error>\n`, ful_input_ec);\n\nconst renderInput = (el) => {\n const slotted = Slots.from(el);\n\n const input = el.input = slotted.input = slotted.input || (() => {\n const el = document.createElement(\"input\")\n el.classList.add(\"form-control\");\n return el;\n })();\n input.setAttribute('ful-validation-target', '');\n\n const id = input.getAttribute('id') || el.getAttribute('input-id') || Attributes.uid('ful-input');\n Attributes.forward('input-', el, slotted.input)\n Attributes.defaultValue(slotted.input, \"id\", id);\n Attributes.defaultValue(slotted.input, \"type\", \"text\");\n Attributes.defaultValue(slotted.input, \"placeholder\", \" \");\n const name = el.getAttribute('name');\n template.renderTo(el, { id, name, slotted });\n}\n\nclass StatelessInput extends ParsedElement() {\n render() {\n renderInput(this);\n }\n}\n\nclass Input extends ParsedElement([], ['value']) {\n render() {\n renderInput(this);\n }\n get value() {\n return this.input.value;\n }\n set value(value) {\n this.input.value = value;\n }\n}\n\nexport { StatelessInput, Input };\n","import { Fragments, Attributes, Slots, ParsedElement } from \"./elements.mjs\"\n/**\n * <script src=\"tom-select.complete.js\"></script>\n * <link href=\"tom-select.bootstrap5.css\" rel=\"stylesheet\" />\n */\nconst ful_select_ec = globalThis.ec || ftl.EvaluationContext.configure({\n\n});\n\nconst ful_select_template_ = globalThis.ful_select_template || ftl.Template.fromHtml(`\n <label data-tpl-for=\"tsId\" class=\"form-label\">{{{{ slotted.default }}}}</label>\n {{{{ input }}}}\n <div class=\"input-group\">\n <span data-tpl-if=\"slotted.ibefore\" class=\"input-group-text\">{{{{ slotted.ibefore }}}}</span>\n <div data-tpl-if=\"slotted.before\" data-tpl-remove=\"tag\">{{{{ slotted.before }}}}</div>\n {{{{ slotted.input }}}} \n <div data-tpl-if=\"slotted.after\" data-tpl-remove=\"tag\">{{{{ slotted.after }}}}</div>\n <span data-tpl-if=\"slotted.iafter\" class=\"input-group-text\">{{{{ slotted.iafter }}}}</span>\n </div>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error> \n`, ful_select_ec);\n\n\nclass Select extends ParsedElement([], [\"value\"]) {\n constructor(tsConfig) {\n super();\n this.tsConfig = tsConfig;\n }\n render() {\n const slotted = Slots.from(this);\n\n const type = this.getAttribute(\"type\") || 'local';\n const remote = type != 'local';\n const loadOnce = this.getAttribute('load') != 'always';\n const name = this.getAttribute('name');\n const input = slotted.input = slotted.input || (() => {\n return document.createElement(\"select\");\n })();\n input.setAttribute('ful-validation-target', '');\n\n const id = input.getAttribute('id') || this.getAttribute('input-id') || Attributes.uid('ful-select');\n const tsId = `${id}-ts-control`;\n Attributes.forward('input-', this, input)\n Attributes.defaultValue(input, \"id\", id);\n Attributes.defaultValue(input, \"placeholder\", \" \");\n\n //tomselect needs the input to have a parent.\n //se we move the input to a fragment\n slotted.input = Fragments.from(input);\n\n this.loaded = !remote;\n\n const tsDefaultConfig = {\n render: {\n loading: () => '<ful-spinner class=\"centered p-2\"></ful-spinner>'\n }\n }\n\n this._remote = remote;\n // we need to await this load in setValue when remote is configured and the option\n // is not loaded yet.\n // tomselect settings.load does not retun a promise as it wraps the configured load function\n // with a debouncer\n this._unwrappedRemoteLoad = async (query, callback) => {\n\n if (!remote || remote && loadOnce && this.loaded) {\n callback();\n return;\n }\n const type = query && query.hasOwnProperty('byId') ? 'id' : 'query';\n const qvalue = type === 'id' ? query.byId : query;\n const data = await (this.loader ? this.loader(qvalue, type) : []);\n if (type !== 'id') {\n this.loaded = true;\n }\n callback(data);\n };\n\n\n this.ts = new TomSelect(input, Object.assign(remote ? {\n preload: 'focus',\n load: this._unwrappedRemoteLoad,\n shouldLoad: (query) => this.shouldLoad ? this.shouldLoad(query) : true\n } : {}, tsDefaultConfig, this.tsConfig));\n //we remove the input to move it\n input.remove();\n ful_select_template_.renderTo(this, { id, tsId, name, input, slotted });\n }\n set value(v) {\n (async () => {\n if (this._remote) {\n await this._unwrappedRemoteLoad({ byId: v }, this.ts.loadCallback.bind(this.ts));\n }\n this.ts.setValue(v);\n })();\n }\n get value() {\n const v = this.ts.getValue();\n return v === '' ? null : v;\n }\n}\n\nexport { Select };\n","import { Attributes, Slots, Fragments, ParsedElement } from \"./elements.mjs\"\n\n\nconst ful_radiogroup_ec = globalThis.ec || ftl.EvaluationContext.configure({\n\n});\n\nconst ful_radiougroup_template_ = globalThis.ful_radiogroup_template || ftl.Template.fromHtml(`\n <fieldset>\n <legend class=\"form-label\">\n {{{{ slotted.default }}}}\n </legend>\n <header data-tpl-if=\"slotted.header\">\n {{{{ slotted.header }}}}\n </header>\n <section>\n <label data-tpl-each=\"inputsAndLabels\" data-tpl-var=\"ial\">\n {{{{ ial[0] }}}}\n {{{{ ial[1] }}}}\n </label>\n </section>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error>\n <footer data-tpl-if=\"slotted.footer\">\n {{{{ slotted.footer }}}}\n </footer>\n </fieldset>\n`, ful_radiogroup_ec);\n\n\nclass RadioGroup extends ParsedElement(['disabled'], ['value']) {\n render() {\n const slotted = Slots.from(this);\n const name = this.getAttribute('name') || Attributes.uid('ful-radiogroup');\n const radioEls = Array.from(slotted.default.querySelectorAll('ful-radio'));\n const inputsAndLabels = radioEls.map(el => {\n const input = document.createElement('input');\n input.setAttribute('type', 'radio');\n Attributes.forward('input-', this, input);\n Attributes.forward('', el, input);\n input.setAttribute('name', `${name}-ignore`);\n input.setAttribute('ful-validation-target', '');\n input.dataset['fulBindInclude'] = 'never';\n const label = Fragments.fromChildNodes(el);\n return [input, label];\n });\n radioEls.forEach(el => el.remove());\n\n ful_radiougroup_template_.renderTo(this, {\n name: name,\n slotted: slotted,\n inputsAndLabels: inputsAndLabels\n });\n }\n get value() {\n const checked = this.querySelector('input[type=radio]:checked');\n return checked ? checked.value : null;\n }\n set value(value) {\n this.querySelector(`input[type=radio][value=${CSS.escape(value)}]`).checked = true;\n }\n}\n\n\nexport { RadioGroup };","import { ParsedElement, Slots } from \"./elements.mjs\"\n\nconst ful_spinner_ec = globalThis.ec || ftl.EvaluationContext.configure({\n\n});\n\nconst template = globalThis.ful_spinner_template || ftl.Template.fromHtml(`\n <div class=\"ful-spinner-wrapper\">\n <div class=\"ful-spinner-text\">{{{{ slotted.default }}}}</div>\n <div class=\"ful-spinner-icon\"></div>\n </div>\n`, ful_spinner_ec);\n\n\nclass Spinner extends ParsedElement() {\n render() {\n const slotted = Slots.from(this);\n template.renderTo(this, { slotted });\n }\n}\n\nexport { Spinner };","class Wizard extends HTMLElement {\n constructor() {\n super();\n this.progress = [...this.children].filter(e => e.matches(\"header,ol,ul\"));\n\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n if (current === undefined && children.length > 0) {\n children[0].classList.add('active');\n }\n });\n if (this.querySelector('section.current') === null) {\n const firstSection = this.querySelector('section:first-of-type');\n if (firstSection !== null) {\n firstSection.classList.add('current');\n }\n }\n }\n next() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.nextElementSibling?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.nextElementSibling.classList.add('current');\n\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n\n }\n prev() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.previousElementSibling?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.previousElementSibling.classList.add('current');\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n moveTo(n) {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n p.children[+n]?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection?.classList.remove(\"current\");\n const nthSection = this.querySelector(`section:nth-child(${+n})`);\n nthSection.classList.add('current');\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n static configure() {\n return Wizard.custom('ful-wizard');\n }\n}\n\n\n\n\nexport { Wizard };\n","import { Spinner } from \"./spinner.mjs\";\nimport { Input } from \"./input.mjs\";\nimport { RadioGroup } from \"./radio.mjs\";\nimport { Select } from \"./select.mjs\";\nimport { Form } from \"./form.mjs\";\n\n\nexport class CustomElements {\n static configure() {\n customElements.define('ful-spinner', Spinner);\n customElements.define('ful-input', Input);\n customElements.define('ful-radio-group', RadioGroup);\n customElements.define('ful-select', Select);\n customElements.define('ful-form', Form);\n }\n}\n"],"names":["Base64","encode","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","i","substring","length","decode","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Hex","hex","Error","lenInBytes","map","e","offset","octet","parseInt","bytes","upper","Array","from","b","toString","toUpperCase","o","padStart","join","ContextInterceptor","constructor","context","document","querySelector","getAttribute","this","endsWith","intercept","request","chain","separator","resource","startsWith","proceed","CsrfTokenInterceptor","k","v","headers","Headers","options","set","RedirectOnUnauthorizedInterceptor","redirectUri","response","status","window","location","href","Failure","parseProblems","text","def","type","reason","details","JSON","parse","fromResponse","problems","super","stringify","name","HttpClientBuilder","interceptors","withContext","push","withCsrfToken","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","HttpInterceptorChain","current","interceptor","builder","exchange","opts","ok","message","json","undefined","jsonRequest","method","body","jsonPost","jsonPut","jsonPatch","Storage","prefix","storage","save","setItem","load","got","getItem","remove","removeItem","pop","decoded","LocalStorage","localStorage","SessionStorage","sessionStorage","VersionedStorage","key","dataSupplier","cache","revision","saved","value","freshData","data","AuthorizationCodeFlow","forKeycloak","clientId","realmBaseUrl","auth","URL","token","logout","registration","redirect","scope","uri","action","additionalParams","pkceVerifier","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","url","searchParams","Object","entries","forEach","kv","applicationInitiatedAction","kcAction","kc_action","_tokenExchange","code","history","replaceState","stateAndVerifier","URLSearchParams","AuthorizationCodeFlowSession","ensureLoggedIn","get","parseToken","rawHeader","rawPayload","signature","split","ut8decoder","TextDecoder","header","payload","t","accessToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","callback","refresh","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refreshIf","id_token","bearerToken","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","timing","sleep","ms","Promise","resolve","setTimeout","DEBOUNCE_DEFAULT","DEBOUNCE_IMMEDIATE","debounce","timeoutMs","func","tid","args","previousTimestamp","later","elapsed","arguments","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","THROTTLE_NO_TRAILING","throttle","remaining","clearTimeout","SyncEvent","CustomEvent","results","dispatchTo","el","dispatchEvent","all","on","h","useCapture","addEventListener","Fragments","fromHtml","html","createElement","innerHTML","fragment","DocumentFragment","append","childNodes","toHtml","r","appendChild","nodes","fromChildNodes","Attributes","static","uid","id","asBoolean","defaultValue","hasAttribute","setAttribute","forward","to","getAttributeNames","filter","a","target","classList","add","Slots","namedSlots","matches","slot","removeAttribute","slotted","fromEntries","default","Nodes","isParsed","c","parentNode","nextSibling","upgradeQueue","q","dequeue","bind","enqueue","requestAnimationFrame","splice","upgrade","ParsedElement","flags","others","observed_flags","observed_others","observed","concat","HTMLElement","observedAttributes","parsed","internals","attachInternals","connectedCallback","ownerDocument","readyState","observer","disconnect","MutationObserver","observe","childList","subtree","attributeChangedCallback","oldValue","newValue","render","flag","other","defineProperty","prototype","enumerable","configurable","states","has","delete","flatten","obj","keys","reduce","acc","pre","assign","mutate","raw","checked","Form","form","replaceChildren","async","preventDefault","spinner","submitter","values","errors","spin","querySelectorAll","hidden","disabled","vs","flattenedKey","CSS","escape","dataset","closest","IGNORED_CHILDREN_SELECTOR","result","path","match","previous","ckey","pkey","Number","isInteger","isArray","providePath","extract","es","fieldErrors","globalErrors","replace","validationTargetsSelector","input","fieldErrorsSelector","innerText","ys","parentElement","getBoundingClientRect","y","scrollY","miny","min","Infinity","scroll","scrollX","SCROLL_OFFSET","ful_input_ec","globalThis","ec","ftl","EvaluationContext","configure","template","ful_input_template","Template","renderInput","renderTo","StatelessInput","Input","ful_select_ec","ful_select_template_","ful_select_template","Select","tsConfig","remote","loadOnce","tsId","loaded","_remote","_unwrappedRemoteLoad","query","hasOwnProperty","qvalue","byId","loader","ts","TomSelect","preload","shouldLoad","loading","loadCallback","setValue","getValue","ful_radiogroup_ec","ful_radiougroup_template_","ful_radiogroup_template","RadioGroup","radioEls","inputsAndLabels","ful_spinner_ec","ful_spinner_template","Spinner","Wizard","progress","children","p","firstSection","next","nextElementSibling","currentSection","bubbles","cancelable","prev","previousElementSibling","moveTo","n","custom","CustomElements","customElements","define"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ful.min.mjs","sources":["../src/encodings.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/timing.mjs","../src/events.mjs","../src/elements/elements.mjs","../src/elements/form.mjs","../src/elements/input.mjs","../src/elements/select.mjs","../src/elements/radio.mjs","../src/elements/spinner.mjs","../src/elements/wizard.mjs","../src/elements/definitions.mjs"],"sourcesContent":["\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","class ContextInterceptor {\n constructor() {\n const context = document.querySelector(\"meta[name='context']\").getAttribute(\"content\");\n this.context = context.endsWith(\"/\") ? context.substring(0, context.length - 1) : context;\n }\n async intercept(request, chain){\n const separator = request.resource.startsWith(\"/\") ? \"\" : \"/\";\n request.resource = this.context + separator + request.resource;\n return await chain.proceed(request);\n }\n}\n\nclass CsrfTokenInterceptor {\n constructor() {\n this.k = document.querySelector(\"meta[name='_csrf_header']\").getAttribute(\"content\");\n this.v = document.querySelector(\"meta[name='_csrf']\").getAttribute(\"content\");\n }\n async intercept(request, chain){\n const headers = new Headers(request.options.headers);\n headers.set(this.k, this.v);\n request.options.headers = headers;\n return await chain.proceed(request);\n }\n}\n\nclass RedirectOnUnauthorizedInterceptor {\n constructor(redirectUri) {\n this.redirectUri = redirectUri;\n }\n async intercept(request, chain){\n const response = await chain.proceed(request);\n if (response.status !== 401) {\n return response;\n }\n window.location.href = this.redirectUri;\n }\n}\n\nclass Failure extends Error {\n static parseProblems(status, text) {\n const def = [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: `${status}: ${text}`,\n details: null\n }];\n try {\n return text ? JSON.parse(text) : def;\n } catch (e) {\n return def;\n }\n }\n static fromResponse(status, text) {\n return new Failure(status, Failure.parseProblems(status, text));\n }\n constructor(status, problems) {\n super(JSON.stringify(problems));\n this.name = `Failure:${status}`;\n this.status = status;\n this.problems = problems;\n }\n}\n\nclass HttpClientBuilder {\n constructor() {\n this.interceptors = [];\n }\n withContext() {\n this.interceptors.push(new ContextInterceptor());\n return this;\n }\n withCsrfToken() {\n this.interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n withInterceptors(...interceptors) {\n this.interceptors.push(...interceptors);\n return this;\n }\n build() {\n const interceptors = this.interceptors;\n return new HttpClient({interceptors});\n }\n}\n\nclass HttpCall {\n async intercept(request, chain){\n return await fetch(request.resource, request.options);\n } \n}\n\nclass HttpInterceptorChain {\n constructor(interceptors, current){\n this.interceptors = interceptors;\n this.current = current;\n }\n async proceed(request){\n const interceptor = this.interceptors[this.current];\n return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));\n }\n}\n\n\nclass HttpClient {\n static builder() {\n return new HttpClientBuilder();\n }\n constructor({interceptors}){\n this.interceptors = interceptors || [];\n }\n async exchange(resource, options) {\n const opts = options || {};\n const interceptors = [...this.interceptors, ...opts.interceptors || [], new HttpCall()];\n const chain = new HttpInterceptorChain(interceptors, 0);\n return await chain.proceed({resource, options: opts});\n }\n async fetch(resource, options) {\n const response = await this.exchange(resource, options);\n if (!response.ok) {\n const message = await response.text();\n throw Failure.fromResponse(response.status, message);\n } \n return response;\n }\n async json(resource, options) {\n try {\n const response = await this.fetch(resource, options);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } catch (e) {\n if (e instanceof Failure) {\n throw e;\n }\n throw new Failure(0, [{\n type: \"CONNECTION_PROBLEM\",\n context: null,\n reason: e.message,\n details: null\n }]);\n }\n }\n}\n\nfunction jsonRequest(method, body, headers){\n return {\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers\n },\n method: method,\n body: JSON.stringify(body) \n }\n}\nfunction jsonPost(body, headers){\n return jsonRequest('POST', body, headers);\n}\nfunction jsonPut(body, headers){\n return jsonRequest('PUT', body, headers);\n}\nfunction jsonPatch(body, headers){\n return jsonRequest('PATCH', body, headers);\n}\n\n\nexport { HttpClient, Failure, jsonRequest, jsonPost, jsonPut, jsonPatch };\n","\nclass Storage {\n constructor(prefix, storage) {\n this.prefix = prefix;\n this.storage = storage;\n }\n save(k, v) {\n this.storage.setItem(`${this.prefix}-${k}`, JSON.stringify(v));\n }\n load(k) {\n const got = this.storage.getItem(`${this.prefix}-${k}`);\n return got === undefined ? undefined : JSON.parse(got);\n }\n remove(k) {\n this.storage.removeItem(`${this.prefix}-${k}`);\n }\n pop(k) {\n const decoded = this.load(k);\n this.remove(k);\n return decoded;\n }\n}\n\nclass LocalStorage extends Storage {\n constructor(prefix) {\n super(prefix, localStorage);\n }\n}\n\nclass SessionStorage extends Storage {\n constructor(prefix) {\n super(prefix, sessionStorage);\n }\n}\n\nclass VersionedStorage {\n constructor(storage, key, dataSupplier){\n this.storage = storage;\n this.key = key;\n this.dataSupplier = dataSupplier;\n this.cache = null;\n \n }\n async load(revision){\n const saved = this.storage.load(this.key);\n if (!!saved && saved.revision === revision) {\n this.cache = saved.value;\n return;\n }\n const freshData = await this.dataSupplier(revision, this.key);\n this.storage.save(this.key, {\n revision: revision,\n value: freshData\n });\n this.cache = freshData;\n }\n data(){\n return this.cache;\n }\n}\n\n\n\nexport {LocalStorage, SessionStorage, VersionedStorage};","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri){\n const scope = \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, {\n auth: new URL(\"protocol/openid-connect/auth\", realmBaseUrl),\n token: new URL(\"protocol/openid-connect/token\", realmBaseUrl),\n logout: new URL(\"protocol/openid-connect/logout\", realmBaseUrl),\n registration: new URL(\"protocol/openid-connect/registrations\", realmBaseUrl),\n redirect: redirectUri\n }); \n }\n constructor(clientId, scope, {auth, token, registration, logout, redirect}) {\n this.storage = new SessionStorage(clientId);\n this.clientId = clientId;\n this.scope = scope;\n this.uri = {auth, token, registration, logout, redirect};\n }\n async action(uri, additionalParams){\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n this.storage.save(AuthorizationCodeFlow.PKCE_AND_STATE_KEY, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(uri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n Object.entries(additionalParams || {}).forEach(kv => {\n url.searchParams.set(kv[0], kv[1]);\n });\n window.location = url;\n }\n async registration(additionalParams){\n await this.action(this.uri.registration, additionalParams);\n }\n async applicationInitiatedAction(kcAction){\n await this.action(this.uri.auth, {\n kc_action: kcAction\n });\n }\n async _tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.uri.redirect);\n const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.uri.redirect]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this._tokenExchange(code, state);\n }\n //if not authorized\n await this.action(this.uri.auth, {});\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n const ut8decoder = new TextDecoder(\"utf-8\");\n return {\n header: JSON.parse(ut8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),\n payload: JSON.parse(ut8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),\n signature: signature\n };\n } \n constructor(clientId, t, {token, logout, redirect}) {\n this.clientId = clientId;\n this.token = t;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);\n this.uri = { token, logout, redirect }\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n throw new Error(\"Error:\" + response.status + \": \" + response.text());\n }\n const token = await response.json();\n this.token = token;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.uri.logout);\n url.searchParams.set(\"post_logout_redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location = url;\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n \n interceptor(gracePeriodBefore, gracePeriodAfter){\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter); \n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.session = session;\n this.gracePeriodBefore = gracePeriodBefore || 2000;\n this.gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async intercept(request, chain) {\n await this.session.refreshIf(this.gracePeriodBefore);\n const headers = new Headers(request.options.headers);\n headers.set(\"Authorization\", this.session.bearerToken());\n request.options.headers = headers;\n const response = await chain.proceed(request);\n await this.session.refreshIf(this.gracePeriodAfter);\n return response;\n }\n}\n\n\nexport {AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","\nconst timing = {\n sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n DEBOUNCE_DEFAULT: 0,\n DEBOUNCE_IMMEDIATE: 1,\n debounce(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.DEBOUNCE_DEFAULT;\n\n const later = () => {\n const elapsed = new Date().getTime() - previousTimestamp;\n if (timeoutMs > elapsed) {\n tid = setTimeout(later, timeoutMs - elapsed);\n return;\n }\n tid = null;\n if (opts !== timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n // This check is needed because `func` can recursively invoke `debounced`.\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n args = arguments;\n previousTimestamp = new Date().getTime();\n if (tid === null) {\n tid = setTimeout(later, timeoutMs);\n if (opts === timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n }\n };\n },\n THROTTLE_DEFAULT: 0,\n THROTTLE_NO_LEADING: 1,\n THROTTLE_NO_TRAILING: 2,\n throttle(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.THROTTLE_DEFAULT;\n\n const later = () => {\n previousTimestamp = (opts & timing.THROTTLE_NO_LEADING) ? 0 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = timeoutMs - (now - previousTimestamp);\n args = arguments;\n if (remaining <= 0 || remaining > timeoutMs) {\n if (tid !== null) {\n clearTimeout(tid);\n tid = null;\n }\n previousTimestamp = now;\n func(...args);\n if (tid === null) {\n args = [];\n }\n } else if (tid === null && !(opts & timing.THROTTLE_NO_TRAILING)) {\n tid = setTimeout(later, remaining);\n }\n };\n\n }\n};\n\n\nexport { timing };","\n\n// SyncEvent.on($0, 'asd', async e => { await ful.timing.sleep(10_000); return 3; })\n// const [success, results] = await new SyncEvent(\"asd\").dispatchTo($0);\nclass SyncEvent extends CustomEvent {\n #results;\n constructor(type, options) {\n super(type, options);\n this.#results = [];\n }\n\n async dispatchTo(el) {\n // unlike \"native\" events, which are fired by the browser and invoke \n // event handlers asynchronously via the event loop, dispatchEvent() \n // invokes event handlers synchronously. \n // see: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent\n const success = el.dispatchEvent(this);\n const results = await Promise.all(this.#results);\n return [success, results];\n }\n\n static on(el, type, h, useCapture) {\n el.addEventListener(type, e => {\n //e *must* be an async event\n e.#results.push(h(e));\n }, useCapture);\n }\n}\n\n\nexport { SyncEvent }\n","import { SyncEvent } from \"../events.mjs\";\n\n\nclass Fragments {\n static fromHtml(...html) {\n const el = document.createElement(\"div\");\n el.innerHTML = html.join(\"\");\n const fragment = new DocumentFragment();\n fragment.append(...el.childNodes);\n return fragment;\n }\n static toHtml(fragment) {\n var r = document.createElement(\"div\");\n r.appendChild(fragment);\n return r.innerHTML;\n }\n static from(...nodes) {\n const fragment = new DocumentFragment();\n fragment.append(...nodes);\n return fragment;\n }\n static fromChildNodes(el) {\n const fragment = new DocumentFragment();\n fragment.append(...el.childNodes);\n return fragment;\n }\n}\n\nclass Attributes {\n static id = 0;\n static uid(prefix) {\n return `${prefix}-${++Attributes.id}`;\n }\n static asBoolean(value) {\n return value !== null && value !== undefined && value !== false;\n }\n static defaultValue(el, k, v) {\n if (!el.hasAttribute(k)) {\n el.setAttribute(k, v);\n }\n return el.getAttribute(k);\n }\n static forward(prefix, from, to) {\n from.getAttributeNames()\n .filter(a => a.startsWith(prefix))\n .forEach(a => {\n const target = a.substring(prefix.length);\n if (target === 'class') {\n to.classList.add(...from.getAttribute(prefix + \"class\").split(\" \").filter(a => a.length));\n return;\n }\n to.setAttribute(target, from.getAttribute(a))\n });\n }\n}\n\nclass Slots {\n static from(el) {\n const namedSlots = Array.from(el.childNodes)\n .filter(el => el.matches && el.matches('[slot]'))\n .map(el => {\n el.remove();\n const slot = el.getAttribute(\"slot\");\n el.removeAttribute(\"slot\");\n return [slot, el];\n });\n const slotted = Object.fromEntries(namedSlots);\n slotted.default = new DocumentFragment();\n slotted.default.append(...el.childNodes);\n return slotted;\n }\n}\n\nclass Nodes {\n static isParsed(el) {\n for (var c = el; c; c = c.parentNode) {\n if (c.nextSibling) {\n return true;\n }\n }\n return false;\n }\n}\n\nclass TemplateRegistry {\n #idToFragment = {};\n #idToTemplate = {};\n #ec;\n put(k, fragment) {\n if (this.#ec) {\n this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, ec);\n return;\n }\n this.#idToFragment[k] = fragment;\n }\n get(k) {\n if (!this.#ec) {\n throw new Error(\"evaluationContext is not configured\");\n }\n const tpl = this.#idToTemplate[k];\n if (!tpl) {\n throw new Error(`missing template: '${k}'`);\n }\n return tpl;\n }\n configure(ec) {\n this.#ec = ec;\n for (const [k, fragment] of Object.entries(this.#idToFragment)) {\n delete this.#idToFragment[k];\n this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, ec);\n }\n }\n}\n\nconst templates = new TemplateRegistry();\n\nclass UpgradeQueue {\n #q = [];\n constructor() {\n document.addEventListener('DOMContentLoaded', this.dequeue.bind(this));\n }\n enqueue(el) {\n if (!this.#q.length) {\n requestAnimationFrame(this.dequeue.bind(this));\n }\n this.#q.push(el);\n }\n dequeue() {\n this.#q.splice(0).forEach(el => el.upgrade());\n }\n}\n\nconst upgradeQueue = new UpgradeQueue();\n\nconst ParsedElement = (flags, others) => {\n\n const observed_flags = flags || [];\n const observed_others = others || []; \n const observed = [].concat(observed_flags).concat(observed_others);\n\n const k = class extends HTMLElement {\n static get observedAttributes() {\n return observed;\n }\n #parsed;\n #internals;\n constructor(...args) {\n super(...args);\n this.#internals = this.attachInternals();\n }\n get internals() {\n return this.#internals;\n }\n connectedCallback() {\n if (this.#parsed) {\n return;\n }\n if (this.ownerDocument.readyState === 'complete' || Nodes.isParsed(this)) {\n upgradeQueue.enqueue(this);\n return;\n }\n this.ownerDocument.addEventListener('DOMContentLoaded', () => {\n observer.disconnect();\n upgradeQueue.enqueue(this);\n });\n const observer = new MutationObserver(() => {\n if (!Nodes.isParsed(this)) {\n return;\n }\n observer.disconnect();\n upgradeQueue.enqueue(this);\n });\n observer.observe(this.parentNode, { childList: true, subtree: true });\n }\n attributeChangedCallback(name, oldValue, newValue) {\n if (!this.#parsed || oldValue === newValue) {\n return;\n }\n this[name] = newValue;\n }\n async upgrade() {\n if (this.#parsed) {\n return;\n }\n this.#parsed = true;\n await this.render();\n for (const flag of observed_flags) {\n if(this.hasAttribute(flag)){\n this[flag] = true;\n }\n }\n for (const other of observed_others) {\n if(this.hasAttribute(other)){\n this[other] = this.getAttribute(other);\n }\n }\n } \n };\n\n for (const flag of observed_flags) {\n Object.defineProperty(k.prototype, flag, {\n enumerable: true,\n configurable: true,\n get() {\n return this.internals.states.has(`--${flag}`);\n },\n set(value) {\n //see https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#using_double_dash_prefixed_idents\n if (Attributes.asBoolean(value)) {\n this.internals.states.add(`--${flag}`);\n return;\n }\n this.internals.states.delete(`--${flag}`);\n }\n });\n }\n\n return k;\n}\n\nexport { Fragments, Attributes, Slots, Nodes, TemplateRegistry, templates, ParsedElement };\n","/* global Infinity, CSS */\n\nimport { Failure } from \"../http-client.mjs\";\nimport { ParsedElement } from \"./elements.mjs\"\n\nfunction flatten(obj, prefix) {\n return Object.keys(obj).reduce((acc, k) => {\n const pre = prefix.length ? prefix + '.' : '';\n if (typeof obj[k] === 'object' && obj[k] !== null) {\n Object.assign(acc, flatten(obj[k], pre + k));\n } else {\n acc[pre + k] = obj[k];\n }\n return acc;\n }, {});\n}\n\nfunction providePath(result, path, value) {\n const keys = path.split(\".\").map((k) => k.match(/^[0-9]+$/) ? +k : k);\n let current = result;\n let previous = null;\n for (let i = 0; ; ++i) {\n const ckey = keys[i];\n const pkey = keys[i - 1];\n if (Number.isInteger(ckey) && !Array.isArray(current)) {\n if (previous !== null) {\n previous[pkey] = current = [];\n } else {\n result = current = [];\n }\n }\n if (i === keys.length - 1) {\n //when value is undefined we only want to define the property if it's not defined \n current[ckey] = value !== undefined ? value : (ckey in current ? current[ckey] : null);\n return result;\n }\n if (current[ckey] === undefined) {\n current[ckey] = {};\n }\n previous = current;\n current = current[ckey];\n }\n}\n\nfunction extract(el) {\n if (el.getAttribute('type') === 'radio') {\n if (!el.checked) {\n return undefined;\n }\n return el.dataset['fulBindType'] === 'boolean' ? el.value === 'true' : el.value;\n }\n if (el.getAttribute('type') === 'checkbox') {\n return el.checked;\n }\n if (el.dataset['fulBindType'] === 'boolean') {\n return !el.value ? null : el.value === 'true';\n }\n return el.value || null;\n}\n\nfunction mutate(el, raw) {\n if (el.getAttribute('type') === 'radio') {\n el.checked = el.getAttribute('value') === raw;\n return;\n }\n if (el.getAttribute('type') === 'checkbox') {\n el.checked = raw;\n return;\n }\n el.value = raw;\n}\n\nclass Form extends ParsedElement() {\n static IGNORED_CHILDREN_SELECTOR = '.d-none, [hidden]';\n static SCROLL_OFFSET = 50;\n render() {\n const form = document.createElement('form');\n form.replaceChildren(...this.childNodes);\n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n this.spinner(true);\n try {\n if (this.submitter) {\n await this.submitter(this.values, this);\n }\n } catch (e) {\n if (e instanceof Failure) {\n this.errors = e.problems;\n return;\n }\n throw e;\n } finally {\n this.spinner(false)\n }\n })\n this.replaceChildren(form);\n }\n spinner(spin) {\n this.querySelectorAll('ful-spinner').forEach(el => el.hidden = !spin)\n this.querySelectorAll('[type=submit],[type=reset]').forEach(el => el.disabled = spin)\n }\n set values(vs) {\n for (const [flattenedKey, value] of Object.entries(flatten(vs, ''))) {\n this.querySelectorAll(`[name='${CSS.escape(flattenedKey)}']`).forEach(el => mutate(el, value));\n }\n }\n get values() {\n return Array.from(this.querySelectorAll('[name]'))\n .filter((el) => {\n if (el.dataset['fulBindInclude'] === 'never') {\n return false;\n }\n return el.dataset['fulBindInclude'] === 'always' || el.closest(Form.IGNORED_CHILDREN_SELECTOR) === null;\n })\n .reduce((result, el) => {\n return providePath(result, el.getAttribute('name'), extract(el));\n }, {});\n }\n set errors(es) {\n const fieldErrors = es.filter((e) => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT');\n const globalErrors = es.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');\n this.querySelectorAll('.is-invalid').forEach(el => el.classList.remove('is-invalid'));\n this.querySelectorAll(\"ful-errors\").forEach(el => {\n el.replaceChildren();\n el.setAttribute('hidden', '');\n });\n fieldErrors.forEach((e) => {\n const name = e.context.replace(\"[\", \".\").replace(\"].\", \".\");\n const validationTargetsSelector = `[name='${CSS.escape(name)}'] [ful-validation-target],[name='${CSS.escape(name)}']:not(:has([ful-validation-target]))`;\n this.querySelectorAll(validationTargetsSelector).forEach(input => input.classList.add('is-invalid'));\n const fieldErrorsSelector = `ful-field-error[field='${CSS.escape(name)}']`;\n this.querySelectorAll(fieldErrorsSelector).forEach(el => el.innerText = e.reason);\n });\n this.querySelectorAll(\"ful-errors\").forEach(el => {\n el.innerText = globalErrors.map(e => e.reason).join(\"\\n\");\n if (globalErrors.length !== 0) {\n el.removeAttribute('hidden');\n }\n });\n if (!this.hasAttribute('scroll-on-error')) {\n return;\n }\n const ys = Array.from(this.querySelectorAll('ful-field-error'))\n .map(el => el.parentElement ? el.parentElement : el)\n .map(el => el.getBoundingClientRect().y + window.scrollY);\n const miny = Math.min(...ys);\n if (miny !== Infinity) {\n window.scroll(window.scrollX, miny > Form.SCROLL_OFFSET ? miny - Form.SCROLL_OFFSET : 0);\n }\n }\n}\n\nexport { Form };\n","import { Attributes, Fragments, Slots, templates, ParsedElement } from \"./elements.mjs\"\n\ntemplates.put('ful-input', Fragments.fromHtml(`\n <label data-tpl-for=\"id\" class=\"form-label\">{{{{ slotted.default }}}}</label>\n <div class=\"input-group\">\n <span data-tpl-if=\"slotted.ibefore\" class=\"input-group-text\">{{{{ slotted.ibefore }}}}</span>\n <div data-tpl-if=\"slotted.before\" data-tpl-remove=\"tag\">{{{{ slotted.before }}}}</div>\n {{{{ slotted.input }}}} \n <div data-tpl-if=\"slotted.after\" data-tpl-remove=\"tag\">{{{{ slotted.after }}}}</div>\n <span data-tpl-if=\"slotted.iafter\" class=\"input-group-text\">{{{{ slotted.iafter }}}}</span>\n </div>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error>\n`));\n\n\nconst makeInputFragment = (el, slotted) => {\n const input = el.input = slotted.input = slotted.input || (() => {\n const el = document.createElement(\"input\")\n el.classList.add(\"form-control\");\n return el;\n })();\n input.setAttribute('ful-validation-target', '');\n\n const id = input.getAttribute('id') || el.getAttribute('input-id') || Attributes.uid('ful-input');\n Attributes.forward('input-', el, slotted.input)\n Attributes.defaultValue(slotted.input, \"id\", id);\n Attributes.defaultValue(slotted.input, \"type\", \"text\");\n Attributes.defaultValue(slotted.input, \"placeholder\", \" \");\n const name = el.getAttribute('name');\n return templates.get('ful-input').render(el, { id, name, slotted });\n}\n\nclass Input extends ParsedElement([], ['value']) {\n render() {\n const slotted = Slots.from(this);\n const fragment = makeInputFragment(this, slotted);\n this.replaceChildren(fragment);\n }\n get value() {\n return this.input.value;\n }\n set value(value) {\n this.input.value = value;\n }\n}\n\nexport { makeInputFragment, Input };\n","import { Fragments, Attributes, Slots, templates, ParsedElement } from \"./elements.mjs\"\n\n/**\n * <script src=\"tom-select.complete.js\"></script>\n * <link href=\"tom-select.bootstrap5.css\" rel=\"stylesheet\" />\n */\n\ntemplates.put('ful-select', Fragments.fromHtml(`\n <label data-tpl-for=\"tsId\" class=\"form-label\">{{{{ slotted.default }}}}</label>\n {{{{ input }}}}\n <div class=\"input-group\">\n <span data-tpl-if=\"slotted.ibefore\" class=\"input-group-text\">{{{{ slotted.ibefore }}}}</span>\n <div data-tpl-if=\"slotted.before\" data-tpl-remove=\"tag\">{{{{ slotted.before }}}}</div>\n {{{{ slotted.input }}}} \n <div data-tpl-if=\"slotted.after\" data-tpl-remove=\"tag\">{{{{ slotted.after }}}}</div>\n <span data-tpl-if=\"slotted.iafter\" class=\"input-group-text\">{{{{ slotted.iafter }}}}</span>\n </div>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error> \n`));\n\n\nclass Select extends ParsedElement([], [\"value\"]) {\n constructor(tsConfig) {\n super();\n this.tsConfig = tsConfig;\n }\n render() {\n const slotted = Slots.from(this);\n\n const type = this.getAttribute(\"type\") || 'local';\n const remote = type != 'local';\n const loadOnce = this.getAttribute('load') != 'always';\n const name = this.getAttribute('name');\n const input = slotted.input = slotted.input || (() => {\n return document.createElement(\"select\");\n })();\n input.setAttribute('ful-validation-target', '');\n\n const id = input.getAttribute('id') || this.getAttribute('input-id') || Attributes.uid('ful-select');\n const tsId = `${id}-ts-control`;\n Attributes.forward('input-', this, input)\n Attributes.defaultValue(input, \"id\", id);\n Attributes.defaultValue(input, \"placeholder\", \" \");\n\n //tomselect needs the input to have a parent.\n //se we move the input to a fragment\n slotted.input = Fragments.from(input);\n\n this.loaded = !remote;\n\n const tsDefaultConfig = {\n render: {\n loading: () => '<ful-spinner class=\"centered p-2\"></ful-spinner>'\n }\n }\n\n this._remote = remote;\n // we need to await this load in setValue when remote is configured and the option\n // is not loaded yet.\n // tomselect settings.load does not retun a promise as it wraps the configured load function\n // with a debouncer\n this._unwrappedRemoteLoad = async (query, callback) => {\n\n if (!remote || remote && loadOnce && this.loaded) {\n callback();\n return;\n }\n const type = query && query.hasOwnProperty('byId') ? 'id' : 'query';\n const qvalue = type === 'id' ? query.byId : query;\n const data = await (this.loader ? this.loader(qvalue, type) : []);\n if (type !== 'id') {\n this.loaded = true;\n }\n callback(data);\n };\n\n\n this.ts = new TomSelect(input, Object.assign(remote ? {\n preload: 'focus',\n load: this._unwrappedRemoteLoad,\n shouldLoad: (query) => this.shouldLoad ? this.shouldLoad(query) : true\n } : {}, tsDefaultConfig, this.tsConfig));\n //we remove the input to move it\n input.remove();\n templates.get('ful-select').renderTo(this, { id, tsId, name, input, slotted });\n }\n set value(v) {\n (async () => {\n if (this._remote) {\n await this._unwrappedRemoteLoad({ byId: v }, this.ts.loadCallback.bind(this.ts));\n }\n this.ts.setValue(v);\n })();\n }\n get value() {\n const v = this.ts.getValue();\n return v === '' ? null : v;\n }\n}\n\nexport { Select };\n","import { Attributes, Slots, Fragments, templates, ParsedElement } from \"./elements.mjs\"\n\ntemplates.put('ful-radio-group', Fragments.fromHtml(`\n <fieldset>\n <legend class=\"form-label\">\n {{{{ slotted.default }}}}\n </legend>\n <header data-tpl-if=\"slotted.header\">\n {{{{ slotted.header }}}}\n </header>\n <section>\n <label data-tpl-each=\"inputsAndLabels\" data-tpl-var=\"ial\">\n {{{{ ial[0] }}}}\n {{{{ ial[1] }}}}\n </label>\n </section>\n <ful-field-error data-tpl-if=\"name\" data-tpl-field=\"name\"></ful-field-error>\n <footer data-tpl-if=\"slotted.footer\">\n {{{{ slotted.footer }}}}\n </footer>\n </fieldset>\n`));\n\n\nclass RadioGroup extends ParsedElement(['disabled'], ['value']) {\n render() {\n const slotted = Slots.from(this);\n const name = this.getAttribute('name') || Attributes.uid('ful-radiogroup');\n const radioEls = Array.from(slotted.default.querySelectorAll('ful-radio'));\n const inputsAndLabels = radioEls.map(el => {\n const input = document.createElement('input');\n input.setAttribute('type', 'radio');\n Attributes.forward('input-', this, input);\n Attributes.forward('', el, input);\n input.setAttribute('name', `${name}-ignore`);\n input.setAttribute('ful-validation-target', '');\n input.dataset['fulBindInclude'] = 'never';\n const label = Fragments.fromChildNodes(el);\n return [input, label];\n });\n radioEls.forEach(el => el.remove());\n templates.get('ful-radio-group').renderTo(this, {\n name: name,\n slotted: slotted,\n inputsAndLabels: inputsAndLabels\n });\n }\n get value() {\n const checked = this.querySelector('input[type=radio]:checked');\n return checked ? checked.value : null;\n }\n set value(value) {\n this.querySelector(`input[type=radio][value=${CSS.escape(value)}]`).checked = true;\n }\n}\n\n\nexport { RadioGroup };","import { Slots, Fragments, templates, ParsedElement } from \"./elements.mjs\"\n\ntemplates.put('ful-spinner', Fragments.fromHtml(`\n <div class=\"ful-spinner-wrapper\">\n <div class=\"ful-spinner-text\">{{{{ slotted.default }}}}</div>\n <div class=\"ful-spinner-icon\"></div>\n </div>\n`));\n\nclass Spinner extends ParsedElement() {\n render() {\n const slotted = Slots.from(this);\n templates.get('ful-spinner').renderTo(this, { slotted });\n }\n}\n\nexport { Spinner };","class Wizard extends HTMLElement {\n constructor() {\n super();\n this.progress = [...this.children].filter(e => e.matches(\"header,ol,ul\"));\n\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n if (current === undefined && children.length > 0) {\n children[0].classList.add('active');\n }\n });\n if (this.querySelector('section.current') === null) {\n const firstSection = this.querySelector('section:first-of-type');\n if (firstSection !== null) {\n firstSection.classList.add('current');\n }\n }\n }\n next() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.nextElementSibling?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.nextElementSibling.classList.add('current');\n\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n\n }\n prev() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.previousElementSibling?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.previousElementSibling.classList.add('current');\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n moveTo(n) {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n p.children[+n]?.classList.add('active');\n });\n const currentSection = this.querySelector('section.current');\n currentSection?.classList.remove(\"current\");\n const nthSection = this.querySelector(`section:nth-child(${+n})`);\n nthSection.classList.add('current');\n this.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n static configure() {\n return Wizard.custom('ful-wizard');\n }\n}\n\n\n\n\nexport { Wizard };\n","import { Spinner } from \"./spinner.mjs\";\nimport { Input } from \"./input.mjs\";\nimport { RadioGroup } from \"./radio.mjs\";\nimport { Select } from \"./select.mjs\";\nimport { Form } from \"./form.mjs\";\nimport { templates } from \"./elements.mjs\";\n\nexport class CustomElements {\n static configure(ec) {\n templates.configure(ec);\n customElements.define('ful-spinner', Spinner);\n customElements.define('ful-input', Input);\n customElements.define('ful-radio-group', RadioGroup);\n customElements.define('ful-select', Select);\n customElements.define('ful-form', Form);\n }\n}\n"],"names":["Base64","encode","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","i","substring","length","decode","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Hex","hex","Error","lenInBytes","map","e","offset","octet","parseInt","bytes","upper","Array","from","b","toString","toUpperCase","o","padStart","join","ContextInterceptor","constructor","context","document","querySelector","getAttribute","this","endsWith","intercept","request","chain","separator","resource","startsWith","proceed","CsrfTokenInterceptor","k","v","headers","Headers","options","set","RedirectOnUnauthorizedInterceptor","redirectUri","response","status","window","location","href","Failure","parseProblems","text","def","type","reason","details","JSON","parse","fromResponse","problems","super","stringify","name","HttpClientBuilder","interceptors","withContext","push","withCsrfToken","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","HttpInterceptorChain","current","interceptor","builder","exchange","opts","ok","message","json","undefined","jsonRequest","method","body","jsonPost","jsonPut","jsonPatch","Storage","prefix","storage","save","setItem","load","got","getItem","remove","removeItem","pop","decoded","LocalStorage","localStorage","SessionStorage","sessionStorage","VersionedStorage","key","dataSupplier","cache","revision","saved","value","freshData","data","AuthorizationCodeFlow","forKeycloak","clientId","realmBaseUrl","auth","URL","token","logout","registration","redirect","scope","uri","action","additionalParams","pkceVerifier","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","url","searchParams","Object","entries","forEach","kv","applicationInitiatedAction","kcAction","kc_action","_tokenExchange","code","history","replaceState","stateAndVerifier","URLSearchParams","AuthorizationCodeFlowSession","ensureLoggedIn","get","parseToken","rawHeader","rawPayload","signature","split","ut8decoder","TextDecoder","header","payload","t","accessToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","callback","refresh","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refreshIf","id_token","bearerToken","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","timing","sleep","ms","Promise","resolve","setTimeout","DEBOUNCE_DEFAULT","DEBOUNCE_IMMEDIATE","debounce","timeoutMs","func","tid","args","previousTimestamp","later","elapsed","arguments","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","THROTTLE_NO_TRAILING","throttle","remaining","clearTimeout","SyncEvent","CustomEvent","results","dispatchTo","el","dispatchEvent","all","on","h","useCapture","addEventListener","Fragments","fromHtml","html","createElement","innerHTML","fragment","DocumentFragment","append","childNodes","toHtml","r","appendChild","nodes","fromChildNodes","Attributes","static","uid","id","asBoolean","defaultValue","hasAttribute","setAttribute","forward","to","getAttributeNames","filter","a","target","classList","add","Slots","namedSlots","matches","slot","removeAttribute","slotted","fromEntries","default","Nodes","isParsed","c","parentNode","nextSibling","TemplateRegistry","idToFragment","idToTemplate","ec","put","ftl","Template","fromFragment","tpl","configure","templates","upgradeQueue","q","dequeue","bind","enqueue","requestAnimationFrame","splice","upgrade","ParsedElement","flags","others","observed_flags","observed_others","observed","concat","HTMLElement","observedAttributes","parsed","internals","attachInternals","connectedCallback","ownerDocument","readyState","observer","disconnect","MutationObserver","observe","childList","subtree","attributeChangedCallback","oldValue","newValue","render","flag","other","defineProperty","prototype","enumerable","configurable","states","has","delete","flatten","obj","keys","reduce","acc","pre","assign","mutate","raw","checked","Form","form","replaceChildren","async","preventDefault","spinner","submitter","values","errors","spin","querySelectorAll","hidden","disabled","vs","flattenedKey","CSS","escape","dataset","closest","IGNORED_CHILDREN_SELECTOR","result","path","match","previous","ckey","pkey","Number","isInteger","isArray","providePath","extract","es","fieldErrors","globalErrors","replace","validationTargetsSelector","input","fieldErrorsSelector","innerText","ys","parentElement","getBoundingClientRect","y","scrollY","miny","min","Infinity","scroll","scrollX","SCROLL_OFFSET","makeInputFragment","Input","Select","tsConfig","remote","loadOnce","tsId","loaded","_remote","_unwrappedRemoteLoad","query","hasOwnProperty","qvalue","byId","loader","ts","TomSelect","preload","shouldLoad","loading","renderTo","loadCallback","setValue","getValue","RadioGroup","radioEls","inputsAndLabels","Spinner","Wizard","progress","children","p","firstSection","next","nextElementSibling","currentSection","bubbles","cancelable","prev","previousElementSibling","moveTo","n","custom","CustomElements","customElements","define"],"mappings":"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"}
|
package/dist/ful.mjs
CHANGED
|
@@ -665,6 +665,38 @@ class Nodes {
|
|
|
665
665
|
}
|
|
666
666
|
}
|
|
667
667
|
|
|
668
|
+
class TemplateRegistry {
|
|
669
|
+
#idToFragment = {};
|
|
670
|
+
#idToTemplate = {};
|
|
671
|
+
#ec;
|
|
672
|
+
put(k, fragment) {
|
|
673
|
+
if (this.#ec) {
|
|
674
|
+
this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, ec);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
this.#idToFragment[k] = fragment;
|
|
678
|
+
}
|
|
679
|
+
get(k) {
|
|
680
|
+
if (!this.#ec) {
|
|
681
|
+
throw new Error("evaluationContext is not configured");
|
|
682
|
+
}
|
|
683
|
+
const tpl = this.#idToTemplate[k];
|
|
684
|
+
if (!tpl) {
|
|
685
|
+
throw new Error(`missing template: '${k}'`);
|
|
686
|
+
}
|
|
687
|
+
return tpl;
|
|
688
|
+
}
|
|
689
|
+
configure(ec) {
|
|
690
|
+
this.#ec = ec;
|
|
691
|
+
for (const [k, fragment] of Object.entries(this.#idToFragment)) {
|
|
692
|
+
delete this.#idToFragment[k];
|
|
693
|
+
this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, ec);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const templates = new TemplateRegistry();
|
|
699
|
+
|
|
668
700
|
class UpgradeQueue {
|
|
669
701
|
#q = [];
|
|
670
702
|
constructor() {
|
|
@@ -918,11 +950,7 @@ class Form extends ParsedElement() {
|
|
|
918
950
|
}
|
|
919
951
|
}
|
|
920
952
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
});
|
|
924
|
-
|
|
925
|
-
const template$1 = globalThis.ful_input_template || ftl.Template.fromHtml(`
|
|
953
|
+
templates.put('ful-input', Fragments.fromHtml(`
|
|
926
954
|
<label data-tpl-for="id" class="form-label">{{{{ slotted.default }}}}</label>
|
|
927
955
|
<div class="input-group">
|
|
928
956
|
<span data-tpl-if="slotted.ibefore" class="input-group-text">{{{{ slotted.ibefore }}}}</span>
|
|
@@ -932,11 +960,10 @@ const template$1 = globalThis.ful_input_template || ftl.Template.fromHtml(`
|
|
|
932
960
|
<span data-tpl-if="slotted.iafter" class="input-group-text">{{{{ slotted.iafter }}}}</span>
|
|
933
961
|
</div>
|
|
934
962
|
<ful-field-error data-tpl-if="name" data-tpl-field="name"></ful-field-error>
|
|
935
|
-
|
|
963
|
+
`));
|
|
936
964
|
|
|
937
|
-
const renderInput = (el) => {
|
|
938
|
-
const slotted = Slots.from(el);
|
|
939
965
|
|
|
966
|
+
const makeInputFragment = (el, slotted) => {
|
|
940
967
|
const input = el.input = slotted.input = slotted.input || (() => {
|
|
941
968
|
const el = document.createElement("input");
|
|
942
969
|
el.classList.add("form-control");
|
|
@@ -950,18 +977,14 @@ const renderInput = (el) => {
|
|
|
950
977
|
Attributes.defaultValue(slotted.input, "type", "text");
|
|
951
978
|
Attributes.defaultValue(slotted.input, "placeholder", " ");
|
|
952
979
|
const name = el.getAttribute('name');
|
|
953
|
-
|
|
980
|
+
return templates.get('ful-input').render(el, { id, name, slotted });
|
|
954
981
|
};
|
|
955
982
|
|
|
956
|
-
class StatelessInput extends ParsedElement() {
|
|
957
|
-
render() {
|
|
958
|
-
renderInput(this);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
|
|
962
983
|
class Input extends ParsedElement([], ['value']) {
|
|
963
984
|
render() {
|
|
964
|
-
|
|
985
|
+
const slotted = Slots.from(this);
|
|
986
|
+
const fragment = makeInputFragment(this, slotted);
|
|
987
|
+
this.replaceChildren(fragment);
|
|
965
988
|
}
|
|
966
989
|
get value() {
|
|
967
990
|
return this.input.value;
|
|
@@ -975,11 +998,8 @@ class Input extends ParsedElement([], ['value']) {
|
|
|
975
998
|
* <script src="tom-select.complete.js"></script>
|
|
976
999
|
* <link href="tom-select.bootstrap5.css" rel="stylesheet" />
|
|
977
1000
|
*/
|
|
978
|
-
const ful_select_ec = globalThis.ec || ftl.EvaluationContext.configure({
|
|
979
|
-
|
|
980
|
-
});
|
|
981
1001
|
|
|
982
|
-
|
|
1002
|
+
templates.put('ful-select', Fragments.fromHtml(`
|
|
983
1003
|
<label data-tpl-for="tsId" class="form-label">{{{{ slotted.default }}}}</label>
|
|
984
1004
|
{{{{ input }}}}
|
|
985
1005
|
<div class="input-group">
|
|
@@ -990,7 +1010,7 @@ const ful_select_template_ = globalThis.ful_select_template || ftl.Template.from
|
|
|
990
1010
|
<span data-tpl-if="slotted.iafter" class="input-group-text">{{{{ slotted.iafter }}}}</span>
|
|
991
1011
|
</div>
|
|
992
1012
|
<ful-field-error data-tpl-if="name" data-tpl-field="name"></ful-field-error>
|
|
993
|
-
|
|
1013
|
+
`));
|
|
994
1014
|
|
|
995
1015
|
|
|
996
1016
|
class Select extends ParsedElement([], ["value"]) {
|
|
@@ -1056,7 +1076,7 @@ class Select extends ParsedElement([], ["value"]) {
|
|
|
1056
1076
|
} : {}, tsDefaultConfig, this.tsConfig));
|
|
1057
1077
|
//we remove the input to move it
|
|
1058
1078
|
input.remove();
|
|
1059
|
-
|
|
1079
|
+
templates.get('ful-select').renderTo(this, { id, tsId, name, input, slotted });
|
|
1060
1080
|
}
|
|
1061
1081
|
set value(v) {
|
|
1062
1082
|
(async () => {
|
|
@@ -1072,11 +1092,7 @@ class Select extends ParsedElement([], ["value"]) {
|
|
|
1072
1092
|
}
|
|
1073
1093
|
}
|
|
1074
1094
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
});
|
|
1078
|
-
|
|
1079
|
-
const ful_radiougroup_template_ = globalThis.ful_radiogroup_template || ftl.Template.fromHtml(`
|
|
1095
|
+
templates.put('ful-radio-group', Fragments.fromHtml(`
|
|
1080
1096
|
<fieldset>
|
|
1081
1097
|
<legend class="form-label">
|
|
1082
1098
|
{{{{ slotted.default }}}}
|
|
@@ -1095,7 +1111,7 @@ const ful_radiougroup_template_ = globalThis.ful_radiogroup_template || ftl.Temp
|
|
|
1095
1111
|
{{{{ slotted.footer }}}}
|
|
1096
1112
|
</footer>
|
|
1097
1113
|
</fieldset>
|
|
1098
|
-
|
|
1114
|
+
`));
|
|
1099
1115
|
|
|
1100
1116
|
|
|
1101
1117
|
class RadioGroup extends ParsedElement(['disabled'], ['value']) {
|
|
@@ -1115,8 +1131,7 @@ class RadioGroup extends ParsedElement(['disabled'], ['value']) {
|
|
|
1115
1131
|
return [input, label];
|
|
1116
1132
|
});
|
|
1117
1133
|
radioEls.forEach(el => el.remove());
|
|
1118
|
-
|
|
1119
|
-
ful_radiougroup_template_.renderTo(this, {
|
|
1134
|
+
templates.get('ful-radio-group').renderTo(this, {
|
|
1120
1135
|
name: name,
|
|
1121
1136
|
slotted: slotted,
|
|
1122
1137
|
inputsAndLabels: inputsAndLabels
|
|
@@ -1131,22 +1146,17 @@ class RadioGroup extends ParsedElement(['disabled'], ['value']) {
|
|
|
1131
1146
|
}
|
|
1132
1147
|
}
|
|
1133
1148
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
});
|
|
1137
|
-
|
|
1138
|
-
const template = globalThis.ful_spinner_template || ftl.Template.fromHtml(`
|
|
1149
|
+
templates.put('ful-spinner', Fragments.fromHtml(`
|
|
1139
1150
|
<div class="ful-spinner-wrapper">
|
|
1140
1151
|
<div class="ful-spinner-text">{{{{ slotted.default }}}}</div>
|
|
1141
1152
|
<div class="ful-spinner-icon"></div>
|
|
1142
1153
|
</div>
|
|
1143
|
-
|
|
1144
|
-
|
|
1154
|
+
`));
|
|
1145
1155
|
|
|
1146
1156
|
class Spinner extends ParsedElement() {
|
|
1147
1157
|
render() {
|
|
1148
1158
|
const slotted = Slots.from(this);
|
|
1149
|
-
|
|
1159
|
+
templates.get('ful-spinner').renderTo(this, { slotted });
|
|
1150
1160
|
}
|
|
1151
1161
|
}
|
|
1152
1162
|
|
|
@@ -1223,7 +1233,8 @@ class Wizard extends HTMLElement {
|
|
|
1223
1233
|
}
|
|
1224
1234
|
|
|
1225
1235
|
class CustomElements {
|
|
1226
|
-
static configure() {
|
|
1236
|
+
static configure(ec) {
|
|
1237
|
+
templates.configure(ec);
|
|
1227
1238
|
customElements.define('ful-spinner', Spinner);
|
|
1228
1239
|
customElements.define('ful-input', Input);
|
|
1229
1240
|
customElements.define('ful-radio-group', RadioGroup);
|
|
@@ -1232,5 +1243,5 @@ class CustomElements {
|
|
|
1232
1243
|
}
|
|
1233
1244
|
}
|
|
1234
1245
|
|
|
1235
|
-
export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, CustomElements, Failure, Form, Fragments, Hex, HttpClient, Input, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Slots, Spinner,
|
|
1246
|
+
export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, CustomElements, Failure, Form, Fragments, Hex, HttpClient, Input, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Slots, Spinner, SyncEvent, TemplateRegistry, VersionedStorage, Wizard, jsonPatch, jsonPost, jsonPut, jsonRequest, makeInputFragment, templates, timing };
|
|
1236
1247
|
//# sourceMappingURL=ful.mjs.map
|