@loadbare/app 0.8.2 → 0.10.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/README.md +3 -3
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +74 -66
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/expand.d.ts.map +1 -1
- package/dist/build/expand.js +20 -19
- package/dist/build/expand.js.map +1 -1
- package/dist/build/locations.d.ts +2 -3
- package/dist/build/locations.d.ts.map +1 -1
- package/dist/build/locations.js +2 -3
- package/dist/build/locations.js.map +1 -1
- package/dist/build/pages.d.ts +3 -4
- package/dist/build/pages.d.ts.map +1 -1
- package/dist/build/pages.js +3 -4
- package/dist/build/pages.js.map +1 -1
- package/dist/core/lb-constants.d.ts +25 -23
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +95 -158
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +73 -75
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +58 -5
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +47 -37
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +174 -193
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +419 -415
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/server/lb-express.d.ts +20 -13
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +50 -52
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +81 -116
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +151 -48
- package/dist/server/lb-server.js.map +1 -1
- package/docs/TECHREF-1.0.md +893 -558
- package/docs/comparison.md +222 -185
- package/docs/prior-art.md +15 -14
- package/docs/reference/builder.md +9 -3
- package/docs/reference/chrome.md +107 -56
- package/docs/reference/custom-elements.md +199 -173
- package/docs/reference/data-binding.md +375 -370
- package/docs/reference/overview.md +12 -10
- package/docs/reference/page-files.md +161 -86
- package/docs/reference/server.md +13 -7
- package/docs/reference/widgets.md +104 -110
- package/docs/roadmap.md +36 -31
- package/docs/terms-of-art.md +57 -0
- package/docs/testing.md +97 -68
- package/docs/theory.md +92 -58
- package/docs/tutorials/010-pages-and-navigation.md +20 -12
- package/docs/tutorials/020-css.md +6 -3
- package/docs/tutorials/030-html-decomposition.md +9 -7
- package/docs/tutorials/040-displaying-data.md +30 -13
- package/docs/tutorials/{050-actions.md → 050-requests.md} +25 -15
- package/docs/tutorials/060-custom-element-code.md +17 -16
- package/docs/tutorials/065-conditional-rendering.md +34 -23
- package/docs/tutorials/070-displaying-a-list.md +29 -21
- package/docs/tutorials/072-inserting-into-a-list.md +24 -16
- package/docs/tutorials/074-deleting-from-a-list.md +9 -7
- package/docs/tutorials/076-updating-a-list-item.md +11 -10
- package/docs/tutorials/080-widget-requests.md +71 -43
- package/docs/tutorials/090-using-widget-libraries.md +22 -22
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +178 -111
- package/skills/loadbare-app/references/TECHREF-1.0.md +893 -558
- package/skills/loadbare-app/references/builder.md +9 -3
- package/skills/loadbare-app/references/chrome.md +107 -56
- package/skills/loadbare-app/references/custom-elements.md +199 -173
- package/skills/loadbare-app/references/data-binding.md +375 -370
- package/skills/loadbare-app/references/overview.md +12 -10
- package/skills/loadbare-app/references/page-files.md +161 -86
- package/skills/loadbare-app/references/server.md +13 -7
- package/skills/loadbare-app/references/widgets.md +104 -110
- package/docs/analysis-accidental-complexity.md +0 -149
- package/docs/analysis-closed-set.md +0 -210
package/dist/hub/lb-apply.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lb-apply.js","sourceRoot":"","sources":["../../hub/lb-apply.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\n\n/**\n * Landing data on a live host — see docs/reference/data-binding.md.\n *\n * One containment ladder, and one function per rung. `applyData` lands a\n * whole response, `applyList` lands one list result, `applyRow` fills one\n * scope from one row. Filling a live row and filling a single-row scope are\n * the same operation, and the only difference is how much of the page the\n * root covers.\n *\n * The row machinery used to live in its own file because every list widget\n * imported and called it. The hub reconciles a list scope itself now, so a\n * widget supplies placement and scaffolding through two optional hooks and\n * never sees a whole result. Cloning the template, matching a row to the\n * element already showing it, and filling that element are the same in every\n * list, so no widget can get them wrong.\n *\n * A condition is the one other thing landing moves. An element whose\n * `lb-show` column is off stands in the document inside a template, and\n * landing reaches in there as it reaches everywhere else, so a branch that\n * returns is already current. Nothing but landing reaches in.\n */\n\nimport {\n ATTR_CELL,\n ATTR_KEY,\n ATTR_KEY_VALUE,\n ATTR_LIST,\n ATTR_QUERY_PARM,\n ATTR_ROW,\n ATTR_ROW_COUNT,\n ATTR_SHOW,\n ATTR_VALUE,\n} from \"../core/lb-constants.js\";\nimport {\n isPatch,\n type HubData,\n type ListHost,\n type ListResult,\n type Row,\n} from \"../core/lb-types.js\";\n\n/** The template holding an absent branch — see ATTR_SHOW. */\nconst PARKED = `template[${ATTR_SHOW}]`;\n\n/** A DocumentFragment's nodeType. Tier 3 has no `Node` global to read it from. */\nconst FRAGMENT_NODE = 11;\n\n/** The input types whose state is not their `value`, or cannot be set. */\nconst UNLANDED_INPUTS = [\"checkbox\", \"radio\", \"file\"];\n\n/**\n * A form control whose state is its `value`: a `<select>`, a `<textarea>`,\n * or an `<input>` of any type but checkbox, radio and file. Landing and\n * gathering draw the same line, so a value read back from a form is the one\n * that landed there.\n *\n * Told apart by tag name and type rather than by class, so it holds for an\n * element from any document.\n */\nexport function isValueControl(\n el: Element,\n): el is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement {\n if (el.localName === \"select\" || el.localName === \"textarea\") return true;\n return (\n el.localName === \"input\" &&\n !UNLANDED_INPUTS.includes((el as HTMLInputElement).type)\n );\n}\n\n/**\n * A cell lands one of three ways. A custom element owns whatever control it\n * wraps, so it receives the value as an attribute and renders it itself.\n * Because the browser runs `attributeChangedCallback` for attributes already\n * present when a widget upgrades, that is the same operation whether the host\n * was inserted a microsecond ago or an hour ago.\n *\n * A form control shows its state as its `value`, so that is where the value\n * goes; its text is its options, for a select. Any other native element has\n * no behavior of its own, so its value is its text. Either one also carries\n * the value as `lb-value`, so a stylesheet can select on what landed.\n * Checkboxes and radio buttons are not implemented, and receive nothing — see\n * docs/TECHREF-1.0.md, \"Blockers\".\n */\nfunction land(el: Element, value: unknown): void {\n // Untouched, whatever the server sent: the browser decides what a\n // non-string looks like. See Row in core/lb-types.ts.\n if (el.localName.includes(\"-\")) {\n el.setAttribute(ATTR_VALUE, value as string);\n } else if (isValueControl(el)) {\n el.value = value as string;\n el.setAttribute(ATTR_VALUE, value as string);\n } else if (el.localName === \"input\") {\n console.warn(\n `lb-hub: a value does not land on <input type=\"${(el as HTMLInputElement).type}\">, ignoring`,\n el,\n );\n } else {\n el.textContent = value as string;\n el.setAttribute(ATTR_VALUE, value as string);\n }\n}\n\n/**\n * Whether an element under `root` belongs to root's scope, rather than to a\n * scope nested inside it.\n *\n * Both scope attributes scope their DOM children, and a nested one of either\n * kind begins a new scope (docs/reference/data-binding.md). So a descendant\n * is in root's scope unless something between it and root carries one. The\n * element's own attribute does not count: it names what the element\n * displays, and where it belongs is its ancestors', so a picker carrying\n * `lb-list` and `lb-cell` is a cell of the row around it. Root's own\n * attribute does not count either: root is the scope being filled, whatever\n * it carries.\n *\n * Root may be the content of a template holding an absent branch. The walk\n * up from an element inside it stops at the top of that content, which has\n * no parent, and the template it stands for was in scope already.\n */\nfunction inScope(root: Element | DocumentFragment, el: Element): boolean {\n for (let node = el.parentElement; node && node !== root;) {\n if (node.hasAttribute(ATTR_LIST) || node.hasAttribute(ATTR_ROW)) {\n return false;\n }\n node = node.parentElement;\n }\n return true;\n}\n\n/**\n * Root if it matches, then every descendant in root's scope that does.\n * Gathering finds cells through here. It does not reach into an absent\n * branch, so a form reads back from the places a row lands that are showing.\n */\nexport function within(root: Element, selector: string): Element[] {\n const found: Element[] = root.matches(selector) ? [root] : [];\n for (const el of root.querySelectorAll(selector)) {\n if (inScope(root, el)) found.push(el);\n }\n return found;\n}\n\n/**\n * Every descendant in root's scope that matches, absent branches included.\n *\n * `querySelectorAll` does not enter template content, so an element that is\n * off would otherwise miss everything landed while it was away, and return\n * stale or with its lists empty. A template holding one is in root's scope by\n * the ordinary rule, and its content is searched as if it stood there.\n */\nfunction below(root: Element | DocumentFragment, selector: string): Element[] {\n const found: Element[] = [];\n for (const el of root.querySelectorAll(selector)) {\n if (inScope(root, el)) found.push(el);\n }\n for (const parked of root.querySelectorAll(PARKED)) {\n if (inScope(root, parked)) {\n found.push(...below((parked as HTMLTemplateElement).content, selector));\n }\n }\n return found;\n}\n\n/** What `within` is for gathering, `reach` is for landing. */\nfunction reach(root: Element, selector: string): Element[] {\n const found = below(root, selector);\n return root.matches(selector) ? [root, ...found] : found;\n}\n\n/**\n * Every element in a whole response's root that matches, absent branches\n * included. A name is looked up this way before any scope is known, so\n * nothing is filtered out by scope.\n */\nfunction everywhere(root: ParentNode, selector: string): Element[] {\n const found = [...root.querySelectorAll(selector)];\n for (const parked of root.querySelectorAll(PARKED)) {\n const content = (parked as HTMLTemplateElement).content;\n found.push(...everywhere(content, selector));\n }\n return found;\n}\n\n/**\n * Put an element in the document or take it out, as its `lb-show` column\n * says.\n *\n * Off is inside a template that stands where the element stood, carrying the\n * same `lb-show`. The element is moved rather than rebuilt, so a widget keeps\n * its instance and a control keeps what was typed into it. On moves it back\n * and the template goes.\n *\n * Landing reaches into that template, so both it and the element it holds\n * arrive here. The template decides; the element it holds, whose parent is\n * the template's content, is left to it.\n */\nfunction present(el: Element, on: boolean): void {\n if (el.localName === \"template\") {\n const branch = (el as HTMLTemplateElement).content.firstElementChild;\n if (on && branch) el.replaceWith(branch);\n return;\n }\n if (on || el.parentNode?.nodeType === FRAGMENT_NODE) return;\n const parked = el.ownerDocument.createElement(\"template\");\n parked.setAttribute(ATTR_SHOW, el.getAttribute(ATTR_SHOW)!);\n el.replaceWith(parked);\n parked.content.append(el);\n}\n\n/**\n * Fill one scope from one row.\n *\n * The root counts as a cell if it carries one. A `<tr>` holds its cells in\n * `<td>` children, but `<option>`'s content model is text, so an option row\n * has to be the cell it displays. Requiring a wrapper there would require an\n * element HTML does not allow.\n */\nexport function applyRow(root: Element, row: Row): void {\n for (const [column, value] of Object.entries(row)) {\n for (const el of reach(root, `[${ATTR_CELL}=\"${column}\"]`)) {\n land(el, value);\n }\n // Only null and false are off. A string is never read, so \"false\" is on,\n // and the query spells a condition as a boolean or a null.\n //\n // Never the root's own: a scope's condition is a cell of the row around\n // it, the way its lb-cell is, and a row template's root carries none.\n const on = value !== null && value !== false;\n for (const el of below(root, `[${ATTR_SHOW}=\"${column}\"]`)) {\n present(el, on);\n }\n }\n}\n\n/**\n * The row template: the one the developer wrote inside this list scope, or\n * null when this scope shows nothing. A template inside a nested scope is\n * that scope's, and a template holding an absent branch is not a row\n * template: rows land before the row template, so one inside the first live\n * row comes first in document order.\n *\n * A scope with no template is bound to the list without displaying it.\n * That is not a mistake, so it is silent. A template that does not name its\n * key column is a mistake, and says so.\n */\nfunction templateIn(scope: Element): HTMLTemplateElement | null {\n const template = within(scope, `template:not([${ATTR_SHOW}])`)[0] as\n HTMLTemplateElement | undefined;\n if (!template) return null;\n if (!template.getAttribute(ATTR_KEY)) {\n console.error(\n `lb-hub: the <template> in <${scope.localName}> has no ${ATTR_KEY} ` +\n `naming the column that identifies a row`,\n );\n return null;\n }\n return template;\n}\n\n/**\n * The rows already showing, by the key value each carries. Only a live row\n * carries one: the template names the key column under a different name.\n *\n * A row of a nested scope is that scope's. A row's own `lb-list` or `lb-row`\n * names what it displays, not which list it is a row of, which is the same\n * test a cell gets.\n */\nfunction showing(scope: Element): Map<string, Element> {\n const rows = new Map<string, Element>();\n for (const el of scope.querySelectorAll(`[${ATTR_KEY_VALUE}]`)) {\n if (inScope(scope, el)) {\n rows.set(el.getAttribute(ATTR_KEY_VALUE)!, el);\n }\n }\n return rows;\n}\n\n/**\n * Land a list result in a list scope.\n *\n * An array is the whole set, so it decides membership and order: every row is\n * placed in the order given, and a row whose key did not arrive is gone. A\n * patch disturbs only what it names — a row it did not mention keeps its\n * contents and its position.\n *\n * A widget that carries `lbPlaceRow` decides where a row goes, because only\n * it knows whether it sorts or groups. Without it a row lands immediately\n * before the template, so rows accumulate in the order they arrive and the\n * template stays put as the insertion marker.\n */\nexport function applyList(scope: Element, result: ListResult): void {\n const template = templateIn(scope);\n if (!template) return;\n const keyColumn = template.getAttribute(ATTR_KEY)!;\n const shown = showing(scope);\n const host = scope as Element & ListHost;\n const whole = !isPatch(result);\n\n const place = (el: Element, row: Row): void => {\n if (host.lbPlaceRow) host.lbPlaceRow(el, row, template);\n else template.parentElement!.insertBefore(el, template);\n };\n\n const upsert = (row: Row): string | null => {\n if (row[keyColumn] === undefined) {\n console.error(\n `lb-hub: a row for <${scope.localName}> has no '${keyColumn}' column`,\n );\n return null;\n }\n // The key is stored on the row as an attribute and read back from\n // there, so it is compared as the string the attribute holds.\n const key = String(row[keyColumn]);\n let el = shown.get(key);\n const fresh = el === undefined;\n if (!el) {\n el = template.content.firstElementChild!.cloneNode(true) as Element;\n el.setAttribute(ATTR_KEY_VALUE, key);\n shown.set(key, el);\n }\n // Fill before insertion. The attributes are already there when the row\n // upgrades, which is the same thing that makes hydration and refresh one\n // operation everywhere else.\n applyRow(el, row);\n if (fresh || whole) place(el, row);\n return key;\n };\n\n if (Array.isArray(result)) {\n const arrived = new Set<string>();\n for (const row of result) {\n const key = upsert(row);\n if (key !== null) arrived.add(key);\n }\n for (const [key, el] of shown) if (!arrived.has(key)) el.remove();\n } else {\n for (const row of result.rows ?? []) upsert(row);\n for (const key of result.drop ?? []) shown.get(String(key))?.remove();\n }\n\n // How many rows are showing, counted from the DOM rather than from either\n // branch above, so a whole set and a patch report the same fact the same\n // way.\n //\n // It is stamped here because only this function knows the count: it is the\n // one conditional a page cannot be sent, since the server answers with rows\n // and says nothing about how many survived reconciliation. A page says what\n // an empty list looks like in a stylesheet, and no list widget carries code\n // for it. See docs/reference/data-binding.md.\n scope.setAttribute(ATTR_ROW_COUNT, String(showing(scope).size));\n\n // Derived scaffolding — a section heading, an <optgroup> — goes when its\n // last row does, and only the widget knows it exists.\n host.lbRowsLanded?.();\n}\n\n/** Land a whole response. Every result arrives through here. */\nexport function applyData(root: ParentNode, data: HubData): void {\n for (const [name, result] of Object.entries(data)) {\n const lists = everywhere(root, `[${ATTR_LIST}=\"${name}\"]`);\n const rows = everywhere(root, `[${ATTR_ROW}=\"${name}\"]`);\n if (lists.length === 0 && rows.length === 0) {\n console.warn(`lb-hub: no scope for '${name}', skipping`);\n continue;\n }\n // Cardinality is a property of the name, so one name is a list or a row\n // and never both. Two spellings of it on one page is a mistake in the\n // markup rather than a case to reconcile.\n if (lists.length > 0 && rows.length > 0) {\n console.error(\n `lb-hub: '${name}' is bound as a list in one place and a row in ` +\n `another; a name answers with one shape`,\n );\n continue;\n }\n if (lists.length > 0) {\n for (const scope of lists) applyList(scope, result as ListResult);\n continue;\n }\n // The only disagreement visible from here: a patch and a row are both\n // objects, so an array arriving at a row scope is the one case the\n // browser can name. createHub holds the stronger check, because it knows\n // what the query declared.\n if (Array.isArray(result)) {\n console.error(\n `lb-hub: '${name}' is bound with ${ATTR_ROW} but answered with rows`,\n );\n continue;\n }\n for (const scope of rows) applyRow(scope, result as Row);\n }\n}\n\n/**\n * Land the query string on every control that writes one of its parms, the\n * way a cell lands a column. A parm the URL does not carry lands empty, so a\n * control shows what the address bar says after Back as well as after a\n * reload: the URL is what is on screen, and nothing else is.\n *\n * Landed after the page's data, so a picker already has the options its\n * value selects.\n */\nexport function applyQueryParms(\n root: ParentNode,\n parms: URLSearchParams,\n): void {\n for (const el of everywhere(root, `[${ATTR_QUERY_PARM}]`)) {\n land(el, parms.get(el.getAttribute(ATTR_QUERY_PARM)!) ?? \"\");\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lb-apply.js","sourceRoot":"","sources":["../../hub/lb-apply.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\n\n/**\n * Landing — see docs/reference/data-binding.md.\n *\n * The hub lands a response item's rows on every element whose `lb-query`\n * names its query. The item says the query's kind and key, so the markup\n * says neither:\n *\n * kind row template the hub\n * row no lands the row on the element itself\n * row yes lands one live row\n * rows yes lands one live row per row\n * rows no lands nothing\n *\n * Filling a live row and filling an element a `row` lands on are the same\n * operation, and the only difference is how much of the page the root\n * covers.\n *\n * A condition is the one other thing landing moves. An element whose\n * `lb-show` column is off stands in the document inside a template, and\n * landing reaches in there as it reaches everywhere else, so a branch that\n * returns is already current. Nothing but landing reaches in.\n */\n\nimport {\n ATTR_COLUMN,\n ATTR_COLUMN_VALUE,\n ATTR_KEY_VALUE,\n ATTR_QUERY,\n ATTR_QUERY_ROW_COUNT,\n ATTR_SHOW,\n KIND_ROW,\n} from \"../core/lb-constants.js\";\nimport {\n isPatch,\n type ResponseItem,\n type Row,\n type RowsHost,\n type RowsResult,\n} from \"../core/lb-types.js\";\n\n/** The template holding an absent branch — see ATTR_SHOW. */\nconst PARKED = `template[${ATTR_SHOW}]`;\n\n/** A DocumentFragment's nodeType. Tier 3 has no `Node` global to read it from. */\nconst FRAGMENT_NODE = 11;\n\n/** The input types whose state is not their `value`, or cannot be set. */\nconst UNLANDED_INPUTS = [\"checkbox\", \"radio\", \"file\"];\n\n/** A control's value, whether it is native or a custom element. */\nexport interface Control extends Element {\n value: string;\n}\n\n/**\n * A native control whose state is its `value`: a `<select>`, a\n * `<textarea>`, or an `<input>` of any type but checkbox, radio and file.\n *\n * Told apart by tag name and type rather than by class, so it holds for an\n * element from any document.\n */\nfunction isNativeControl(el: Element): boolean {\n if (el.localName === \"select\" || el.localName === \"textarea\") return true;\n return (\n el.localName === \"input\" &&\n !UNLANDED_INPUTS.includes((el as HTMLInputElement).type)\n );\n}\n\n/**\n * A form-associated custom element with a `value` property. HTML marks one\n * with `static formAssociated = true` on its class, and a control has a value.\n */\nexport function isFormAssociated(el: Element): boolean {\n const ctor = el.constructor as { formAssociated?: unknown };\n return ctor.formAssociated === true && \"value\" in el;\n}\n\n/**\n * A control: an `<input>`, `<select>` or `<textarea>`, or a form-associated\n * custom element with a `value` property. Landing and gathering draw the\n * same line, so a value read back is the one that landed there.\n */\nexport function isControl(el: Element): el is Control {\n return isNativeControl(el) || isFormAssociated(el);\n}\n\n/**\n * Set an element from a column. A control's `value` is set. A custom element\n * that is not a control keeps its content, which the builder placed there\n * from its element file, and renders the stamp instead. Any other element's\n * text content is set. Every one carries the value as `lb-column-value`.\n */\nfunction land(el: Element, value: unknown): void {\n // Untouched, whatever the server sent: the browser decides what a\n // non-string looks like. See Row in core/lb-types.ts.\n if (value === null || value === undefined) {\n if (isControl(el)) el.value = \"\";\n else if (!el.localName.includes(\"-\") && el.localName !== \"input\") {\n el.textContent = \"\";\n }\n el.removeAttribute(ATTR_COLUMN_VALUE);\n return;\n }\n if (isControl(el)) {\n el.value = value as string;\n } else if (el.localName === \"input\") {\n console.warn(\n `lb-hub: a value does not land on <input type=\"${(el as HTMLInputElement).type}\">, ignoring`,\n el,\n );\n return;\n } else if (!el.localName.includes(\"-\")) {\n el.textContent = value as string;\n }\n el.setAttribute(ATTR_COLUMN_VALUE, value as string);\n}\n\n/**\n * Whether an element under `root` belongs to root's query, rather than to a\n * query nested inside it.\n *\n * A descendant is root's unless something between it and root carries\n * `lb-query`. The element's own `lb-query` does not count: it names what the\n * element holds, and the row it reads from is its ancestors'. So a picker\n * carrying `lb-query` and `lb-column` is set from the row around it. Root's\n * own attribute does not count either: root is what is being filled.\n *\n * Root may be the content of a template holding an absent branch. The walk\n * up from an element inside it stops at the top of that content, which has\n * no parent, and the template it stands for was in scope already.\n */\nfunction inScope(root: Element | DocumentFragment, el: Element): boolean {\n for (let node = el.parentElement; node && node !== root;) {\n if (node.hasAttribute(ATTR_QUERY)) return false;\n node = node.parentElement;\n }\n return true;\n}\n\n/**\n * Root if it matches, then every descendant in root's query that does.\n * Gathering finds columns through here. It does not reach into an absent\n * branch, so a live row is read back from the places a row lands that are\n * showing.\n */\nexport function within(root: Element, selector: string): Element[] {\n const found: Element[] = root.matches(selector) ? [root] : [];\n for (const el of root.querySelectorAll(selector)) {\n if (inScope(root, el)) found.push(el);\n }\n return found;\n}\n\n/**\n * Every descendant in root's query that matches, absent branches included.\n *\n * `querySelectorAll` does not enter template content, so an element that is\n * off would otherwise miss everything landed while it was away, and return\n * stale or with its rows empty. A template holding one is in root's query by\n * the ordinary rule, and its content is searched as if it stood there.\n */\nfunction below(root: Element | DocumentFragment, selector: string): Element[] {\n const found: Element[] = [];\n for (const el of root.querySelectorAll(selector)) {\n if (inScope(root, el)) found.push(el);\n }\n for (const parked of root.querySelectorAll(PARKED)) {\n if (inScope(root, parked)) {\n found.push(...below((parked as HTMLTemplateElement).content, selector));\n }\n }\n return found;\n}\n\n/**\n * Every element in root that matches, absent branches included. A query is\n * looked up this way before any row is known, so nothing is filtered out.\n */\nfunction everywhere(root: ParentNode, selector: string): Element[] {\n const found = [...root.querySelectorAll(selector)];\n for (const parked of root.querySelectorAll(PARKED)) {\n const content = (parked as HTMLTemplateElement).content;\n found.push(...everywhere(content, selector));\n }\n return found;\n}\n\n/**\n * Put an element in the document or take it out, as its `lb-show` column\n * says.\n *\n * Off is inside a template that stands where the element stood, carrying the\n * same `lb-show`. The element is moved rather than rebuilt, so a custom\n * element keeps its instance and a control keeps what was typed into it. On\n * moves it back and the template goes.\n *\n * Landing reaches into that template, so both it and the element it holds\n * arrive here. The template decides; the element it holds, whose parent is\n * the template's content, is left to it.\n */\nfunction present(el: Element, on: boolean): void {\n if (el.localName === \"template\") {\n const branch = (el as HTMLTemplateElement).content.firstElementChild;\n if (on && branch) el.replaceWith(branch);\n return;\n }\n if (on || el.parentNode?.nodeType === FRAGMENT_NODE) return;\n const parked = el.ownerDocument.createElement(\"template\");\n parked.setAttribute(ATTR_SHOW, el.getAttribute(ATTR_SHOW)!);\n el.replaceWith(parked);\n parked.content.append(el);\n}\n\n/**\n * Fill from one row: every `lb-column` and `lb-show` in root's query.\n *\n * A live row is its own row, so its root counts when it carries\n * `lb-column`: `<option>`'s content model is text, so an option row has to\n * be the column it displays. An element a `row` lands on is not its own\n * ancestor, so its own `lb-column` reads from the row around it and is left\n * alone here.\n */\nexport function applyRow(root: Element, row: Row, liveRow = false): void {\n for (const [column, value] of Object.entries(row)) {\n const selector = `[${ATTR_COLUMN}=\"${column}\"]`;\n const columns = below(root, selector);\n if (liveRow && root.matches(selector)) columns.unshift(root);\n for (const el of columns) land(el, value);\n // Only null and false are off. A string is never read, so \"false\" is on,\n // and the query spells a condition as a boolean or a null.\n //\n // Never the root's own: a row template's root carries none, and the\n // element a row lands on reads its condition from the row around it.\n const on = value !== null && value !== false;\n for (const el of below(root, `[${ATTR_SHOW}=\"${column}\"]`)) {\n present(el, on);\n }\n }\n}\n\n/**\n * The row template: the first `<template>` among the element's descendants,\n * outside any nested `lb-query`. A template holding an absent branch is not a\n * row template: rows land before the row template, so one inside the first\n * live row comes first in document order.\n */\nexport function templateIn(el: Element): HTMLTemplateElement | null {\n const template = within(el, `template:not([${ATTR_SHOW}])`).find(\n (t) => t !== el,\n );\n return (template as HTMLTemplateElement | undefined) ?? null;\n}\n\n/**\n * The live rows already showing, by the key each carries. A row of a nested\n * query is that query's.\n */\nfunction showing(el: Element): Map<string, Element> {\n const rows = new Map<string, Element>();\n for (const row of el.querySelectorAll(`[${ATTR_KEY_VALUE}]`)) {\n if (inScope(el, row)) rows.set(row.getAttribute(ATTR_KEY_VALUE)!, row);\n }\n return rows;\n}\n\n/**\n * Land rows through a row template.\n *\n * All rows decide membership and order: every row is placed in the order\n * given, and a row whose key did not arrive is gone. A patch disturbs only\n * what it names — a row it did not mention keeps its contents and its\n * position.\n *\n * A custom element that carries `lbPlaceRow` decides where a row goes,\n * because only it knows whether it sorts or groups. Without it a row lands\n * immediately before the template, so rows accumulate in the order they\n * arrive and the template stays put as the insertion marker.\n */\nexport function applyRows(\n el: Element,\n template: HTMLTemplateElement,\n keyColumn: string,\n result: RowsResult,\n): void {\n const shown = showing(el);\n const host = el as Element & RowsHost;\n const whole = !isPatch(result);\n\n const place = (row: Element, data: Row): void => {\n if (host.lbPlaceRow) host.lbPlaceRow(row, data, template);\n else template.parentElement!.insertBefore(row, template);\n };\n\n const upsert = (data: Row): string | null => {\n if (data[keyColumn] === undefined) {\n console.error(\n `lb-hub: a row for <${el.localName}> has no '${keyColumn}' column`,\n );\n return null;\n }\n // The key is stored on the row as an attribute and read back from\n // there, so it is compared as the string the attribute holds.\n const key = String(data[keyColumn]);\n let row = shown.get(key);\n const fresh = row === undefined;\n if (!row) {\n // Imported rather than cloned: template content belongs to a document\n // with no custom element definitions, so a clone would not upgrade\n // until inserted, and a form-associated control would be filled as if\n // it were not one.\n row = el.ownerDocument.importNode(\n template.content.firstElementChild!,\n true,\n );\n row.setAttribute(ATTR_KEY_VALUE, key);\n shown.set(key, row);\n }\n // Fill before insertion. The attributes are already there when the row\n // upgrades, which is the same thing that makes a first landing and a\n // refresh one operation everywhere else.\n applyRow(row, data, true);\n if (fresh || whole) place(row, data);\n return key;\n };\n\n if (Array.isArray(result)) {\n const arrived = new Set<string>();\n for (const data of result) {\n const key = upsert(data);\n if (key !== null) arrived.add(key);\n }\n for (const [key, row] of shown) if (!arrived.has(key)) row.remove();\n } else {\n for (const data of result.rows ?? []) upsert(data);\n for (const key of result.drop ?? []) shown.get(String(key))?.remove();\n }\n\n // Counted from the DOM rather than from either branch above, so all rows\n // and a patch report the same fact the same way. Only here is the count\n // known: the server answers with rows and says nothing about how many\n // survived reconciliation.\n el.setAttribute(ATTR_QUERY_ROW_COUNT, String(showing(el).size));\n\n // Derived scaffolding — a section heading, an <optgroup> — goes when its\n // last row does, and only the custom element knows it exists.\n host.lbRowsLanded?.();\n}\n\n/** Land one response item on one element that names its query. */\nfunction landItem(el: Element, item: ResponseItem): void {\n const template = templateIn(el);\n if (item.kind === KIND_ROW) {\n const row = item.row ?? {};\n if (template) {\n applyRows(el, template, item.key, [row]);\n return;\n }\n applyRow(el, row);\n const key = row[item.key];\n if (key !== undefined && key !== null) {\n el.setAttribute(ATTR_KEY_VALUE, String(key));\n }\n return;\n }\n // A `rows` query with no row template lands nothing: an insert form names\n // the query it adds to, and shows none of its rows.\n if (!template) return;\n const result = item.patch ?? item.rows ?? [];\n applyRows(el, template, item.key, result);\n}\n\n/**\n * Land response items. Every answer arrives through here.\n *\n * `quiet` names queries that may have nowhere to land without a warning: the\n * hub's own `lb-url` lands wherever a chrome or page names it, and nowhere\n * otherwise.\n */\nexport function applyResponse(\n root: ParentNode,\n items: ResponseItem[],\n quiet: readonly string[] = [],\n): void {\n for (const item of items) {\n const targets = everywhere(root, `[${ATTR_QUERY}=\"${item.query}\"]`);\n if (targets.length === 0) {\n if (!quiet.includes(item.query)) {\n console.warn(`lb-hub: nothing names '${item.query}', skipping`);\n }\n continue;\n }\n for (const el of targets) landItem(el, item);\n }\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { applyResponse, applyRow } from "./lb-apply.js";
|
|
2
2
|
//# sourceMappingURL=lb-hub.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lb-hub.browser.d.ts","sourceRoot":"","sources":["../../hub/lb-hub.browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lb-hub.browser.d.ts","sourceRoot":"","sources":["../../hub/lb-hub.browser.ts"],"names":[],"mappings":"AA8CA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|