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

Use dispatchTransactions option when creating EditorView (#14743)

Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com>
GitOrigin-RevId: ccc43ead570bdf96e47d1d08fc114ddce32d1293
Alf Eaton 3 лет назад
Родитель
Сommit
cf0dc6f132

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

@@ -41,13 +41,13 @@ function CodeMirrorEditor() {
 
     const view = new EditorView({
       state,
-      dispatch: tr => {
-        timer.start(tr)
-        view.update([tr])
+      dispatchTransactions: trs => {
+        timer.start(trs)
+        view.update(trs)
         if (isMounted.current) {
           setState(view.state)
         }
-        timer.end(tr, view)
+        timer.end(trs, view)
       },
     })
     viewRef.current = view

+ 31 - 20
services/web/frontend/js/infrastructure/cm6-performance.ts

@@ -81,8 +81,8 @@ function isKeypress(userEventType: string | undefined) {
 }
 
 export function dispatchTimer(): {
-  start: (tr: Transaction) => void
-  end: (tr: Transaction, view: EditorView) => void
+  start: (trs: readonly Transaction[]) => void
+  end: (trs: readonly Transaction[], view: EditorView) => void
 } {
   if (!performanceOptionsSupport) {
     return { start: () => {}, end: () => {} }
@@ -92,34 +92,45 @@ export function dispatchTimer(): {
   let keypressesSinceDomUpdateCount = 0
   const unpaintedKeypressStartTimes: number[] = []
 
-  const start = (tr: Transaction) => {
-    const userEventType = tr.annotation(Transaction.userEvent)
+  const start = (trs: readonly Transaction[]) => {
+    const keypressStart = performance.now()
 
-    if (isKeypress(userEventType)) {
-      unpaintedKeypressStartTimes.push(performance.now())
-    }
+    trs.forEach(tr => {
+      const userEventType = tr.annotation(Transaction.userEvent)
+
+      if (isKeypress(userEventType)) {
+        unpaintedKeypressStartTimes.push(keypressStart)
+      }
+    })
 
     performance.mark(TIMER_START_NAME)
   }
 
-  const end = (tr: Transaction, view: EditorView) => {
+  const end = (trs: readonly Transaction[], view: EditorView) => {
     performance.mark(TIMER_END_NAME)
 
-    const userEventType = tr.annotation(Transaction.userEvent)
+    let anyInputOrDelete = false
 
-    if (isInputOrDelete(userEventType)) {
-      ++userEventsSinceDomUpdateCount
+    trs.forEach(tr => {
+      const userEventType = tr.annotation(Transaction.userEvent)
 
-      if (isKeypress(userEventType)) {
-        ++keypressesSinceDomUpdateCount
-      }
+      if (isInputOrDelete(userEventType)) {
+        anyInputOrDelete = true
+        ++userEventsSinceDomUpdateCount
 
-      performance.measure(TIMER_MEASURE_NAME, {
-        start: TIMER_START_NAME,
-        end: TIMER_END_NAME,
-        detail: { userEventType, userEventsSinceDomUpdateCount },
-      })
+        if (isKeypress(userEventType)) {
+          ++keypressesSinceDomUpdateCount
+        }
+
+        performance.measure(TIMER_MEASURE_NAME, {
+          start: TIMER_START_NAME,
+          end: TIMER_END_NAME,
+          detail: { userEventType, userEventsSinceDomUpdateCount },
+        })
+      }
+    })
 
+    if (anyInputOrDelete) {
       // The `key` property ensures that the measurement task is only run once
       // per measure phase
       view.requestMeasure({
@@ -144,7 +155,7 @@ export function dispatchTimer(): {
       })
     }
 
-    latestDocLength = tr.state.doc.length
+    latestDocLength = trs[trs.length - 1].state.doc.length
   }
 
   return { start, end }