Bläddra i källkod

Merge pull request #4942 from overleaf/ae-synctex-controller

Move PdfSynctexController and synctex factory to a separate module

GitOrigin-RevId: 0fdd87425159bbdec21ab5c82c9f4abb47f82d07
Alf Eaton 5 år sedan
förälder
incheckning
7ba6776b2e

+ 1 - 0
services/web/frontend/js/ide/pdf/PdfManager.js

@@ -9,6 +9,7 @@
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
 import './controllers/PdfController'
+import './controllers/PdfSynctexController'
 import './controllers/PdfViewToggleController'
 import '../pdfng/directives/pdfJs'
 

+ 0 - 181
services/web/frontend/js/ide/pdf/controllers/PdfController.js

@@ -974,187 +974,6 @@ App.controller(
   }
 )
 
-App.factory('synctex', function (ide, $http, $q) {
-  const synctex = {
-    syncToPdfInFlight: false,
-    syncToCodeInFlight: false,
-
-    syncToPdf(cursorPosition) {
-      const deferred = $q.defer()
-
-      const docId = ide.editorManager.getCurrentDocId()
-      if (docId == null) {
-        deferred.reject()
-        return deferred.promise
-      }
-      const doc = ide.fileTreeManager.findEntityById(docId)
-      if (doc == null) {
-        deferred.reject()
-        return deferred.promise
-      }
-      let path = ide.fileTreeManager.getEntityPath(doc)
-      if (path == null) {
-        deferred.reject()
-        return deferred.promise
-      }
-
-      // If the root file is folder/main.tex, then synctex sees the
-      // path as folder/./main.tex
-      const rootDocDirname = ide.fileTreeManager.getRootDocDirname()
-      if (rootDocDirname != null && rootDocDirname !== '') {
-        path = path.replace(RegExp(`^${rootDocDirname}`), `${rootDocDirname}/.`)
-      }
-
-      const { row, column } = cursorPosition
-
-      this.syncToPdfInFlight = true
-
-      $http({
-        url: `/project/${ide.project_id}/sync/code`,
-        method: 'GET',
-        params: {
-          file: path,
-          line: row + 1,
-          column,
-          clsiserverid: ide.clsiServerId,
-        },
-      })
-        .then(response => {
-          this.syncToPdfInFlight = false
-          const { data } = response
-          return deferred.resolve(data.pdf || [])
-        })
-        .catch(response => {
-          this.syncToPdfInFlight = false
-          const error = response.data
-          return deferred.reject(error)
-        })
-
-      return deferred.promise
-    },
-
-    syncToCode(position, options) {
-      if (options == null) {
-        options = {}
-      }
-      const deferred = $q.defer()
-      if (position == null) {
-        deferred.reject()
-        return deferred.promise
-      }
-
-      // FIXME: this actually works better if it's halfway across the
-      // page (or the visible part of the page). Synctex doesn't
-      // always find the right place in the file when the point is at
-      // the edge of the page, it sometimes returns the start of the
-      // next paragraph instead.
-      const h = position.offset.left
-
-      // Compute the vertical position to pass to synctex, which
-      // works with coordinates increasing from the top of the page
-      // down.  This matches the browser's DOM coordinate of the
-      // click point, but the pdf position is measured from the
-      // bottom of the page so we need to invert it.
-      let v
-      if (
-        options.fromPdfPosition &&
-        (position.pageSize != null ? position.pageSize.height : undefined) !=
-          null
-      ) {
-        v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted)
-      } else {
-        v = position.offset.top || 0 // measure from html click position
-      }
-
-      // It's not clear exactly where we should sync to if it wasn't directly
-      // clicked on, but a little bit down from the very top seems best.
-      if (options.includeVisualOffset) {
-        v += 72 // use the same value as in pdfViewer highlighting visual offset
-      }
-
-      this.syncToCodeInFlight = true
-
-      $http({
-        url: `/project/${ide.project_id}/sync/pdf`,
-        method: 'GET',
-        params: {
-          page: position.page + 1,
-          h: h.toFixed(2),
-          v: v.toFixed(2),
-          clsiserverid: ide.clsiServerId,
-        },
-      })
-        .then(response => {
-          this.syncToCodeInFlight = false
-          const { data } = response
-          if (
-            data.code != null &&
-            data.code.length > 0 &&
-            data.code[0].file !== ''
-          ) {
-            const doc = ide.fileTreeManager.findEntityByPath(data.code[0].file)
-            if (doc == null) {
-              deferred.reject()
-            }
-            return deferred.resolve({ doc, line: data.code[0].line })
-          } else if (data.code[0].file === '') {
-            ide.$scope.sync_tex_error = true
-            setTimeout(() => (ide.$scope.sync_tex_error = false), 4000)
-          }
-        })
-        .catch(response => {
-          this.syncToCodeInFlight = false
-          const error = response.data
-          return deferred.reject(error)
-        })
-
-      return deferred.promise
-    },
-  }
-
-  return synctex
-})
-
-App.controller('PdfSynctexController', function ($scope, synctex, ide) {
-  this.cursorPosition = null
-
-  $scope.$watch(
-    () => synctex.syncToPdfInFlight,
-    value => ($scope.syncToPdfInFlight = value)
-  )
-  $scope.$watch(
-    () => synctex.syncToCodeInFlight,
-    value => ($scope.syncToCodeInFlight = value)
-  )
-
-  ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => {
-    this.cursorPosition = cursorPosition
-  })
-
-  $scope.syncToPdf = () => {
-    if (this.cursorPosition == null) {
-      return
-    }
-    synctex.syncToPdf(this.cursorPosition).then(highlights => {
-      $scope.pdf.highlights = highlights
-    })
-  }
-
-  ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf)
-
-  $scope.syncToCode = function () {
-    synctex
-      .syncToCode($scope.pdf.position, {
-        includeVisualOffset: true,
-        fromPdfPosition: true,
-      })
-      .then(function (data) {
-        const { doc, line } = data
-        ide.editorManager.openDoc(doc, { gotoLine: line })
-      })
-  }
-})
-
 App.controller('ClearCacheModalController', function ($scope, $modalInstance) {
   $scope.state = { error: false, inflight: false }
 

+ 180 - 0
services/web/frontend/js/ide/pdf/controllers/PdfSynctexController.js

@@ -0,0 +1,180 @@
+import App from '../../../base'
+
+App.controller('PdfSynctexController', function ($scope, synctex, ide) {
+  this.cursorPosition = null
+
+  $scope.$watch(
+    () => synctex.syncToPdfInFlight,
+    value => ($scope.syncToPdfInFlight = value)
+  )
+  $scope.$watch(
+    () => synctex.syncToCodeInFlight,
+    value => ($scope.syncToCodeInFlight = value)
+  )
+
+  ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => {
+    this.cursorPosition = cursorPosition
+  })
+
+  $scope.syncToPdf = () => {
+    if (this.cursorPosition == null) {
+      return
+    }
+    synctex.syncToPdf(this.cursorPosition).then(highlights => {
+      $scope.pdf.highlights = highlights
+    })
+  }
+
+  ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf)
+
+  $scope.syncToCode = function () {
+    synctex
+      .syncToCode($scope.pdf.position, {
+        includeVisualOffset: true,
+        fromPdfPosition: true,
+      })
+      .then(function (data) {
+        const { doc, line } = data
+        ide.editorManager.openDoc(doc, { gotoLine: line })
+      })
+  }
+})
+
+App.factory('synctex', function (ide, $http, $q) {
+  return {
+    syncToPdfInFlight: false,
+    syncToCodeInFlight: false,
+
+    syncToPdf(cursorPosition) {
+      const deferred = $q.defer()
+
+      const docId = ide.editorManager.getCurrentDocId()
+      if (docId == null) {
+        deferred.reject()
+        return deferred.promise
+      }
+      const doc = ide.fileTreeManager.findEntityById(docId)
+      if (doc == null) {
+        deferred.reject()
+        return deferred.promise
+      }
+      let path = ide.fileTreeManager.getEntityPath(doc)
+      if (path == null) {
+        deferred.reject()
+        return deferred.promise
+      }
+
+      // If the root file is folder/main.tex, then synctex sees the
+      // path as folder/./main.tex
+      const rootDocDirname = ide.fileTreeManager.getRootDocDirname()
+      if (rootDocDirname != null && rootDocDirname !== '') {
+        path = path.replace(RegExp(`^${rootDocDirname}`), `${rootDocDirname}/.`)
+      }
+
+      const { row, column } = cursorPosition
+
+      this.syncToPdfInFlight = true
+
+      $http({
+        url: `/project/${ide.project_id}/sync/code`,
+        method: 'GET',
+        params: {
+          file: path,
+          line: row + 1,
+          column,
+          clsiserverid: ide.clsiServerId,
+        },
+      })
+        .then(response => {
+          this.syncToPdfInFlight = false
+          const { data } = response
+          return deferred.resolve(data.pdf || [])
+        })
+        .catch(response => {
+          this.syncToPdfInFlight = false
+          const error = response.data
+          return deferred.reject(error)
+        })
+
+      return deferred.promise
+    },
+
+    syncToCode(position, options) {
+      if (options == null) {
+        options = {}
+      }
+      const deferred = $q.defer()
+      if (position == null) {
+        deferred.reject()
+        return deferred.promise
+      }
+
+      // FIXME: this actually works better if it's halfway across the
+      // page (or the visible part of the page). Synctex doesn't
+      // always find the right place in the file when the point is at
+      // the edge of the page, it sometimes returns the start of the
+      // next paragraph instead.
+      const h = position.offset.left
+
+      // Compute the vertical position to pass to synctex, which
+      // works with coordinates increasing from the top of the page
+      // down.  This matches the browser's DOM coordinate of the
+      // click point, but the pdf position is measured from the
+      // bottom of the page so we need to invert it.
+      let v
+      if (
+        options.fromPdfPosition &&
+        (position.pageSize != null ? position.pageSize.height : undefined) !=
+          null
+      ) {
+        v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted)
+      } else {
+        v = position.offset.top || 0 // measure from html click position
+      }
+
+      // It's not clear exactly where we should sync to if it wasn't directly
+      // clicked on, but a little bit down from the very top seems best.
+      if (options.includeVisualOffset) {
+        v += 72 // use the same value as in pdfViewer highlighting visual offset
+      }
+
+      this.syncToCodeInFlight = true
+
+      $http({
+        url: `/project/${ide.project_id}/sync/pdf`,
+        method: 'GET',
+        params: {
+          page: position.page + 1,
+          h: h.toFixed(2),
+          v: v.toFixed(2),
+          clsiserverid: ide.clsiServerId,
+        },
+      })
+        .then(response => {
+          this.syncToCodeInFlight = false
+          const { data } = response
+          if (
+            data.code != null &&
+            data.code.length > 0 &&
+            data.code[0].file !== ''
+          ) {
+            const doc = ide.fileTreeManager.findEntityByPath(data.code[0].file)
+            if (doc == null) {
+              deferred.reject()
+            }
+            return deferred.resolve({ doc, line: data.code[0].line })
+          } else if (data.code[0].file === '') {
+            ide.$scope.sync_tex_error = true
+            setTimeout(() => (ide.$scope.sync_tex_error = false), 4000)
+          }
+        })
+        .catch(response => {
+          this.syncToCodeInFlight = false
+          const error = response.data
+          return deferred.reject(error)
+        })
+
+      return deferred.promise
+    },
+  }
+})