diff --git a/Makefile b/Makefile index c50a5c26da16f5..32eafa993ed8aa 100644 --- a/Makefile +++ b/Makefile @@ -821,8 +821,13 @@ VERSION=v$(RAWVER) .NOTPARALLEL: doc-only doc-only: $(apidoc_dirs) $(apidocs_html) $(apidocs_json) out/doc/api/all.html out/doc/api/all.json out/doc/apilinks.json ## Builds the docs with the local or the global Node.js binary. +.PHONY: doc-add-js +doc-add-js: + cp tools/doc/add_toc_tree_to_leftnav.js out/doc/api/ + $(NODE_EXE) tools/doc/addjs2html.mjs + .PHONY: doc -doc: $(NODE_EXE) doc-only ## Build Node.js, and then build the documentation with the new binary. +doc: $(NODE_EXE) doc-only doc-add-js ## Build Node.js, and then build the documentation with the new binary. out/doc: mkdir -p $@ diff --git a/tools/doc/add_toc_tree_to_leftnav.js b/tools/doc/add_toc_tree_to_leftnav.js new file mode 100644 index 00000000000000..007fdd9d3dc5c8 --- /dev/null +++ b/tools/doc/add_toc_tree_to_leftnav.js @@ -0,0 +1,84 @@ + +function add_toc_tree_to_leftnav(force){ + if (force) document.querySelector('#toc_in_leftnav')?.remove(); + + var toc_in_leftnav = document.querySelector('#toc_in_leftnav'); + var toc_tree, toc_tree_ul, left_nav_tree; + if (!toc_in_leftnav) { + console.log('href', document.location.href, 'nodejs doc add toc_tree'); + + const leftnav = document.querySelector('#column2.interior'); + if (leftnav) { + leftnav.style.overflow = 'scroll'; // default x is hidden + } + + toc_tree = document.querySelector('#toc-picker > li')?.cloneNode(true); + left_nav_tree = document.querySelector('#content > #column2'); + if (!toc_tree || !left_nav_tree) { + console.warn('not found nodejs doc ?') + return false; + } + + toc_tree.id = 'toc_in_leftnav'; + left_nav_tree.insertAdjacentElement('afterbegin', toc_tree); + + toc_tree.insertAdjacentHTML('afterbegin', ` +
+ + + + + +
`); + toc_tree_ul = toc_tree.querySelector('ul'); + + toc_tree_ul.querySelectorAll('li > ul').forEach(ul => { + const li = ul.parentElement; + const detail1 = document.createElement('details'); + const summ = document.createElement('summary'); + detail1.title = 'show details ' + (li.querySelector('a')?.textContent || ''); + summ.innerHTML = ''; + summ.style.color = 'lightyellow'; + detail1.open = false; + detail1.appendChild(summ); + detail1.appendChild(ul); + li.appendChild(detail1); + }); + + // TODO use css? + toc_tree_ul.querySelectorAll('*').forEach(x => { + x.style.marginTop = '0px'; + x.style.marginBottom = '0px'; + x.style.paddingTop = '0px'; + x.style.paddingBottom = '0px'; + x.style.textWrapMode = 'nowrap'; + x.style.fontSize = 'small'; + }); + }; +} + +document.addEventListener('DOMContentLoaded', () => add_toc_tree_to_leftnav()) + + +function setDetailOpen(stat) { + document.getElementById('toc_in_leftnav').querySelectorAll('details').forEach(x => x.open=stat); +} + +function setLeftNavWidth(inc_px) { + const leftnav = document.querySelector('#column2.interior'); + const rightcont = document.querySelector('#column1.interior'); + let cur_width = parseInt(leftnav.style.width); + if (isNaN(cur_width)) { + cur_width = 234; // in css, default 234px + } + + let pxstr = ''; + if (typeof inc_px == 'number' && !isNaN(inc_px) && inc_px != 0) { + cur_width += inc_px; + pxstr = '' + cur_width + 'px'; + } + + leftnav.style.width = pxstr; + rightcont.style.marginLeft = pxstr; +} + diff --git a/tools/doc/addjs2html.mjs b/tools/doc/addjs2html.mjs new file mode 100644 index 00000000000000..936d184472a2e0 --- /dev/null +++ b/tools/doc/addjs2html.mjs @@ -0,0 +1,35 @@ +import fs from 'node:fs' +import fsp from 'node:fs/promises' + +const fns = fs.globSync('out/doc/api/*.html') + +const scripts = ''; + +const last_nbyte = 512 +const buffer = Buffer.alloc(last_nbyte) +let no = 0 + +for (let fn of fns) { + if (fn.endsWith('all.html')) continue; + + let fh + try { + fh = await fsp.open(fn, 'a+') + let st = await fh.stat() + if (st.size < last_nbyte) continue; + + await fh.read({buffer, position: st.size - last_nbyte}) + if (buffer.toString().includes(scripts)) continue; + await fh.appendFile('\n' + scripts) + console.log(` * append