diff options
author | Antoine du Hamel <duhamelantoine1995@gmail.com> | 2022-06-27 19:31:44 +0300 |
---|---|---|
committer | Michaƫl Zasso <targos@protonmail.com> | 2022-07-31 10:45:01 +0300 |
commit | a5089c9b6d805313320cc9777afe4345ee2070cb (patch) | |
tree | cb280a1e2528a57a43adc754aa520d34cb420660 /tools | |
parent | aab5adbcbe0d1759d269afd416dc6c1c8cf7b248 (diff) |
tools: fix CJS/ESM toggle on small screens
PR-URL: https://github.com/nodejs/node/pull/43506
Co-authored-by: Moshe Atlow <moshe@atlow.co.il>
Fixes: https://github.com/nodejs/node/issues/43468
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/doc/allhtml.mjs | 10 | ||||
-rw-r--r-- | tools/doc/buildCSSForFlavoredJS.mjs | 53 | ||||
-rw-r--r-- | tools/doc/html.mjs | 13 |
3 files changed, 74 insertions, 2 deletions
diff --git a/tools/doc/allhtml.mjs b/tools/doc/allhtml.mjs index 50f145034cc..fb0b719ac8a 100644 --- a/tools/doc/allhtml.mjs +++ b/tools/doc/allhtml.mjs @@ -2,6 +2,7 @@ // of the generated html files. import fs from 'fs'; +import buildCSSForFlavoredJS from './buildCSSForFlavoredJS.mjs'; const source = new URL('../../out/doc/api/', import.meta.url); @@ -90,7 +91,14 @@ all = all.slice(0, tocStart.index + tocStart[0].length) + // Replace apicontent with the concatenated set of apicontents from each source. const apiStart = /<\w+ id="apicontent">\s*/.exec(all); const apiEnd = all.lastIndexOf('<!-- API END -->'); -all = all.slice(0, apiStart.index + apiStart[0].length) + +all = all.slice(0, apiStart.index + apiStart[0].length) + .replace( + '\n</head>', + buildCSSForFlavoredJS(new Set(Array.from( + apicontent.matchAll(/(?<=<pre class="with-)\d+(?=-chars">)/g), + (x) => Number(x[0]) + ))) + '\n</head>' + ) + apicontent + all.slice(apiEnd); diff --git a/tools/doc/buildCSSForFlavoredJS.mjs b/tools/doc/buildCSSForFlavoredJS.mjs new file mode 100644 index 00000000000..6b355ab1760 --- /dev/null +++ b/tools/doc/buildCSSForFlavoredJS.mjs @@ -0,0 +1,53 @@ +const CHAR_THRESHOLD = 68; // Around 68 characters, we have to take into +// account the left column that appears on screen +// wider than 1024px. + +const ESTIMATED_CHAR_WIDTH = 8; // If the root element font-size is 16px (default value), 1ch is 7.8025px. +const TOGGLE_WIDTH = 142; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L954 + +const PRE_MARGIN_LEFT = 16; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L516 +const PRE_MARGIN_RIGHT = 16; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L516 +const PRE_PADDING_LEFT = 16; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L513 +const PRE_PADDING_RIGHT = 16; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L513 + + +const COLUMN_RIGHT_MARGIN_LEFT_LARGE_SCREEN = 234; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L653 +const COLUMN_RIGHT_MARGIN_LEFT_SMALL_SCREEN = 0; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L906 +const COLUMN_RIGHT_MARGIN_RIGHT_LARGE_SCREEN = 0; +const COLUMN_RIGHT_MARGIN_RIGHT_SMALL_SCREEN = 0; +const COLUMN_RIGHT_PADDING_LEFT_LARGE_SCREEN = 24; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L655 +const COLUMN_RIGHT_PADDING_LEFT_SMALL_SCREEN = 8; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L907 +const COLUMN_RIGHT_PADDING_RIGHT_LARGE_SCREEN = 32; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L654 +const COLUMN_RIGHT_PADDING_RIGHT_SMALL_SCREEN = 8; // https://github.com/nodejs/node/blob/dbd938549b16718f2e4cc2809746b8c44a191b1d/doc/api_assets/style.css#L908 + +const getMarginLeft = (charCount) => + (charCount > CHAR_THRESHOLD ? + COLUMN_RIGHT_MARGIN_LEFT_LARGE_SCREEN : + COLUMN_RIGHT_MARGIN_LEFT_SMALL_SCREEN) + PRE_MARGIN_LEFT; +const getPaddingLeft = (charCount) => + (charCount > CHAR_THRESHOLD ? + COLUMN_RIGHT_PADDING_LEFT_LARGE_SCREEN : + COLUMN_RIGHT_PADDING_LEFT_SMALL_SCREEN) + PRE_PADDING_LEFT; +const getPaddingRight = (charCount) => + (charCount > CHAR_THRESHOLD ? + COLUMN_RIGHT_PADDING_RIGHT_LARGE_SCREEN : + COLUMN_RIGHT_PADDING_RIGHT_SMALL_SCREEN) + PRE_PADDING_RIGHT; +const getMarginRight = (charCount) => + (charCount > CHAR_THRESHOLD ? + COLUMN_RIGHT_MARGIN_RIGHT_LARGE_SCREEN : + COLUMN_RIGHT_MARGIN_RIGHT_SMALL_SCREEN) + PRE_MARGIN_RIGHT; + + +export default function buildCSSForFlavoredJS(dynamicSizes) { + if (dynamicSizes == null || dynamicSizes.length === 0) return ''; + + return `<style>${Array.from(dynamicSizes, (charCount) => + `@media(max-width:${getMarginLeft(charCount) + getPaddingLeft(charCount) + + charCount * ESTIMATED_CHAR_WIDTH + TOGGLE_WIDTH + + getPaddingRight(charCount) + getMarginRight(charCount)}px){` + + `.with-${charCount}-chars>.js-flavor-selector{` + + 'float:none;' + + 'margin:0 0 1em auto;' + + '}' + + '}').join('')}</style>`; +} diff --git a/tools/doc/html.mjs b/tools/doc/html.mjs index 1caffa7158c..373f5487a31 100644 --- a/tools/doc/html.mjs +++ b/tools/doc/html.mjs @@ -33,6 +33,9 @@ import { visit } from 'unist-util-visit'; import * as common from './common.mjs'; import * as typeParser from './type-parser.mjs'; +import buildCSSForFlavoredJS from './buildCSSForFlavoredJS.mjs'; + +const dynamicSizes = Object.create(null); const { highlight, getLanguage } = highlightJs; @@ -90,6 +93,8 @@ function processContent(content) { } export function toHTML({ input, content, filename, nodeVersion, versions }) { + const dynamicSizesForThisFile = dynamicSizes[filename]; + filename = path.basename(filename, '.md'); const id = filename.replace(/\W+/g, '-'); @@ -99,6 +104,7 @@ export function toHTML({ input, content, filename, nodeVersion, versions }) { .replace('__SECTION__', content.section) .replace(/__VERSION__/g, nodeVersion) .replace(/__TOC__/g, content.toc) + .replace('__JS_FLAVORED_DYNAMIC_CSS__', buildCSSForFlavoredJS(dynamicSizesForThisFile)) .replace(/__TOC_PICKER__/g, tocPicker(id, content)) .replace(/__GTOC_PICKER__/g, gtocPicker(id)) .replace(/__GTOC__/g, gtocHTML.replace( @@ -228,14 +234,19 @@ export function preprocessElements({ filename }) { const previousNode = parent.children[index - 1] || {}; const nextNode = parent.children[index + 1] || {}; + const charCountFirstTwoLines = Math.max(...node.value.split('\n', 2).map((str) => str.length)); + if (!isJSFlavorSnippet(previousNode) && isJSFlavorSnippet(nextNode) && nextNode.lang !== node.lang) { // Saving the highlight code as value to be added in the next node. node.value = highlighted; + node.charCountFirstTwoLines = charCountFirstTwoLines; } else if (isJSFlavorSnippet(previousNode) && previousNode.lang !== node.lang) { - node.value = '<pre>' + + const actualCharCount = Math.max(charCountFirstTwoLines, previousNode.charCountFirstTwoLines); + (dynamicSizes[filename] ??= new Set()).add(actualCharCount); + node.value = `<pre class="with-${actualCharCount}-chars">` + '<input class="js-flavor-selector" type="checkbox"' + // If CJS comes in second, ESM should display by default. (node.lang === 'cjs' ? ' checked' : '') + |