diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee index c19ad6e2da..7a84635bed 100755 --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -129,11 +129,11 @@ module.exports = CompileController = return next(new Error("invalid h parameter")) if not v?.match(/^\d+\.\d+$/) return next(new Error("invalid v parameter")) - url = CompileController._getUrl(project_id, user_id, "sync/pdf") - destination = {url: url, qs: {page, h, v}} # whether this request is going to a per-user container CompileController._compileAsUser req, (error, user_id) -> return next(error) if error? + url = CompileController._getUrl(project_id, user_id, "sync/pdf") + destination = {url: url, qs: {page, h, v}} CompileController.proxyToClsi(project_id, destination, req, res, next) proxySyncCode: (req, res, next = (error) ->) -> @@ -145,10 +145,10 @@ module.exports = CompileController = return next(new Error("invalid line parameter")) if not column?.match(/^\d+$/) return next(new Error("invalid column parameter")) - url = CompileController._getUrl(project_id, user_id, "sync/code") - destination = {url:url, qs: {file, line, column}} CompileController._compileAsUser req, (error, user_id) -> return next(error) if error? + url = CompileController._getUrl(project_id, user_id, "sync/code") + destination = {url:url, qs: {file, line, column}} CompileController.proxyToClsi(project_id, destination, req, res, next) proxyToClsi: (project_id, url, req, res, next = (error) ->) -> diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 4bbc637815..9b7c2d5bc8 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -125,7 +125,8 @@ define [ file.name = "#{file.path.replace(/^output\./, "")} file" else file.name = file.path - file.url = "/project/#{project_id}/output/#{file.path}" + if not file.url? + file.url = "/project/#{project_id}/output/#{file.path}" if response.clsiServerId? file.url = file.url + "?clsiserverid=#{response.clsiServerId}" $scope.pdf.outputFiles.push file @@ -301,6 +302,9 @@ define [ $scope.startedFreeTrial = true App.factory "synctex", ["ide", "$http", "$q", (ide, $http, $q) -> + # enable per-user containers if querystring includes isolated=true + perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined + synctex = syncToPdf: (cursorPosition) -> deferred = $q.defer() @@ -350,18 +354,35 @@ define [ 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. + 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. + if options.fromPdfPosition and position.pageSize?.height? + v = (position.pageSize.height - position.offset.top) or 0 # measure from pdf point (inverted) + else + v = position.offset.top or 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 - position.offset.top = position.offset.top + 80 + v += 72 # use the same value as in pdfViewer highlighting visual offset $http({ url: "/project/#{ide.project_id}/sync/pdf", method: "GET", params: { page: position.page + 1 - h: position.offset.left.toFixed(2) - v: position.offset.top.toFixed(2) + h: h.toFixed(2) + v: v.toFixed(2) clsiserverid:ide.clsiServerId isolated: perUserCompile } @@ -392,7 +413,7 @@ define [ $scope.syncToCode = () -> synctex - .syncToCode($scope.pdf.position, includeVisualOffset: true) + .syncToCode($scope.pdf.position, includeVisualOffset: true, fromPdfPosition: true) .then (data) -> {doc, line} = data ide.editorManager.openDoc(doc, gotoLine: line) diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee index 2df89bc35f..310a9ba7f8 100644 --- a/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee +++ b/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee @@ -50,7 +50,11 @@ define [ scope.scale = { scaleMode: 'scale_mode_fit_width' } if (position = localStorage("pdf.position.#{attrs.key}")) - scope.position = { page: +position.page, offset: { "top": +position.offset.top, "left": +position.offset.left } } + scope.position = + page: +position.page, + offset: + "top": +position.offset.top + "left": +position.offset.left #scope.position = pdfListView.getPdfPosition(true) diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee index f0ec8d61b1..5f87ff25e9 100644 --- a/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee +++ b/services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee @@ -187,7 +187,8 @@ define [ # console.log 'converted to offset = ', pdfOffset newPosition = { "page": topPageIdx, - "offset" : { "top" : pdfOffset[1], "left": 0 } + "offset" : { "top" : pdfOffset[1], "left": 0} + "pageSize": { "height": viewport.viewBox[3], "width": viewport.viewBox[2] } } return newPosition @@ -208,6 +209,8 @@ define [ return $scope.document.getPdfViewport(page.pageNum).then (viewport) -> page.viewport = viewport pageOffset = viewport.convertToViewportPoint(offset.left, offset.top) + # if the passed-in position doesn't have the page height/width add them now + position.pageSize ?= {"height": viewport.viewBox[3], "width": viewport.viewBox[2]} # console.log 'addition offset =', pageOffset # console.log 'total', pageTop + pageOffset[1] Math.round(pageTop + pageOffset[1] + currentScroll) ## 10 is margin @@ -513,8 +516,17 @@ define [ first = highlights[0] - pageNum = scope.pages[first.page].pageNum + # switching between split and full pdf views can cause + # highlights to appear before rendering + if !scope.pages + return # ignore highlight scroll if still rendering + pageNum = scope.pages[first.page]?.pageNum + + if !pageNum? + return # ignore highlight scroll if page not found + + # use a visual offset of 72pt to match the offset in PdfController syncToCode scope.document.getPdfViewport(pageNum).then (viewport) -> position = { page: first.page diff --git a/services/web/public/img/about/paulo_reis.jpg b/services/web/public/img/about/paulo_reis.jpg new file mode 100644 index 0000000000..e928bfb1e8 Binary files /dev/null and b/services/web/public/img/about/paulo_reis.jpg differ