|
|
@@ -646,8 +646,6 @@
|
|
|
var instancesByHolder = new WeakMap();
|
|
|
/** Loop instance nodes; skipped by the render walk (owned by their holder). */
|
|
|
var instanceNodes = new WeakSet();
|
|
|
- /** If-chain anchors for detached branches. @type {WeakMap<Element, Comment>} */
|
|
|
- var ifAnchors = new WeakMap();
|
|
|
/** Elements whose `stm-action` has been wired, to avoid double-binding. */
|
|
|
var wired = new WeakSet();
|
|
|
|
|
|
@@ -674,30 +672,14 @@
|
|
|
toRemove.forEach(function (n) { el.removeAttribute(n); });
|
|
|
}
|
|
|
|
|
|
- /** Ensure an element is in the DOM (reattaching at its remembered anchor). */
|
|
|
- function ensureAttached(el) {
|
|
|
- var anchor = ifAnchors.get(el);
|
|
|
- if (anchor && anchor.parentNode) {
|
|
|
- anchor.parentNode.insertBefore(el, anchor);
|
|
|
- anchor.parentNode.removeChild(anchor);
|
|
|
- ifAnchors.delete(el);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** Detach an element, remembering its position with a comment anchor. */
|
|
|
- function ensureDetached(el) {
|
|
|
- if (!el.parentNode) return;
|
|
|
- if (!ifAnchors.has(el)) {
|
|
|
- var anchor = document.createComment('#stm-if');
|
|
|
- el.parentNode.insertBefore(anchor, el);
|
|
|
- ifAnchors.set(el, anchor);
|
|
|
- }
|
|
|
- el.parentNode.removeChild(el);
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Evaluate an `stm-if` / `stm-else-if` / `stm-else` chain beginning at `el`,
|
|
|
- * attaching the matching branch and detaching the rest.
|
|
|
+ * showing the matching branch and hiding the rest.
|
|
|
+ *
|
|
|
+ * Branches are toggled with the `hidden` attribute rather than detached, so
|
|
|
+ * every branch stays in the DOM and is re-evaluated on each render. (Detaching
|
|
|
+ * the `stm-if` element would remove it from the render walk, leaving an
|
|
|
+ * already-attached `stm-else` branch skipped and never refreshed.)
|
|
|
* @returns {Element|null} The active branch element (or `null`).
|
|
|
*/
|
|
|
function handleIfChain(el, scope) {
|
|
|
@@ -720,8 +702,8 @@
|
|
|
if (b.expr === null || !!evalExpr(b.expr, scope)) { activeEl = b.el; break; }
|
|
|
}
|
|
|
branches.forEach(function (b) {
|
|
|
- if (b.el === activeEl) ensureAttached(b.el);
|
|
|
- else ensureDetached(b.el);
|
|
|
+ if (b.el === activeEl) b.el.removeAttribute('hidden');
|
|
|
+ else b.el.setAttribute('hidden', '');
|
|
|
});
|
|
|
return activeEl;
|
|
|
}
|
|
|
@@ -747,7 +729,7 @@
|
|
|
function handleTextHtml(el, scope) {
|
|
|
if (el.hasAttribute('stm-text')) {
|
|
|
var text = evalExpr(el.getAttribute('stm-text'), scope);
|
|
|
- if (text !== undefined) el.innerText = text === null ? '' : String(text);
|
|
|
+ if (text !== undefined) el.textContent = text === null ? '' : String(text);
|
|
|
}
|
|
|
if (el.hasAttribute('stm-html')) {
|
|
|
var html = evalExpr(el.getAttribute('stm-html'), scope);
|
|
|
@@ -984,9 +966,15 @@
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
/**
|
|
|
- * Toggle pre/post-entrypoint visibility. While loading, `stm-preloader`
|
|
|
- * elements are shown and `stm-content` elements hidden; once ready, the
|
|
|
- * reverse. Uses the `hidden` attribute so it does not fight inline styles.
|
|
|
+ * Toggle pre/post-entrypoint visibility with the `hidden` attribute. While
|
|
|
+ * loading, `stm-preloader` elements are shown and `stm-content` elements
|
|
|
+ * hidden; once ready, the reverse.
|
|
|
+ *
|
|
|
+ * To avoid a flash of un-bound template before the script runs, authors may
|
|
|
+ * pre-set `hidden` directly on `stm-content` in the HTML (e.g.
|
|
|
+ * `<div stm-content hidden>`); the library removes it once ready. The library
|
|
|
+ * also sets `hidden` itself during loading as a fallback for authors who do
|
|
|
+ * not pre-set it.
|
|
|
* @param {boolean} ready
|
|
|
*/
|
|
|
function setBootState(ready) {
|