فهرست منبع

Refactor Writefull toolbar (#28911)

GitOrigin-RevId: 1d8a3addc9046dc67c0cca20d5cf4fba35d132d1
Borja 10 ماه پیش
والد
کامیت
ce38ba6fc1

+ 15 - 15
package-lock.json

@@ -21735,17 +21735,17 @@
       }
     },
     "node_modules/@writefull/core": {
-      "version": "1.27.26",
-      "resolved": "https://registry.npmjs.org/@writefull/core/-/core-1.27.26.tgz",
-      "integrity": "sha512-EI8te62cSuxTLT6tv9tOuk0ddkVIcciD/a/HdTaCsEAF+vpAJHEtD4fkLHeZt+U4P5cJhQPNt6lG/Ei0O2AR9g==",
+      "version": "1.27.27",
+      "resolved": "https://registry.npmjs.org/@writefull/core/-/core-1.27.27.tgz",
+      "integrity": "sha512-q5UWTq7zRQb6y/n8J4k1c2DzuhGnJin6VdY/GeGd7QW7/XRoVlq2pknKQXXdJJCx7mlMahsaZcAj38iqvKii0w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@bugsnag/js": "^7.23.0",
         "@bugsnag/plugin-react": "^7.24.0",
         "@growthbook/growthbook": "^1.4.1",
-        "@writefull/ui": "^1.27.26",
-        "@writefull/utils": "^1.27.26",
+        "@writefull/ui": "^1.27.27",
+        "@writefull/utils": "^1.27.27",
         "axios": "^1.8.3",
         "idb": "^8.0.2",
         "inversify": "^6.0.2",
@@ -21757,14 +21757,14 @@
       }
     },
     "node_modules/@writefull/ui": {
-      "version": "1.27.26",
-      "resolved": "https://registry.npmjs.org/@writefull/ui/-/ui-1.27.26.tgz",
-      "integrity": "sha512-I9hcCKz6VE8bpmo3/MDAZPNX01TkBj63FcBpKcPQ/bkvNAwQvjJ1zaB1K65GBPIZS1FvFN6fXEO8+LPj/0Z+Kg==",
+      "version": "1.27.27",
+      "resolved": "https://registry.npmjs.org/@writefull/ui/-/ui-1.27.27.tgz",
+      "integrity": "sha512-hM3y2oy0leorke+dWMyBl7ur6lRR1l6qICZlwqBCJouqiZnffHTxeDipdzDlbFzyfC4qgozgAcVVEmPtbKfSGw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@floating-ui/react": "^0.27.5",
-        "@writefull/utils": "^1.27.26"
+        "@writefull/utils": "^1.27.27"
       },
       "peerDependencies": {
         "react": ">= 18",
@@ -21772,9 +21772,9 @@
       }
     },
     "node_modules/@writefull/utils": {
-      "version": "1.27.26",
-      "resolved": "https://registry.npmjs.org/@writefull/utils/-/utils-1.27.26.tgz",
-      "integrity": "sha512-cb1nGLP0RBKSvwzGfEGj8xZN9jy15JPoPbNiijHlILiR2+KQ0ICu2uWSos2K2OaKO8mK/2P0nFU4rJOZ/9jc8w==",
+      "version": "1.27.27",
+      "resolved": "https://registry.npmjs.org/@writefull/utils/-/utils-1.27.27.tgz",
+      "integrity": "sha512-yv2135in+NQbYfr+0rmGAKFY55u1OIkOXPQyniRXPjdYwiRVC77tt5XJwqrThVPYd1mruZcFKJ9qDSK4RfAtOg==",
       "dev": true,
       "license": "MIT"
     },
@@ -53334,9 +53334,9 @@
         "@uppy/utils": "^5.7.0",
         "@uppy/xhr-upload": "^3.6.0",
         "@vitest/eslint-plugin": "1.1.44",
-        "@writefull/core": "^1.27.26",
-        "@writefull/ui": "^1.27.26",
-        "@writefull/utils": "^1.27.26",
+        "@writefull/core": "^1.27.27",
+        "@writefull/ui": "^1.27.27",
+        "@writefull/utils": "^1.27.27",
         "5to6-codemod": "^1.8.0",
         "abort-controller": "^3.0.0",
         "acorn": "^7.1.1",

