From 5edeff36b6dd946a730410e5fe8fec37794ee7fd Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 6 Feb 2018 16:22:20 +0000 Subject: [PATCH 1/7] Vertically center caret --- services/web/public/stylesheets/components/dropdowns.less | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/public/stylesheets/components/dropdowns.less b/services/web/public/stylesheets/components/dropdowns.less index 516db7178e..8744c1f35c 100755 --- a/services/web/public/stylesheets/components/dropdowns.less +++ b/services/web/public/stylesheets/components/dropdowns.less @@ -13,6 +13,7 @@ border-top: @caret-width-base solid; border-right: @caret-width-base solid transparent; border-left: @caret-width-base solid transparent; + margin-top: -@caret-width-base/2; } // The dropdown wrapper (div) From 5bf2ff0a4780b6249a1c345ce7c1bfd53bb01774 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 8 Feb 2018 10:24:21 +0000 Subject: [PATCH 2/7] Show animated bar while auto-compile is pending --- services/web/app/views/project/editor/pdf.pug | 14 ++++- .../public/coffee/ide/editor/Document.coffee | 5 ++ .../coffee/ide/editor/ShareJsDoc.coffee | 2 + .../editor/sharejs/vendor/client/doc.coffee | 3 + .../ide/pdf/controllers/PdfController.coffee | 35 +++++++++-- .../public/stylesheets/app/editor/pdf.less | 58 ++++++++++++++----- 6 files changed, 96 insertions(+), 21 deletions(-) diff --git a/services/web/app/views/project/editor/pdf.pug b/services/web/app/views/project/editor/pdf.pug index 9681c4fc9a..0175ca2844 100644 --- a/services/web/app/views/project/editor/pdf.pug +++ b/services/web/app/views/project/editor/pdf.pug @@ -1,5 +1,5 @@ div.full-size.pdf(ng-controller="PdfController") - .toolbar.toolbar-pdf + .toolbar.toolbar-pdf(ng-class="{ 'uncompiled-changes': uncompiledChanges && !autoCompileLintingError }") .btn-group.btn-recompile-group#recompile( dropdown, tooltip-html="'"+translate('recompile_pdf')+" ({{modifierKey}} + Enter)'" @@ -92,6 +92,18 @@ div.full-size.pdf(ng-controller="PdfController") i.fa.fa-download .toolbar-right + span.auto-compile-status.small( + ng-show="uncompiledChanges && !compiling && !autoCompileLintingError" + ) #{translate('uncompiled_changes')} + span.auto-compile-status.auto-compile-error.small( + ng-show="autoCompileLintingError" + tooltip-placement="bottom" + tooltip=translate("code_check_failed_explanation") + tooltip-append-to-body="true" + ) + i.fa.fa-fw.fa-exclamation-triangle + | + | #{translate("code_check_failed")} a( href, ng-click="switchToFlatLayout()" diff --git a/services/web/public/coffee/ide/editor/Document.coffee b/services/web/public/coffee/ide/editor/Document.coffee index b6ea177fc8..4c059259d8 100644 --- a/services/web/public/coffee/ide/editor/Document.coffee +++ b/services/web/public/coffee/ide/editor/Document.coffee @@ -340,8 +340,13 @@ define [ v: version @doc.on "change", (ops, oldSnapshot, msg) => @_applyOpsToRanges(ops, oldSnapshot, msg) + @ide.$scope.$emit "doc:changed", + doc_id: @doc_id @doc.on "flipped_pending_to_inflight", () => @trigger "flipped_pending_to_inflight" + @doc.on "saved", () => + @ide.$scope.$emit "doc:saved", + doc_id: @doc_id _onError: (error, meta = {}) -> meta.doc_id = @doc_id diff --git a/services/web/public/coffee/ide/editor/ShareJsDoc.coffee b/services/web/public/coffee/ide/editor/ShareJsDoc.coffee index 569a6c7a9f..ded30a8cb2 100644 --- a/services/web/public/coffee/ide/editor/ShareJsDoc.coffee +++ b/services/web/public/coffee/ide/editor/ShareJsDoc.coffee @@ -46,6 +46,8 @@ define [ @trigger "remoteop", args... @_doc.on "flipped_pending_to_inflight", () => @trigger "flipped_pending_to_inflight" + @_doc.on "saved", () => + @trigger "saved" @_doc.on "error", (e) => @_handleError(e) diff --git a/services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee b/services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee index aca3560b49..edfed10386 100644 --- a/services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee +++ b/services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee @@ -164,6 +164,9 @@ class Doc @inflightOp = null @inflightSubmittedIds.length = 0 + if @pendingOp == null # All ops are acked + @emit 'saved' + error = msg.error if error # The server has rejected an op from the client for some reason. diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index d5d3a41af5..57fa2bee83 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -93,6 +93,9 @@ define [ $scope.recompile(isAutoCompileOnChange: true) # compile if no linting errors else if !ide.$scope.settings.syntaxValidation $scope.recompile(isAutoCompileOnChange: true) # always recompile + else + $scope.$apply () -> + $scope.autoCompileLintingError = true else # Extend remainder of timeout autoCompileTimeout = setTimeout () -> @@ -100,13 +103,37 @@ define [ triggerAutoCompile() , AUTO_COMPILE_TIMEOUT - timeSinceLastCompile - autoCompileListener = null + $scope.uncompiledChanges = false + recalculateUncompiledChanges = () -> + if $scope.docLastChanged > $scope.projectLastCompiled + $scope.uncompiledChanges = true + else + $scope.uncompiledChanges = false + + onDocChanged = () -> + $scope.autoCompileLintingError = false + $scope.docLastChanged = Date.now() + recalculateUncompiledChanges() + + onCompilingStateChanged = (compiling) -> + if compiling + $scope.projectLastCompiled = Date.now() + recalculateUncompiledChanges() + + autoCompileListeners = [] toggleAutoCompile = (enabling) -> if enabling - autoCompileListener = ide.$scope.$on "ide:opAcknowledged", _.debounce(triggerAutoCompile, OP_ACKNOWLEDGEMENT_TIMEOUT) + autoCompileListeners = [ + ide.$scope.$on "doc:changed", onDocChanged + ide.$scope.$on "doc:saved", onDocChanged + $scope.$watch "pdf.compiling", onCompilingStateChanged + ide.$scope.$on "ide:opAcknowledged", _.debounce(triggerAutoCompile, OP_ACKNOWLEDGEMENT_TIMEOUT) + ] else - autoCompileListener() if autoCompileListener - autoCompileListener = null + for unbind in autoCompileListeners + unbind() + autoCompileListeners = [] + $scope.autoCompileLintingError = false $scope.autocompile_enabled = localStorage("autocompile_enabled:#{$scope.project_id}") or false $scope.$watch "autocompile_enabled", (newValue, oldValue) -> diff --git a/services/web/public/stylesheets/app/editor/pdf.less b/services/web/public/stylesheets/app/editor/pdf.less index d59ca93069..6fe6d90d81 100644 --- a/services/web/public/stylesheets/app/editor/pdf.less +++ b/services/web/public/stylesheets/app/editor/pdf.less @@ -1,13 +1,38 @@ +@stripe-width: 20px; +@-webkit-keyframes pdf-toolbar-stripes { + from { background-position: 0 0; } + to { background-position: @stripe-width 0; } +} +@keyframes pdf-toolbar-stripes { + from { background-position: 0 0; } + to { background-position: @stripe-width 0; } +} + .pdf .toolbar.toolbar-pdf when (@is-overleaf = true) { .toolbar-small-mixin; .toolbar-alt-mixin; border-bottom: 0; padding-right: 5px; + &.uncompiled-changes { + #gradient > .striped(@color: rgba(255,255,255,.10), @angle: -45deg); + background-size: @stripe-width @stripe-width; + .animation(pdf-toolbar-stripes 2s linear infinite); + } + .auto-compile-status { + color: white; + margin-right: (@line-height-computed / 2); + i { + color: @brand-danger; + } + } } .pdf .toolbar.toolbar-pdf when (@is-overleaf = false) { .toolbar-tall-mixin; padding: 0 (@line-height-computed / 2); + .auto-compile-status { + display: none; + } } .pdf { @@ -31,29 +56,30 @@ .btn-recompile-group when (@is-overleaf = true) { align-self: stretch; - margin-right: 5px; + margin-right: 6px; + .btn-recompile { + height: 100%; + .btn-primary; + padding-top: 3px; + padding-bottom: 3px; + &:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + &[disabled] { + background-color: mix(@btn-primary-bg, @toolbar-alt-bg-color, 65%); + .opacity(1.0); + } + } } .btn-recompile-group when (@is-overleaf = false) { margin-right: (@line-height-computed / 2); -} - - -.btn-recompile when (@is-overleaf = true) { - height: 100%; - .btn-primary; - padding-top: 3px; - padding-bottom: 3px; - &:first-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0; + .btn-recompile { + .btn-info; } } -.btn-recompile when (@is-overleaf = false) { - .btn-info; -} - .btn-split-screen when (@is-overleaf = false) { .fa { display: none; From 7866a91d212f9fd255b39d90e3042f89197125f8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 8 Feb 2018 13:32:15 +0000 Subject: [PATCH 3/7] Refactor auto-compile trigger logic --- .../ide/pdf/controllers/PdfController.coffee | 114 ++++++++++++------ 1 file changed, 79 insertions(+), 35 deletions(-) diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 57fa2bee83..1145625db4 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -5,8 +5,12 @@ define [ "libs/bib-log-parser" "services/log-hints-feedback" ], (App, Ace, HumanReadableLogs, BibLogParser) -> - AUTO_COMPILE_TIMEOUT = 5000 - OP_ACKNOWLEDGEMENT_TIMEOUT = 1100 + AUTO_COMPILE_MAX_WAIT = 5000 + # We add a 1 second debounce to sending user changes to server if they aren't + # collaborating with anyone. This needs to be higher than that, and allow for + # client to server latency, otherwise we compile before the op reaches the server + # and then again on ack. + AUTO_COMPILE_DEBOUNCE = 2000 App.controller "PdfController", ($scope, $http, ide, $modal, synctex, event_tracking, logHintsFeedback, localStorage) -> # enable per-user containers by default @@ -75,59 +79,96 @@ define [ $scope.pdf.view = 'errors' $scope.pdf.renderingError = true - autoCompileTimeout = null + autoCompileInterval = null + autoCompileIfReady = () -> + if $scope.pdf.compiling + return + + # Only checking linting if syntaxValidation is on and visible to the user + autoCompileLintingError = ide.$scope.hasLintingError and ide.$scope.settings.syntaxValidation + if $scope.autoCompileLintingError != autoCompileLintingError + $scope.$apply () -> + $scope.autoCompileLintingError = autoCompileLintingError + # We've likely been waiting a while until the user fixed the linting, but we + # don't want to compile as soon as it is fixed, so reset the timeout. + $scope.startedTryingAutoCompileAt = Date.now() + $scope.docLastChangedAt = Date.now() + if autoCompileLintingError + return + + # If there's a longish compile, don't compile immediately after if user is still typing + startedTryingAt = Math.max($scope.startedTryingAutoCompileAt, $scope.lastFinishedCompileAt || 0) + + timeSinceStartedTrying = Date.now() - startedTryingAt + timeSinceLastChange = Date.now() - $scope.docLastChangedAt + + shouldCompile = false + if timeSinceLastChange > AUTO_COMPILE_DEBOUNCE # Don't compile in the middle of the user typing + shouldCompile = true + else if timeSinceStartedTrying > AUTO_COMPILE_MAX_WAIT # Unless they type for a long time + shouldCompile = true + else if timeSinceStartedTrying < 0 or timeSinceLastChange < 0 + # If time is non-monotonic, assume that the user's system clock has been + # changed and continue with compile + shouldCompile = true + + if shouldCompile + triggerAutoCompile() + triggerAutoCompile = () -> - return if autoCompileTimeout or $scope.ui.pdfHidden + $scope.recompile(isAutoCompileOnChange: true) - timeSinceLastCompile = Date.now() - $scope.recompiledAt - # If time is non-monotonic, assume that the user's system clock has been - # changed and continue with recompile - isTimeNonMonotonic = timeSinceLastCompile < 0 + startTryingAutoCompile = () -> + return if autoCompileInterval? + $scope.startedTryingAutoCompileAt = Date.now() + autoCompileInterval = setInterval autoCompileIfReady, 200 - if isTimeNonMonotonic || timeSinceLastCompile >= AUTO_COMPILE_TIMEOUT - # If user has code check disabled, it is likely because they have - # linting errors that they are ignoring. Therefore it doesn't make sense - # to block auto compiles. It also causes problems where server-provided - # linting errors aren't cleared after typing - if (ide.$scope.settings.syntaxValidation and !ide.$scope.hasLintingError) - $scope.recompile(isAutoCompileOnChange: true) # compile if no linting errors - else if !ide.$scope.settings.syntaxValidation - $scope.recompile(isAutoCompileOnChange: true) # always recompile - else - $scope.$apply () -> - $scope.autoCompileLintingError = true + stopTryingAutoCompile = () -> + clearInterval autoCompileInterval + autoCompileInterval = null + + $scope.$watch "uncompiledChanges", (uncompiledChanges) -> + if uncompiledChanges + startTryingAutoCompile() else - # Extend remainder of timeout - autoCompileTimeout = setTimeout () -> - autoCompileTimeout = null - triggerAutoCompile() - , AUTO_COMPILE_TIMEOUT - timeSinceLastCompile + stopTryingAutoCompile() $scope.uncompiledChanges = false recalculateUncompiledChanges = () -> - if $scope.docLastChanged > $scope.projectLastCompiled + if $scope.ui.pdfHidden + # Don't both auto-compiling if pdf isn't visible + $scope.uncompiledChanges = false + else if !$scope.docLastChangedAt? + $scope.uncompiledChanges = false + else if !$scope.lastStartedCompileAt? or $scope.docLastChangedAt > $scope.lastStartedCompileAt $scope.uncompiledChanges = true else $scope.uncompiledChanges = false - onDocChanged = () -> - $scope.autoCompileLintingError = false - $scope.docLastChanged = Date.now() + _updateDocLastChangedAt = () -> + $scope.docLastChangedAt = Date.now() recalculateUncompiledChanges() + onDocChanged = () -> + $scope.autoCompileLintingError = false + _updateDocLastChangedAt() + + onDocSaved = () -> + # We use the save as a trigger too, to account for the delay between the client + # and server. Otherwise, we might have compiled after the user made + # the change on the client, but before the server had it. + _updateDocLastChangedAt() + onCompilingStateChanged = (compiling) -> - if compiling - $scope.projectLastCompiled = Date.now() - recalculateUncompiledChanges() + recalculateUncompiledChanges() autoCompileListeners = [] toggleAutoCompile = (enabling) -> if enabling autoCompileListeners = [ ide.$scope.$on "doc:changed", onDocChanged - ide.$scope.$on "doc:saved", onDocChanged + ide.$scope.$on "doc:saved", onDocSaved $scope.$watch "pdf.compiling", onCompilingStateChanged - ide.$scope.$on "ide:opAcknowledged", _.debounce(triggerAutoCompile, OP_ACKNOWLEDGEMENT_TIMEOUT) ] else for unbind in autoCompileListeners @@ -455,6 +496,7 @@ define [ event_tracking.sendMBSampled "editor-recompile-sampled", options + $scope.lastStartedCompileAt = Date.now() $scope.pdf.compiling = true $scope.pdf.isAutoCompileOnLoad = options?.isAutoCompileOnLoad # initial autocompile @@ -472,6 +514,8 @@ define [ options.rootDocOverride_id = getRootDocOverride_id() + $scope.$apply() + sendCompileRequest(options) .then (response) -> { data } = response @@ -487,7 +531,7 @@ define [ $scope.pdf.error = true $scope.pdf.view = 'errors' .finally () -> - $scope.recompiledAt = Date.now() + $scope.lastFinishedCompileAt = Date.now() # This needs to be public. ide.$scope.recompile = $scope.recompile From bd9f30d858d5fcf1d2b28a26d66e245dc0219226 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 8 Feb 2018 14:41:39 +0000 Subject: [PATCH 4/7] Adjust icon spacing in PDF toolbar --- services/web/app/views/project/editor/file-tree.pug | 10 +++++----- services/web/app/views/project/editor/pdf.pug | 6 +++--- services/web/public/stylesheets/app/editor/pdf.less | 1 - .../web/public/stylesheets/app/editor/toolbar.less | 8 +++++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/services/web/app/views/project/editor/file-tree.pug b/services/web/app/views/project/editor/file-tree.pug index fade8e0782..7b33509c9e 100644 --- a/services/web/app/views/project/editor/file-tree.pug +++ b/services/web/app/views/project/editor/file-tree.pug @@ -6,21 +6,21 @@ aside.file-tree(ng-controller="FileTreeController", ng-class="{ 'multi-selected' tooltip-html="'"+translate('new_file').replace(' ', '
')+"'", tooltip-placement="bottom" ) - i.fa.fa-file + i.fa.fa-fw.fa-file a( href, ng-click="openNewFolderModal()", tooltip-html="'"+translate('new_folder').replace(' ', '
')+"'", tooltip-placement="bottom" ) - i.fa.fa-folder + i.fa.fa-fw.fa-folder a( href, ng-click="openUploadFileModal()", tooltip=translate('upload'), tooltip-placement="bottom" ) - i.fa.fa-upload + i.fa.fa-fw.fa-upload .toolbar-right a( @@ -30,7 +30,7 @@ aside.file-tree(ng-controller="FileTreeController", ng-class="{ 'multi-selected' tooltip-placement="bottom", ng-show="multiSelectedCount == 0" ) - i.fa.fa-pencil + i.fa.fa-fw.fa-pencil a( href, ng-click="openDeleteModalForSelected()", @@ -38,7 +38,7 @@ aside.file-tree(ng-controller="FileTreeController", ng-class="{ 'multi-selected' tooltip-placement="bottom", tooltip-append-to-body="true" ) - i.fa.fa-trash-o + i.fa.fa-fw.fa-trash-o .file-tree-inner( diff --git a/services/web/app/views/project/editor/pdf.pug b/services/web/app/views/project/editor/pdf.pug index 0175ca2844..a87b765cf2 100644 --- a/services/web/app/views/project/editor/pdf.pug +++ b/services/web/app/views/project/editor/pdf.pug @@ -65,7 +65,7 @@ div.full-size.pdf(ng-controller="PdfController") tooltip=translate('stop_compile') tooltip-placement="bottom" ) - i.fa.fa-stop() + i.fa.fa-fw.fa-stop() a.log-btn( href ng-click="toggleLogs()" @@ -73,7 +73,7 @@ div.full-size.pdf(ng-controller="PdfController") tooltip=translate('logs_and_output_files') tooltip-placement="bottom" ) - i.fa.fa-file-text-o + i.fa.fa-fw.fa-file-text-o span.label( ng-show="pdf.logEntries.warnings.length + pdf.logEntries.errors.length > 0" ng-class="{\ @@ -89,7 +89,7 @@ div.full-size.pdf(ng-controller="PdfController") tooltip=translate('download_pdf') tooltip-placement="bottom" ) - i.fa.fa-download + i.fa.fa-fw.fa-download .toolbar-right span.auto-compile-status.small( diff --git a/services/web/public/stylesheets/app/editor/pdf.less b/services/web/public/stylesheets/app/editor/pdf.less index 6fe6d90d81..ed9f40f10a 100644 --- a/services/web/public/stylesheets/app/editor/pdf.less +++ b/services/web/public/stylesheets/app/editor/pdf.less @@ -172,7 +172,6 @@ width: 16px; height: 16px; border: 1px solid @gray-light; - margin-top: 5px; } i.full-screen { diff --git a/services/web/public/stylesheets/app/editor/toolbar.less b/services/web/public/stylesheets/app/editor/toolbar.less index 8370e40959..3175aa3b29 100644 --- a/services/web/public/stylesheets/app/editor/toolbar.less +++ b/services/web/public/stylesheets/app/editor/toolbar.less @@ -25,7 +25,9 @@ .toolbar-right > a:not(.btn) { display: inline-block; color: @toolbar-icon-btn-color; - padding: 0 5px; + padding: 4px 2px; + line-height: 1; + height: 24px; border-radius: @border-radius-small; &.toolbar-header-back-projects { padding: 5px 10px 4px; @@ -49,6 +51,10 @@ } } + &.toolbar-pdf > a:not(.btn) { + margin-right: 3px; + } + .btn-full-height { border: none; border-radius: 0; From 9e86abbb0455b5049a4d943a29aadb48c24eb5c8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 9 Feb 2018 17:54:42 +0000 Subject: [PATCH 5/7] Remove unneeded webkit prefix in css --- services/web/public/stylesheets/app/editor/pdf.less | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/web/public/stylesheets/app/editor/pdf.less b/services/web/public/stylesheets/app/editor/pdf.less index ed9f40f10a..0f76816fd5 100644 --- a/services/web/public/stylesheets/app/editor/pdf.less +++ b/services/web/public/stylesheets/app/editor/pdf.less @@ -1,8 +1,4 @@ @stripe-width: 20px; -@-webkit-keyframes pdf-toolbar-stripes { - from { background-position: 0 0; } - to { background-position: @stripe-width 0; } -} @keyframes pdf-toolbar-stripes { from { background-position: 0 0; } to { background-position: @stripe-width 0; } From ab940fb462e9b4a5c909e2c1fb78c9d7b3fe9bfa Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 9 Feb 2018 17:54:58 +0000 Subject: [PATCH 6/7] Fix typo in comment --- .../web/public/coffee/ide/pdf/controllers/PdfController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 1145625db4..59cf07a7d8 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -136,7 +136,7 @@ define [ $scope.uncompiledChanges = false recalculateUncompiledChanges = () -> if $scope.ui.pdfHidden - # Don't both auto-compiling if pdf isn't visible + # Don't bother auto-compiling if pdf isn't visible $scope.uncompiledChanges = false else if !$scope.docLastChangedAt? $scope.uncompiledChanges = false From 92e59f700800fa470b20b78b8523717c2163c64c Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 9 Feb 2018 17:58:19 +0000 Subject: [PATCH 7/7] Remove unneeded apply --- .../web/public/coffee/ide/pdf/controllers/PdfController.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 59cf07a7d8..bf55961589 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -514,8 +514,6 @@ define [ options.rootDocOverride_id = getRootDocOverride_id() - $scope.$apply() - sendCompileRequest(options) .then (response) -> { data } = response