openvibers/openvibe.blog Commits
A fold says what it holds, counted, not "tap to open" (#171)
Changes
@@@ -63,13 +63,27 @@ function pickListRules(key, n) {return Array.from({ length: n }, (_, i) => pickListRule(key, i)).join('');}++/**++ * What a fold holds, counted, for its title row (the owner, 2026-10-31: a fold that shortens a page shows its count):++ * "6 questions", "12 items", "latest 5" for the shipped list, or nothing when there is nothing to count. Replaces the++ * hint the fold used to show instead.++ */++function foldMeta(body, cls = '') {++ const s = typeof body === 'string' ? body : String((body && (body.s || body.html || body.value)) || body || '');++ const n = (re) => (s.match(re) || []).length;++ const shipped = /data-ov-shipped="list"[^>]*?data-limit="(\d+)"|data-limit="(\d+)"[^>]*?data-ov-shipped="list"/.exec(s);++ const q = n(/<details[\s>]/g), li = n(/<li[\s>]/g), a = n(/<a\s/g);++ const text = shipped ? `latest ${shipped[1] || shipped[2]}` : q > 1 ? `${q} questions` : li > 1 ? `${li} items` : a > 1 ? `${a} links` : '';++ return text ? `<span${cls ? ` class="${cls}"` : ''}>${text}</span>` : '';++}++/*** A fold. The head is the heading the block had; the html is what it holds.** foldBlock({ id, head, html })*/function foldBlock({ id, head, html }) {-- return '<details class="bl-fold bl-fold-block" id="' + esc(id) + '" open><summary>' + head + '<span class="bl-fold-hint">tap to open</span></summary>' + html + '</details>' + foldScript(id);++ return '<details class="bl-fold bl-fold-block" id="' + esc(id) + '" open><summary>' + head + foldMeta(html, 'bl-fold-hint') + '</summary>' + html + '</details>' + foldScript(id);}/** The script a fold carries: closed on a phone unless the reader opened it before, and it remembers that. */@@@ -106,4 +120,4 @@ function foldAround(html, needle, id, head) {return html.slice(0, p.start) + foldBlock({ id, head, html: p.html }) + html.slice(p.end);}--module.exports = { pickBlock, pickRule, pickRules, pickList, pickListRule, pickListRules, foldBlock, foldScript, part, swap, foldAround };++module.exports = { pickBlock, pickRule, pickRules, pickList, pickListRule, pickListRules, foldBlock, foldMeta, foldScript, part, swap, foldAround };
@@ -63,13 +63,27 @@ function pickListRules(key, n) {
@@ -63,13 +63,27 @@ function pickListRules(key, n) {
return Array.from({ length: n }, (_, i) => pickListRule(key, i)).join('');
return Array.from({ length: n }, (_, i) => pickListRule(key, i)).join('');
}
}
+/**
+ * What a fold holds, counted, for its title row (the owner, 2026-10-31: a fold that shortens a page shows its count):
+ * "6 questions", "12 items", "latest 5" for the shipped list, or nothing when there is nothing to count. Replaces the
+ * hint the fold used to show instead.
+ */
+function foldMeta(body, cls = '') {
+ const s = typeof body === 'string' ? body : String((body && (body.s || body.html || body.value)) || body || '');
+ const n = (re) => (s.match(re) || []).length;
+ const shipped = /data-ov-shipped="list"[^>]*?data-limit="(\d+)"|data-limit="(\d+)"[^>]*?data-ov-shipped="list"/.exec(s);
+ const q = n(/<details[\s>]/g), li = n(/<li[\s>]/g), a = n(/<a\s/g);
+ const text = shipped ? `latest ${shipped[1] || shipped[2]}` : q > 1 ? `${q} questions` : li > 1 ? `${li} items` : a > 1 ? `${a} links` : '';
+ return text ? `<span${cls ? ` class="${cls}"` : ''}>${text}</span>` : '';
+}
+
/**
/**
* A fold. The head is the heading the block had; the html is what it holds.
* A fold. The head is the heading the block had; the html is what it holds.
*
*
* foldBlock({ id, head, html })
* foldBlock({ id, head, html })
*/
*/
function foldBlock({ id, head, html }) {
function foldBlock({ id, head, html }) {
- return '<details class="bl-fold bl-fold-block" id="' + esc(id) + '" open><summary>' + head + '<span class="bl-fold-hint">tap to open</span></summary>' + html + '</details>' + foldScript(id);
+ return '<details class="bl-fold bl-fold-block" id="' + esc(id) + '" open><summary>' + head + foldMeta(html, 'bl-fold-hint') + '</summary>' + html + '</details>' + foldScript(id);
}
}
/** The script a fold carries: closed on a phone unless the reader opened it before, and it remembers that. */
/** The script a fold carries: closed on a phone unless the reader opened it before, and it remembers that. */
@@ -106,4 +120,4 @@ function foldAround(html, needle, id, head) {
@@ -106,4 +120,4 @@ function foldAround(html, needle, id, head) {
return html.slice(0, p.start) + foldBlock({ id, head, html: p.html }) + html.slice(p.end);
return html.slice(0, p.start) + foldBlock({ id, head, html: p.html }) + html.slice(p.end);
}
}
-module.exports = { pickBlock, pickRule, pickRules, pickList, pickListRule, pickListRules, foldBlock, foldScript, part, swap, foldAround };
+module.exports = { pickBlock, pickRule, pickRules, pickList, pickListRule, pickListRules, foldBlock, foldMeta, foldScript, part, swap, foldAround };