+ 0 - 3
services/web/frontend/extracted-translations.json

@@ -991,7 +991,6 @@
   "loading_github_repositories": "",
   "loading_prices": "",
   "loading_recent_github_commits": "",
-  "loading_writefull": "",
   "log_entry_description": "",
   "log_entry_maximum_entries": "",
   "log_entry_maximum_entries_enable_stop_on_first_error": "",
@@ -2170,8 +2169,6 @@
   "work_with_non_overleaf_users": "",
   "work_with_other_github_users": "",
   "write_faster_smarter_with_overleaf_and_writefull_ai_tools": "",
-  "writefull_loading_error_body": "",
-  "writefull_loading_error_title": "",
   "x_changes_in": "",
   "x_changes_in_plural": "",
   "x_libraries_accessed_in_this_project": "",

+ 0 - 9
services/web/frontend/js/features/source-editor/components/codemirror-editor.tsx

@@ -27,10 +27,6 @@ const sourceEditorComponents = importOverleafModules(
   'sourceEditorComponents'
 ) as { import: { default: ElementType }; path: string }[]
 
-const sourceEditorToolbarComponents = importOverleafModules(
-  'sourceEditorToolbarComponents'
-) as { import: { default: ElementType }; path: string }[]
-
 function CodeMirrorEditor() {
   // create the initial state
   const [state, setState] = useState(() => {
@@ -77,11 +73,6 @@ function CodeMirrorEditorComponents() {
       <FigureModal />
       <CodeMirrorSearch />
       <CodeMirrorToolbar />
-      {sourceEditorToolbarComponents.map(
-        ({ import: { default: Component }, path }) => (
-          <Component key={path} />
-        )
-      )}
       <CodeMirrorCommandTooltip />
 
       <MathPreviewTooltip />

+ 18 - 1
services/web/frontend/js/features/source-editor/components/codemirror-toolbar.tsx

@@ -1,4 +1,11 @@
-import { memo, useCallback, useEffect, useRef, useState } from 'react'
+import {
+  ElementType,
+  memo,
+  useCallback,
+  useEffect,
+  useRef,
+  useState,
+} from 'react'
 import { createPortal } from 'react-dom'
 import {
   useCodeMirrorStateContext,
@@ -27,6 +34,11 @@ import Breadcrumbs from '@/features/ide-redesign/components/breadcrumbs'
 import classNames from 'classnames'
 import { useUserSettingsContext } from '@/shared/context/user-settings-context'
 import { useFeatureFlag } from '@/shared/context/split-test-context'
+import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
+
+const sourceEditorToolbarComponents = importOverleafModules(
+  'sourceEditorToolbarComponents'
+) as { import: { default: ElementType }; path: string }[]
 
 export const CodeMirrorToolbar = () => {
   const view = useCodeMirrorViewContext()
@@ -198,6 +210,11 @@ const Toolbar = memo(function Toolbar() {
             <DetachCompileButtonWrapper />
           </div>
         </div>
+        {sourceEditorToolbarComponents.map(
+          ({ import: { default: Component }, path }) => (
+            <Component key={path} />
+          )
+        )}
         {newEditor && breadcrumbs && <Breadcrumbs />}
       </div>
     </>

+ 7 - 0
services/web/frontend/js/features/source-editor/components/toolbar/button-menu.tsx

@@ -13,6 +13,7 @@ export const ToolbarButtonMenu: FC<
     id: string
     label: string
     icon: React.ReactNode
+    disabled?: boolean
     disablePopover?: boolean
     altCommand?: (view: EditorView) => void
   }>
@@ -21,6 +22,7 @@ export const ToolbarButtonMenu: FC<
   id,
   label,
   altCommand,
+  disabled,
   disablePopover,
   children,
 }) {
@@ -39,11 +41,16 @@ export const ToolbarButtonMenu: FC<
       type="button"
       className="ol-cm-toolbar-button"
       aria-label={label}
+      aria-disabled={disabled}
       onMouseDown={event => {
         event.preventDefault()
         event.stopPropagation()
       }}
       onClick={event => {
+        if (disabled) {
+          event.preventDefault()
+          return
+        }
         if (event.altKey && altCommand && open === false) {
           emitToolbarEvent(view, id)
           event.preventDefault()

+ 14 - 2
services/web/frontend/js/features/source-editor/components/toolbar/overflow.tsx

@@ -12,8 +12,16 @@ export const ToolbarOverflow: FC<
     overflowOpen: boolean
     setOverflowOpen: (open: boolean) => void
     overflowRef?: React.Ref<HTMLDivElement>
+    popoverClassName?: string
   }>
-> = ({ overflowed, overflowOpen, setOverflowOpen, overflowRef, children }) => {
+> = ({
+  overflowed,
+  overflowOpen,
+  setOverflowOpen,
+  overflowRef,
+  popoverClassName,
+  children,
+}) => {
   const { t } = useTranslation()
   const buttonRef = useRef<HTMLButtonElement>(null)
   const keyboardInputRef = useRef(false)
@@ -104,7 +112,11 @@ export const ToolbarOverflow: FC<
           ref={overflowRef}
           role="toolbar"
         >
-          <div className="ol-cm-toolbar-overflow">{children}</div>
+          <div
+            className={classnames(popoverClassName, 'ol-cm-toolbar-overflow')}
+          >
+            {children}
+          </div>
         </OLPopover>
       </OLOverlay>
     </>

+ 1 - 1
services/web/frontend/js/shared/context/types/writefull-instance.ts

@@ -9,7 +9,7 @@ export interface WritefullEvents {
 }
 
 export interface WritefullAPI {
-  init(): Promise<void>
+  init(): void
   addEventListener<eventName extends keyof WritefullEvents>(
     name: eventName,
     callback: (detail: WritefullEvents[eventName]) => void

+ 0 - 3
services/web/locales/da.json

@@ -1002,7 +1002,6 @@
   "loading_github_repositories": "Indlæser dit GitHub repository",
   "loading_prices": "Indlæser priser",
   "loading_recent_github_commits": "Indlæs nylige commits",
-  "loading_writefull": "Indlæser Writefull",
   "log_entry_description": "Logoptegnelse med niveau: __level__",
   "log_entry_maximum_entries": "Grænsen for elementer i loggen er nået",
   "log_entry_maximum_entries_enable_stop_on_first_error": "Prøv at fikse den første fejl og genkompilere. Ofte kan en fejl være skyld i mange efterfølgende fejlmeddelelser. Du kan Slå <0>“Stop ved første fejl”</0> til for at fokusere på at fikse fejl. Vi anbefaler, at du fikser fejl så hurtigt som muligt; hvis de får lov at hobe sig op kan de føre til fejl, som er svære at fejlrette, og fatale fejl. <1>Lære mere</1>",
@@ -2124,8 +2123,6 @@
   "work_or_university_sso": "Arbejds/universitets single sign-on",
   "work_with_non_overleaf_users": "Arbejd sammen med ikke-Overleaf-brugere",
   "writefull": "Writefull",
-  "writefull_loading_error_body": "Prøv at genindlæse siden. Hvis det ikke virker, prøv at deaktivere alle aktive browserudvidelser for at tjekket at de ikke blokerer Writefull for at indlæse.",
-  "writefull_loading_error_title": "Writefull blev ikke indlæst korrekt",
   "x_changes_in": "__count__ ændring i",
   "x_changes_in_plural": "__count__ ændringer i",
   "x_libraries_accessed_in_this_project": "__provider__ biblioteker tilgået i dette projekt",

+ 0 - 3
services/web/locales/en.json

@@ -1274,7 +1274,6 @@
   "loading_github_repositories": "Loading your GitHub repositories",
   "loading_prices": "loading prices",
   "loading_recent_github_commits": "Loading recent commits",
-  "loading_writefull": "Loading Writefull",
   "log_entry_description": "Log entry with level: __level__",
   "log_entry_maximum_entries": "Maximum log entries limit hit",
   "log_entry_maximum_entries_enable_stop_on_first_error": "Try to fix the first error and recompile. Often one error causes many later error messages. You can <0>Enable “Stop on first error”</0> to focus on fixing errors. We recommend fixing errors as soon as possible; letting them accumulate may lead to hard-to-debug and fatal errors. <1>Learn more</1>",
@@ -2720,8 +2719,6 @@
   "work_with_other_github_users": "Work with other GitHub users",
   "write_faster_smarter_with_overleaf_and_writefull_ai_tools": "Write faster, smarter, and with confidence with Overleaf and Writefull AI tools",
   "writefull": "Writefull",
-  "writefull_loading_error_body": "Try refreshing the page. If this doesn’t work, try disabling any active browser extensions to check they aren’t blocking Writefull from loading.",
-  "writefull_loading_error_title": "Writefull didn’t load correctly",
   "x_changes_in": "__count__ change in",
   "x_changes_in_plural": "__count__ changes in",
   "x_libraries_accessed_in_this_project": "__provider__ libraries accessed in this project",

+ 0 - 3
services/web/locales/zh-CN.json

@@ -1200,7 +1200,6 @@
   "loading_github_repositories": "正在读取您的GitHub存储库",
   "loading_prices": "加载价格",
   "loading_recent_github_commits": "正在装载最近的提交",
-  "loading_writefull": "加载 Writefull",
   "log_entry_description": "级别为__level__的日志条目",
   "log_entry_maximum_entries": "最大日志条目限制已达到",
   "log_entry_maximum_entries_enable_stop_on_first_error": "尝试修复第一个错误并重新编译。通常一个错误会导致许多后续的错误消息。您可以<0>启用“第一次出现错误时停止”</0>以专注于修复错误。我们建议尽快修复错误;让它们积累起来可能会导致难以调试和致命的错误<1> 了解更多信息</1>",
@@ -2553,8 +2552,6 @@
   "work_with_non_overleaf_users": "和非Overleaf用户一起工作",
   "work_with_other_github_users": "与其他 GitHub 用户合作",
   "writefull": "Writefull",
-  "writefull_loading_error_body": "尝试刷新页面,如果无效,尝试禁用所有的浏览器拓展,以便检查是否他们阻止了 Writefull 的加载。",
-  "writefull_loading_error_title": "Writefull 加载失败",
   "x_changes_in": "__count__ 处变化在",
   "x_changes_in_plural": "__count__ 处变化在",
   "x_libraries_accessed_in_this_project": "本项目中访问的 __provider__ 库",

+ 3 - 3
services/web/package.json

@@ -275,9 +275,9 @@
     "@uppy/utils": "^5.7.0",
     "@uppy/xhr-upload": "^3.6.0",
     "@vitest/eslint-plugin": "1.1.44",
-    "@writefull/core": "^1.27.26",
-    "@writefull/ui": "^1.27.26",
-    "@writefull/utils": "^1.27.26",
+    "@writefull/core": "^1.27.27",
+    "@writefull/ui": "^1.27.27",
+    "@writefull/utils": "^1.27.27",
     "5to6-codemod": "^1.8.0",
     "abort-controller": "^3.0.0",
     "acorn": "^7.1.1",

+ 24 - 0
services/web/webpack.config.js

@@ -236,6 +236,30 @@ module.exports = {
               },
             ],
           },
+          {
+            // CSS from writefull module - inject directly into DOM
+            include: path.resolve(__dirname, 'modules/writefull/'),
+            use: [
+              'style-loader',
+              {
+                loader: 'css-loader',
+                options: {
+                  importLoaders: 1,
+                },
+              },
+              {
+                loader: 'postcss-loader',
+                options: {
+                  postcssOptions: {
+                    config: path.resolve(
+                      __dirname,
+                      'modules/writefull/frontend/js/integration/postcss.config.js'
+                    ),
+                  },
+                },
+              },
+            ],
+          },
           {
             // Standard CSS processing (extracted into separate file)
             use: [MiniCssExtractPlugin.loader, 'css-loader'],