Просмотр исходного кода

Merge pull request #8678 from weseek/fix/141529-143073-editor-displays-correctly-even-with-large-file-sizes

fix: Footnotes making page scrollable.
Yuki Takei 2 лет назад
Родитель
Сommit
01930e1cfb

+ 22 - 8
apps/app/src/components/PageEditor/ScrollSyncHelper.tsx

@@ -19,12 +19,12 @@ const getDataLine = (element: Element | null): number => {
 
 const getEditorElements = (editorRootElement: HTMLElement): Array<Element> => {
   return Array.from(editorRootElement.getElementsByClassName('cm-line'))
-    .filter((element) => { return !Number.isNaN(element.getAttribute('data-line')) });
+    .filter((element) => { return !Number.isNaN(element.getAttribute('data-line') ?? Number.NaN) });
 };
 
 const getPreviewElements = (previewRootElement: HTMLElement): Array<Element> => {
   return Array.from(previewRootElement.getElementsByClassName('has-data-line'))
-    .filter((element) => { return !Number.isNaN(element.getAttribute('data-line')) });
+    .filter((element) => { return !Number.isNaN(element.getAttribute('data-line') ?? Number.NaN) });
 };
 
 // Ref: https://github.com/mikolalysenko/binary-search-bounds/blob/f436a2a8af11bf3208434e18bbac17e18e7a3a30/search-bounds.js
@@ -63,14 +63,14 @@ const findElementIndexFromDataLine = (previewElements: Array<Element>, dataline:
 
 
 type SourceElement = {
-  start: DOMRect,
-  top: DOMRect,
-  next: DOMRect | undefined,
+  start?: DOMRect,
+  top?: DOMRect,
+  next?: DOMRect,
 }
 
 type TargetElement = {
-  start: DOMRect,
-  next: DOMRect | undefined,
+  start?: DOMRect,
+  next?: DOMRect,
 }
 
 const calcScrollElementToTop = (element: Element): number => {
@@ -78,7 +78,13 @@ const calcScrollElementToTop = (element: Element): number => {
 };
 
 const calcScorllElementByRatio = (sourceElement: SourceElement, targetElement: TargetElement): number => {
-  if (sourceElement.start === sourceElement.next || sourceElement.next == null || targetElement.next == null) {
+  if (sourceElement.start === sourceElement.next) {
+    return 0;
+  }
+  if (sourceElement.start == null || sourceElement.top == null || sourceElement.next == null) {
+    return 0;
+  }
+  if (targetElement.start == null || targetElement.next == null) {
     return 0;
   }
   const sourceAllHeight = sourceElement.next.top - sourceElement.start.top;
@@ -107,6 +113,10 @@ const scrollEditor = (editorRootElement: HTMLElement, previewRootElement: HTMLEl
 
   let newScrollTop = previewRootElement.scrollTop;
 
+  if (previewElements[topPreviewElementIndex] == null) {
+    return;
+  }
+
   newScrollTop += calcScrollElementToTop(previewElements[topPreviewElementIndex]);
   newScrollTop += calcScorllElementByRatio(
     {
@@ -136,6 +146,10 @@ const scrollPreview = (editorRootElement: HTMLElement, previewRootElement: HTMLE
   const startEditorElementIndex = findElementIndexFromDataLine(editorElements, getDataLine(previewElements[topPreviewElementIndex]));
   const nextEditorElementIndex = findElementIndexFromDataLine(editorElements, getDataLine(previewElements[topPreviewElementIndex + 1]));
 
+  if (editorElements[startEditorElementIndex] == null) {
+    return;
+  }
+
   let newScrollTop = editorRootElement.scrollTop;
 
   newScrollTop += calcScrollElementToTop(editorElements[startEditorElementIndex]);

+ 9 - 3
apps/app/src/services/renderer/rehype-plugins/add-line-number-attribute.ts

@@ -1,11 +1,11 @@
-import { Schema as SanitizeOption } from 'hast-util-sanitize';
+import type { Schema as SanitizeOption } from 'hast-util-sanitize';
 import type { Element } from 'hast-util-select/lib/types';
 import type { Plugin } from 'unified';
-import { visit } from 'unist-util-visit';
+import { visit, EXIT, CONTINUE } from 'unist-util-visit';
 
 import { addClassToProperties } from './add-class';
 
-const REGEXP_TARGET_TAGNAMES = new RegExp(/^(h1|h2|h3|h4|h5|h6|p|img|pre|blockquote|hr|ol|ul|table|tr)$/);
+const REGEXP_TARGET_TAGNAMES = new RegExp(/^(h1|h2|h3|h4|h5|h6|p|img|pre|blockquote|hr|ol|ul|table)$/);
 
 export const rehypePlugin: Plugin = () => {
   return (tree) => {
@@ -13,6 +13,11 @@ export const rehypePlugin: Plugin = () => {
       if (REGEXP_TARGET_TAGNAMES.test(node.tagName as string)) {
         const properties = node.properties ?? {};
 
+        // skip footnotes node
+        if (properties?.id === 'footnote-label') {
+          return EXIT;
+        }
+
         // add class
         addClassToProperties(properties, 'has-data-line');
         // add attribute
@@ -20,6 +25,7 @@ export const rehypePlugin: Plugin = () => {
 
         node.properties = properties;
       }
+      return CONTINUE;
     });
   };
 };

+ 1 - 8
apps/app/src/styles/organisms/_wiki.scss

@@ -177,14 +177,7 @@
     border-top: 1px solid bs.$border-color;
     /* Hide the section label for visual users. */
     #footnote-label {
-      position: absolute;
-      width: 1px;
-      height: 1px;
-      padding: 0;
-      overflow: hidden;
-      clip: rect(0, 0, 0, 0);
-      word-wrap: normal;
-      border: 0;
+      display: none;
     }
   }
   /* Place `[` and `]` around footnote references. */