From a5089c9b6d805313320cc9777afe4345ee2070cb Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 27 Jun 2022 18:31:44 +0200 Subject: [PATCH] tools: fix CJS/ESM toggle on small screens PR-URL: https://github.com/nodejs/node/pull/43506 Co-authored-by: Moshe Atlow Fixes: https://github.com/nodejs/node/issues/43468 Reviewed-By: LiviaMedeiros --- doc/api_assets/style.css | 3 ++ doc/template.html | 1 + tools/doc/allhtml.mjs | 10 +++++- tools/doc/buildCSSForFlavoredJS.mjs | 53 +++++++++++++++++++++++++++++ tools/doc/html.mjs | 13 ++++++- 5 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tools/doc/buildCSSForFlavoredJS.mjs diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index c567fbed1c23d4..663025e1c27ef5 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -953,6 +953,9 @@ kbd { background-repeat: no-repeat; width: 142px; height: 20px; + display: block; + cursor: pointer; + margin: 0; } .js-flavor-selector:checked { background-image: url(./js-flavor-esm.svg); diff --git a/doc/template.html b/doc/template.html index 86ba3c9581e004..a186e4fbded383 100644 --- a/doc/template.html +++ b/doc/template.html @@ -10,6 +10,7 @@ + __JS_FLAVORED_DYNAMIC_CSS__
diff --git a/tools/doc/allhtml.mjs b/tools/doc/allhtml.mjs index 50f145034ccb7a..fb0b719ac8a8a9 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(''); -all = all.slice(0, apiStart.index + apiStart[0].length) + +all = all.slice(0, apiStart.index + apiStart[0].length) + .replace( + '\n', + buildCSSForFlavoredJS(new Set(Array.from( + apicontent.matchAll(/(?<=
)/g),
+        (x) => Number(x[0])
+      ))) + '\n'
+    ) +
   apicontent +
   all.slice(apiEnd);
 
diff --git a/tools/doc/buildCSSForFlavoredJS.mjs b/tools/doc/buildCSSForFlavoredJS.mjs
new file mode 100644
index 00000000000000..6b355ab1760a64
--- /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 ``;
+}
diff --git a/tools/doc/html.mjs b/tools/doc/html.mjs
index 1caffa7158c950..373f5487a31d4b 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 = '
' +
+            const actualCharCount = Math.max(charCountFirstTwoLines, previousNode.charCountFirstTwoLines);
+            (dynamicSizes[filename] ??= new Set()).add(actualCharCount);
+            node.value = `
` +
               '