From badc4ecb7a8f140a8dc4dc81b8ead3c3464880c9 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 14 Feb 2017 14:40:21 +0000 Subject: [PATCH 01/17] Show add comment tooltip to the left when appropriate. --- services/web/app/views/project/editor/review-panel.pug | 3 ++- .../coffee/ide/review-panel/directives/addCommentEntry.coffee | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/services/web/app/views/project/editor/review-panel.pug b/services/web/app/views/project/editor/review-panel.pug index 8b33be8ef6..1f4fd45a4e 100644 --- a/services/web/app/views/project/editor/review-panel.pug +++ b/services/web/app/views/project/editor/review-panel.pug @@ -79,6 +79,7 @@ on-submit="submitNewComment(content);" on-cancel="cancelNewComment();" on-indicator-click="toggleReviewPanel();" + layout-to-left="reviewPanel.layoutToLeft" ) .rp-entry-list( @@ -310,7 +311,7 @@ script(type='text/ng-template', id='addCommentEntryTemplate') ng-if="!commentState.adding" ng-click="startNewComment(); onIndicatorClick();" tooltip="Add a comment" - tooltip-placement="right" + tooltip-placement="{{ layoutToLeft ? 'left' : 'right' }}" tooltip-append-to-body="true" ) i.fa.fa-commenting diff --git a/services/web/public/coffee/ide/review-panel/directives/addCommentEntry.coffee b/services/web/public/coffee/ide/review-panel/directives/addCommentEntry.coffee index c23c37b674..c30eaadd0f 100644 --- a/services/web/public/coffee/ide/review-panel/directives/addCommentEntry.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/addCommentEntry.coffee @@ -9,6 +9,7 @@ define [ onSubmit: "&" onCancel: "&" onIndicatorClick: "&" + layoutToLeft: "=" link: (scope, element, attrs) -> scope.state = isAdding: false From 36e5ac74dc7d8da69e4e0b9a9aad372108c06359 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 15 Feb 2017 15:11:01 +0000 Subject: [PATCH 02/17] Give the scrollbar a background-color, so that Safari knows that it should paint it. --- services/web/public/stylesheets/app/editor.less | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/services/web/public/stylesheets/app/editor.less b/services/web/public/stylesheets/app/editor.less index 250269a7a2..fdf18d7b38 100644 --- a/services/web/public/stylesheets/app/editor.less +++ b/services/web/public/stylesheets/app/editor.less @@ -181,6 +181,19 @@ } } +// Hack to solve an issue where scrollbars aren't visible in Safari. +// Safari seems to clip part of the scrollbar element. By giving the +// element a background, we're telling Safari that it *really* needs to +// paint the whole area. See https://github.com/ajaxorg/ace/issues/2872 +.ace_scrollbar-inner { + background-color: #FFF; + opacity: 0.01; + + .ace_dark & { + background-color: #000; + } +} + .ui-layout-resizer { width: 6px; background-color: #f4f4f4; From c8a6555cb1fcbe120be68dd86875d6f587a8110d Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 16 Feb 2017 17:07:56 +0100 Subject: [PATCH 03/17] Update RangesTracker --- .../ide/review-panel/RangesTracker.coffee | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/services/web/public/coffee/ide/review-panel/RangesTracker.coffee b/services/web/public/coffee/ide/review-panel/RangesTracker.coffee index e31b84f051..0430ea2945 100644 --- a/services/web/public/coffee/ide/review-panel/RangesTracker.coffee +++ b/services/web/public/coffee/ide/review-panel/RangesTracker.coffee @@ -105,6 +105,7 @@ load = (EventEmitter) -> throw new Error("unknown op type") addComment: (op, metadata) -> + # TODO: Don't allow overlapping comments? @comments.push comment = { id: op.t or @newId() op: # Copy because we'll modify in place @@ -167,12 +168,14 @@ load = (EventEmitter) -> op_length = op.i.length op_end = op.p + op_length + already_merged = false previous_change = null moved_changes = [] remove_changes = [] new_changes = [] - for change in @changes + + for change, i in @changes change_start = change.op.p if change.op.d? @@ -200,6 +203,16 @@ load = (EventEmitter) -> # Only merge inserts if they are from the same user is_same_user = metadata.user_id == change.metadata.user_id + # If this is an insert op at the end of an existing insert with a delete following, and it cancels out the following + # delete then we shouldn't append it to this insert, but instead only cancel the following delete. + # E.g. + # foo|<--- about to insert 'b' here + # inserted 'foo' --^ ^-- deleted 'bar' + # should become just 'foo' not 'foob' (with the delete marker becoming just 'ar'), . + next_change = @changes[i+1] + is_op_adjacent_to_next_delete = next_change? and next_change.op.d? and op.p == change_end and next_change.op.p == op.p + will_op_cancel_next_delete = is_op_adjacent_to_next_delete and next_change.op.d.slice(0, op.i.length) == op.i + # If there is a delete at the start of the insert, and we're inserting # at the start, we SHOULDN'T merge since the delete acts as a partition. # The previous op will be the delete, but it's already been shifted by this insert @@ -222,7 +235,8 @@ load = (EventEmitter) -> if @track_changes and is_change_overlapping and !is_insert_blocked_by_delete and - !already_merged and + !already_merged and + !will_op_cancel_next_delete and is_same_user offset = op_start - change_start change.op.i = change.op.i.slice(0, offset) + op.i + change.op.i.slice(offset) @@ -396,9 +410,13 @@ load = (EventEmitter) -> @emit "changes:moved", moved_changes _addOp: (op, metadata) -> + # Don't take a reference to the existing op since we'll modify this in place with future changes + clone_op = {} + for k,v of op + clone_op[k] = v change = { id: @newId() - op: op + op: clone_op metadata: metadata } @changes.push change From 31ae2e71241fb86783bd8ecc5e279bc9997b6d6a Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 17 Feb 2017 09:24:25 +0100 Subject: [PATCH 04/17] Update RangesTracker --- .../coffee/ide/review-panel/RangesTracker.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/services/web/public/coffee/ide/review-panel/RangesTracker.coffee b/services/web/public/coffee/ide/review-panel/RangesTracker.coffee index 0430ea2945..865ecf4ef6 100644 --- a/services/web/public/coffee/ide/review-panel/RangesTracker.coffee +++ b/services/web/public/coffee/ide/review-panel/RangesTracker.coffee @@ -410,14 +410,10 @@ load = (EventEmitter) -> @emit "changes:moved", moved_changes _addOp: (op, metadata) -> - # Don't take a reference to the existing op since we'll modify this in place with future changes - clone_op = {} - for k,v of op - clone_op[k] = v change = { id: @newId() - op: clone_op - metadata: metadata + op: @_clone(op) # Don't take a reference to the existing op since we'll modify this in place with future changes + metadata: @_clone(metadata) } @changes.push change @@ -489,6 +485,11 @@ load = (EventEmitter) -> else # Only update to the current change if we haven't removed it. previous_change = change return { moved_changes, remove_changes } + + _clone: (object) -> + clone = {} + (clone[k] = v for k,v of object) + return clone if define? define ["utils/EventEmitter"], load From debe78030a7b3c217d39552667acd37edca74ec6 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 17 Feb 2017 11:05:17 +0000 Subject: [PATCH 05/17] use html from jade as strings now fully html escaped --- services/web/app/views/project/editor/pdf.pug | 2 +- services/web/app/views/user/sessions.pug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/views/project/editor/pdf.pug b/services/web/app/views/project/editor/pdf.pug index ba03f068a6..e75a2919b7 100644 --- a/services/web/app/views/project/editor/pdf.pug +++ b/services/web/app/views/project/editor/pdf.pug @@ -302,7 +302,7 @@ div.full-size.pdf(ng-controller="PdfController") .alert.alert-danger(ng-show="pdf.validation.conflictedPaths") div strong #{translate("conflicting_paths_found")} - div #{translate("following_paths_conflict")} + div !{translate("following_paths_conflict")} div li(ng-repeat="entry in pdf.validation.conflictedPaths") {{ '/'+entry['path'] }} diff --git a/services/web/app/views/user/sessions.pug b/services/web/app/views/user/sessions.pug index 948ed2d94f..c952daea03 100644 --- a/services/web/app/views/user/sessions.pug +++ b/services/web/app/views/user/sessions.pug @@ -17,7 +17,7 @@ block content div p.small - | #{translate("clear_sessions_description")} + | !{translate("clear_sessions_description")} div div(ng-if="state.otherSessions.length == 0") From 58c7dda945c20d4b11245c5bf0939452974e3e9c Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 17 Feb 2017 11:05:27 +0000 Subject: [PATCH 06/17] fix couple of bad translations --- services/web/app/views/subscriptions/group/successful_join.pug | 2 +- services/web/app/views/user/settings.pug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/views/subscriptions/group/successful_join.pug b/services/web/app/views/subscriptions/group/successful_join.pug index 6de282aa36..9e748f4c38 100644 --- a/services/web/app/views/subscriptions/group/successful_join.pug +++ b/services/web/app/views/subscriptions/group/successful_join.pug @@ -20,6 +20,6 @@ block content .col-md-12   .row .span-md-12 - a.btn.btn-success(href="/project") #{translate("Done")} + a.btn.btn-success(href="/project") #{translate("done")} diff --git a/services/web/app/views/user/settings.pug b/services/web/app/views/user/settings.pug index a4217d8ca4..c358909110 100644 --- a/services/web/app/views/user/settings.pug +++ b/services/web/app/views/user/settings.pug @@ -107,7 +107,7 @@ block content span.small.text-primary(ng-show="changePasswordForm.newPassword2.$error.areEqual && changePasswordForm.newPassword2.$dirty") | #{translate("doesnt_match")} span.small.text-primary(ng-show="!changePasswordForm.newPassword2.$error.areEqual && changePasswordForm.newPassword2.$invalid && changePasswordForm.newPassword2.$dirty") - | #{translate("Invalid Password")} + | #{translate("invalid_password")} .actions button.btn.btn-primary( type='submit', From e9752b4d10362051dc71a78f082584e66ad3a336 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Fri, 17 Feb 2017 11:24:50 +0000 Subject: [PATCH 07/17] Avoid blank screen bug, when triggered by very large comments. --- services/web/public/stylesheets/app/editor/review-panel.less | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index 1d1900c90c..e82170de91 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -158,6 +158,8 @@ position: absolute; top: 0; bottom: 0; + padding-bottom: 52px; + overflow: hidden; } .rp-state-overview & { From 2eb9058c7c972e1d015aabed8d4d4c92ec8820a8 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Fri, 17 Feb 2017 15:16:35 +0000 Subject: [PATCH 08/17] Add max-height to comment inputs. --- services/web/public/stylesheets/app/editor/review-panel.less | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index e82170de91..8e35a6abcf 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -463,6 +463,7 @@ margin-top: 3px; overflow-x: hidden; min-height: 3em; + max-height: 400px; } .rp-icon-delete { From 7ffb6edd1cb4efffc3901773cf2b2c8bbf5595b9 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 20 Feb 2017 11:21:56 +0000 Subject: [PATCH 09/17] Use solid color instead of opacity, to avoid rendering issues. --- services/web/public/stylesheets/app/editor/review-panel.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index 1d1900c90c..9930eaa4a3 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -49,11 +49,11 @@ } &[disabled] { - opacity: 0.5; + background-color: tint(@rp-highlight-blue, 50%); &:hover, &:focus { - background-color: @rp-highlight-blue; + background-color: tint(@rp-highlight-blue, 50%); } } } From 995fa6122b930e4b680b4987338442c13b33382a Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 20 Feb 2017 12:56:26 +0100 Subject: [PATCH 10/17] Scroll the review panel past the limits of Ace --- .../ide/editor/directives/aceEditor.coffee | 17 ++++++++++ .../controllers/ReviewPanelController.coffee | 3 ++ .../directives/reviewPanelSorted.coffee | 31 ++++++++++--------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index 9205cb7b87..b3c607455b 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -184,6 +184,23 @@ define [ session = editor.getSession() session.setScrollTop(session.getScrollTop() + newScreenPosition - previousScreenPosition) + scope.$on "#{scope.name}:set-scroll-size", (e, size) -> + # Make sure that the editor has enough scroll margin above and below + # to scroll the review panel with the given size + marginChanged = false + if editor.renderer.scrollMargin.top != size.overflowTop + window.editors[0].renderer.scrollMargin.top = size.overflowTop + marginChanged = true + + maxHeight = editor.renderer.layerConfig.maxHeight + marginBottom = Math.max(size.height - maxHeight, 0) + if editor.renderer.scrollMargin.bottom != marginBottom + editor.renderer.scrollMargin.bottom = marginBottom + marginChanged = true + + if marginChanged + editor.renderer.updateFull() + scope.$watch "theme", (value) -> editor.setTheme("ace/theme/#{value}") diff --git a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee index 88a3233934..d0af889dda 100644 --- a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee +++ b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee @@ -39,6 +39,9 @@ define [ $timeout () -> $scope.$broadcast "review-panel:layout" + $scope.$on "review-panel:sizes", (e, sizes) -> + $scope.$broadcast "editor:set-scroll-size", sizes + $scope.$watch "ui.pdfLayout", (layout) -> $scope.reviewPanel.layoutToLeft = (layout == "flat") diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee index 4028406713..551658eacb 100644 --- a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee @@ -15,9 +15,11 @@ define [ if scope.ui.reviewPanelOpen PADDING = 8 TOOLBAR_HEIGHT = 38 + OVERVIEW_TOGGLE_HEIGHT = 57 else PADDING = 4 TOOLBAR_HEIGHT = 4 + OVERVIEW_TOGGLE_HEIGHT = 0 entries = [] for el in element.find(".rp-entry-wrapper") @@ -50,19 +52,6 @@ define [ sl_console.log "focused_entry_index", focused_entry_index - # As we go backwards, we run the risk of pushing things off the top of the editor. - # If we go through the entries before and assume they are as pushed together as they - # could be, we can work out the 'ceiling' that each one can't go through. I.e. the first - # on can't go beyond the toolbar height, the next one can't go beyond the bottom of the first - # one at this minimum height, etc. - heights = (entry.$layout_el.height() for entry in entries_before) - previousMinTop = TOOLBAR_HEIGHT - min_tops = [] - for height in heights - min_tops.push previousMinTop - previousMinTop += PADDING + height - min_tops.reverse() - positionLayoutEl = ($callout_el, original_top, top) -> if original_top <= top $callout_el.removeClass("rp-entry-callout-inverted") @@ -72,7 +61,7 @@ define [ $callout_el.css(top: top + line_height, height: original_top - top) # Put the focused entry as close to where it wants to be as possible - focused_entry_top = Math.max(previousMinTop, focused_entry.scope.entry.screenPos.y) + focused_entry_top = focused_entry.scope.entry.screenPos.y focused_entry.$box_el.css(top: focused_entry_top) focused_entry.$indicator_el.css(top: focused_entry_top) positionLayoutEl(focused_entry.$callout_el, focused_entry.scope.entry.screenPos.y, focused_entry_top) @@ -87,6 +76,8 @@ define [ entry.$indicator_el.css(top: top) positionLayoutEl(entry.$callout_el, original_top, top) sl_console.log "ENTRY", {entry: entry.scope.entry, top} + + lastBottom = previousBottom previousTop = focused_entry_top entries_before.reverse() # Work through backwards, starting with the one just above @@ -95,12 +86,22 @@ define [ height = entry.$layout_el.height() original_bottom = original_top + height bottom = Math.min(original_bottom, previousTop - PADDING) - top = Math.max(bottom - height, min_tops[i]) + top = bottom - height previousTop = top entry.$box_el.css(top: top) entry.$indicator_el.css(top: top) positionLayoutEl(entry.$callout_el, original_top, top) sl_console.log "ENTRY", {entry: entry.scope.entry, top} + + lastTop = top + if lastTop < TOOLBAR_HEIGHT + overflowTop = -lastTop + TOOLBAR_HEIGHT + else + overflowTop = 0 + scope.$emit "review-panel:sizes", { + overflowTop: overflowTop, + height: previousBottom + OVERVIEW_TOGGLE_HEIGHT + } scope.$applyAsync () -> layout() From b52e4a5d1c40081744744703a47eedb4c33f06ff Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 20 Feb 2017 15:46:53 +0100 Subject: [PATCH 11/17] Reset scroll margins when changing document --- .../ide/editor/directives/aceEditor.coffee | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index b3c607455b..faa1159e00 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -187,20 +187,25 @@ define [ scope.$on "#{scope.name}:set-scroll-size", (e, size) -> # Make sure that the editor has enough scroll margin above and below # to scroll the review panel with the given size - marginChanged = false - if editor.renderer.scrollMargin.top != size.overflowTop - window.editors[0].renderer.scrollMargin.top = size.overflowTop - marginChanged = true - + marginTop = size.overflowTop maxHeight = editor.renderer.layerConfig.maxHeight marginBottom = Math.max(size.height - maxHeight, 0) + setScrollMargins(marginTop, marginBottom) + + setScrollMargins = (marginTop, marginBottom) -> + marginChanged = false + if editor.renderer.scrollMargin.top != marginTop + editor.renderer.scrollMargin.top = marginTop + marginChanged = true if editor.renderer.scrollMargin.bottom != marginBottom editor.renderer.scrollMargin.bottom = marginBottom marginChanged = true - if marginChanged editor.renderer.updateFull() + resetScrollMargins = () -> + setScrollMargins(0,0) + scope.$watch "theme", (value) -> editor.setTheme("ace/theme/#{value}") @@ -325,6 +330,8 @@ define [ sharejs_doc.attachToAce(editor) editor.initing = false + resetScrollMargins() + # need to set annotations after attaching because attaching # deletes and then inserts document content session.setAnnotations scope.annotations From 8c5800ceafd6abad920600f6a4d35e08a0e51692 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 20 Feb 2017 16:03:02 +0100 Subject: [PATCH 12/17] Only render the entries that are visible in the text --- .../app/views/project/editor/review-panel.pug | 1 + .../track-changes/TrackChangesManager.coffee | 32 +++++++++++++++++-- .../controllers/ReviewPanelController.coffee | 6 +++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/services/web/app/views/project/editor/review-panel.pug b/services/web/app/views/project/editor/review-panel.pug index 93ff664eed..2ef5175cf2 100644 --- a/services/web/app/views/project/editor/review-panel.pug +++ b/services/web/app/views/project/editor/review-panel.pug @@ -47,6 +47,7 @@ .rp-entry-list-inner .rp-entry-wrapper( ng-repeat="(entry_id, entry) in reviewPanel.entries[editor.open_doc_id]" + ng-if="entry.visible" ) div(ng-if="entry.type === 'insert' || entry.type === 'delete'") change-entry( diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee index b75cb07dba..1e06acd4d5 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee @@ -60,6 +60,18 @@ define [ onChangeSession = (e) => @clearAnnotations() @redrawAnnotations() + @editor.session.on "changeScrollTop", onChangeScroll + + _scrollTimeout = null + onChangeScroll = () => + if _scrollTimeout? + return + else + _scrollTimeout = setTimeout () => + @recalculateVisibleEntries() + @$scope.$apply() + _scrollTimeout = null + , 200 bindToAce = () => @editor.on "changeSelection", onChangeSelection @@ -282,6 +294,7 @@ define [ recalculateReviewEntriesScreenPositions: () -> session = @editor.getSession() renderer = @editor.renderer + {firstRow, lastRow} = renderer.layerConfig entries = @_getCurrentDocEntries() for entry_id, entry of entries or {} doc_position = @_shareJsOffsetToAcePosition(entry.offset) @@ -290,9 +303,24 @@ define [ entry.screenPos ?= {} entry.screenPos.y = y entry.docPos = doc_position - + @recalculateVisibleEntries() @$scope.$apply() - + + recalculateVisibleEntries: () -> + OFFSCREEN_ROWS = 5 + CULL_AFTER = 100 # With less than this number of entries, don't bother culling to avoid little UI jumps when scrolling. + {firstRow, lastRow} = @editor.renderer.layerConfig + entries = @_getCurrentDocEntries() or {} + entriesLength = Object.keys(entries).length + changed = false + for entry_id, entry of entries + old = entry.visible + entry.visible = (entriesLength < CULL_AFTER) or (firstRow - OFFSCREEN_ROWS <= entry.docPos.row <= lastRow + OFFSCREEN_ROWS) + if (entry.visible != old) + changed = true + if changed + @$scope.$emit "editor:track-changes:visibility_changed" + _getCurrentDocEntries: () -> doc_id = @$scope.docId entries = @$scope.reviewPanel.entries[doc_id] ?= {} diff --git a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee index d0af889dda..33cfae0982 100644 --- a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee +++ b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee @@ -266,7 +266,11 @@ define [ updateEntries(doc_id) $scope.$broadcast "review-panel:recalculate-screen-positions" $scope.$broadcast "review-panel:layout" - + + $scope.$on "editor:track-changes:visibility_changed", () -> + $timeout () -> + $scope.$broadcast "review-panel:layout", false + $scope.$on "editor:focus:changed", (e, selection_offset_start, selection_offset_end, selection) -> doc_id = $scope.editor.open_doc_id entries = getDocEntries(doc_id) From ad05cc288cfcb70a795b981462b4d2c780c0cbee Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 20 Feb 2017 16:22:18 +0100 Subject: [PATCH 13/17] Do DOM reads first to prevent thrashing --- .../ide/review-panel/directives/reviewPanelSorted.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee index 551658eacb..f64b014410 100644 --- a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee @@ -33,6 +33,7 @@ define [ entry.$layout_el = entry.$box_el else entry.$layout_el = entry.$indicator_el + entry.height = entry.$layout_el.height() # Do all of our DOM reads first for perfomance, see http://wilsonpage.co.uk/preventing-layout-thrashing/ entries.push entry entries.sort (a,b) -> a.scope.entry.offset - b.scope.entry.offset @@ -69,7 +70,7 @@ define [ previousBottom = focused_entry_top + focused_entry.$layout_el.height() for entry in entries_after original_top = entry.scope.entry.screenPos.y - height = entry.$layout_el.height() + height = entry.height top = Math.max(original_top, previousBottom + PADDING) previousBottom = top + height entry.$box_el.css(top: top) @@ -83,7 +84,7 @@ define [ entries_before.reverse() # Work through backwards, starting with the one just above for entry, i in entries_before original_top = entry.scope.entry.screenPos.y - height = entry.$layout_el.height() + height = entry.height original_bottom = original_top + height bottom = Math.min(original_bottom, previousTop - PADDING) top = bottom - height From 6c21d198944c43c3bc7da48e8bbe83f11786de38 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 20 Feb 2017 16:24:19 +0100 Subject: [PATCH 14/17] Increase offscreen lines considered for visibility --- .../aceEditor/track-changes/TrackChangesManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee index 1e06acd4d5..38b3e5678c 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/track-changes/TrackChangesManager.coffee @@ -307,7 +307,7 @@ define [ @$scope.$apply() recalculateVisibleEntries: () -> - OFFSCREEN_ROWS = 5 + OFFSCREEN_ROWS = 20 CULL_AFTER = 100 # With less than this number of entries, don't bother culling to avoid little UI jumps when scrolling. {firstRow, lastRow} = @editor.renderer.layerConfig entries = @_getCurrentDocEntries() or {} From 5e07565c8e0cd785afaa59f7da7ed901568b7881 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 20 Feb 2017 15:37:12 +0000 Subject: [PATCH 15/17] Add retina icon for review features. --- .../web/public/img/review-icon-sprite@2x.png | Bin 0 -> 24635 bytes .../stylesheets/app/editor/review-panel.less | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 services/web/public/img/review-icon-sprite@2x.png diff --git a/services/web/public/img/review-icon-sprite@2x.png b/services/web/public/img/review-icon-sprite@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..20c66b093946cecba13b8357612f307eaceb544e GIT binary patch literal 24635 zcmeI4cT|&0*XSR>La)-Ls#xd=HByusq)IPRLJ}ZA03mciEP#p>3(`RZK@b#>CQ_yM z4gyMVN(TWc$_^ue)D+2xnTP=ZAX9?M zX<~mRu-|OL1K7VcZ0gn6A0h{+ffE3b&}@J4fXHYD03cRH$;xVISlMIjoviE~*p*~u z*&Q71El{>d0C4M#(Q?(lw@N29u!^M6m3cFt8D@J0;5?E>SVL*>i1ID~yG}`crqcHY zvF;&Ss%WTA#nnz?Xv~e_hbQta&)&LW7@%`OY?ke9a*mhB+|0~I_eSAF^u%V9dozU( z6*bqL@kiExxTdcJMiwt0p%HeRDfg5@wV3CYYc^Y|ixkpQVJ@R0prfcFZv_Di3~Ja94cOhkHV!nMyA zVRkOhG=nDU_sIy_txg>IQtf;BbI{4wVWG?mJhZnK^l#>CaH>|jztp@V$59(PO#S{c zXo2m)XQF$qWI&pqdZ}9O!JK;AQtw$j`~Y(OHW%QG_Y&`ICXzb-DpiC4AouXfsf@D+Ny`qUm6Au7u@silmK!3oDA@(&xp&!w{vo(Y? zFb>EKD)XQ>oK1xE5kdPnVNjvFK8ft_ZyY+$Sy|(lh@T>3ea9GjWRchLka*yQGwUIJ zHSC~Uo3{!T1@B+UI#1An?|kOv6E>z>RS%t7F+vo^J`Wz*v@&J0O8VqJN^Vu2bjAQ) zw}Rk4t%Bqhw|ih0Zu`rd-PC8|s-}aF=?m)y3&UCTMO|o_OJiYkgh%lMd}yW#O|DbE zw!In>qNuN;FZ<-!^pR}p0zy5aYu5!|ALqRHL_PbM2lZNon>i#iL|-9|YnFqRBleid zadH~dd(flgwRcC=h&hghfRsp-Y@mHm-bAfLsWwVfvJ3Pop%VI`iw3`z ze+rF|bL6qcC_35tMBaqXmPnK(YSoJWJ*I%@-8EMEu$Hhko5_RkC*EKC=t@fFM|Q0m zYJP&zhS8HTnIVsnKSCvGe|uO&jkZ8Hh&jSCoFd#_NB`8ysY|qX>Zn5@p}L{op%bav zI!-#$o$je5+D~;To|@=-B`N5<&=^S}>Y#htnZly;Dn;a3lcuX?utxKF(}ZHv&sW#s zWLbW`3J?9D3EJ?yD#kz#x+)NIL0_iJQI}wf$0l6W+$d{pTE%7m2D1ylr;3)WQ>sOp z#T|>7@r#XkGrO$QEz-TyMSDGZi+jyy9B1ferh4a` z9b(SJ@Wd=b(2!MUq5_eE^98;Iea_7vq}t(A?(d0~>z2viziU-oMt@9LrvEV4HP^}} zDj-BC62fRJC=o3 zBt0s4Tq^&x=v$GUvk7a zH@Mh36iy`$36-Z*q?Etcvt+i6cZyjOrcY81sizKe38U9SC*Ml8i}R=t9b=j;Xv=9| zPKbIH^)|f+-SMtLveN76hALkabFFc?yfM6@D@<2j5ZDl~?Tgs=_@MCq!2Pcd@RLf>%8(L~8L&Ct zvoEDzWL|@V-&*oSw$j!S#?TrvuM0GAsjzlY1^G1-4p4gAC#|WxZ^$LQF{o&JBcBb$ z7(u`0b?D?NP%7Vt^VwRMi+#cgJINLs!J!o%WJl zxAIe0aIOLqscUk(-(kG_^2m~^u3T4tT653E9$xYL(f6YhG|5m8vbnnj@=oNbTX1vV zBO7%eN7pgm^RHVSJ+kJs)JJRUtJ0c~t@%uYoKA)R3AdXOgOOW4vCupo$fN(?2w|UiD)n`5UtTC*wsk3P9 z{&q1)^IF^E$Fkg4^@KuG?$_4aJ^N_*5>5*XMd-{~hjkk1UOq)1YMSPd_T<^842Ash zVLdg|&P&Vg=-%G`b9r?$Q_!izDZ8{)gOcaximcCew)oAHr86%Cjxn2}&-G*CJ*=05 z8nYYg8VQ79!ZStvcb;Kg}!d;p*)wdFSf6M1GBh_H_T;{prFS zZZ|!fB6+W6ySCY@?}C}knF~tBz2D_4x~f;k275mCJh&o1H)V~nw|)D(q$G<7ttk@7 z3WYd~MfuqGM$JUJ<~SIhB7c2$tnBze(k0Ikjmh|?^0(!U0}+?=mI{*R4xCow`4D^BKpv7tK{oGw0cHy*r$LtYG<*%gPMBEAgz# zTVs!4x96M1y`MiET&MVOIr~c{vJ^e|$*k0@x!izaj-1Fp_RIaPcK@L^#RkRBBML_X zgJam(n8}!m77-CVZr0y?Gf%P>&|LD&J!Q#p?rF+% zNcE9ww!$WN$%UlN^rk+qx%|0;f$Ac*h!dMrvYJ7=2Y02;3gc2SeDKBl+CW4%jplo0&?xIl$mHNDR9<(h_AS$vO9`gp(bG zkmS@8RuxcnkVRUdpdOA$Ee|zqxQ7i~9Kk6qMJ(Y4!8$-AF)(&Fw5^>J#7&a(t6vCK z-Y(|nWdEvyv619FyWJqWzN!Yhti2}qB(C~z8^+Fws_LJOfAklP{$tZl72LWF;q?@;>P9J>J#FbwQJ zIoPST!vz8kv9NbU!!S}PG|Upo?_g&s!T+;xhbC@CLS*f2?H#c_LP~)p`2SS=M=R_N zSL53SSIS9KQHEVfURFd`b96#(uWd=rAB!6oE^yIc+vex6zP6y8C@~{9%25W&a2Je=sNC z*4(cfXy+Q)cJ-Hiw;cdgRUt}tP8gUS9H}HHg)QJip%4%e5eu*Y0xrlagb)$s6%r8# z^O}Ri1bIb4U=a~Pga90FF7h=r{%ZbntlwSB*~6W;Pg1PwZ%GHj9*%YYbAKWP1q4K4 z0%E*iF#&UI@D+ve!Yl;gykZDpb0M%eTo5UQ4O8Fxxx?9C8d7(}-plP^wmWpT$AZ8% zW)2cSAVfiMY${_8=M_SN5WHgI*z`qI1OZ2aK*GWZ5#b+A{K3s%nu4O7um_O)ueY<=7>CNiCrAKJIBBI{nhaI2L8K|_gjnKXTb^P@-OE= zNE{|&AqL|Wgdxp&g}~SaX>NfO;uRD}f)QYl09Zf-_G6BBOyTcC++I>U5My%|T+)F} z$FVt!I5ub5q44+izoOh#F14FE_}M|Y70k{OiIC#|(V-s&zxV0?{utl?-n9M975AnM7xV1xT#%0cBuvYx+YG(Xa}Z%b2QdqZvKG5)a0WKY6$Rx2fc}R{r4TXKO#m%l!nr zBXgA4erf{2=Azi-=xYR%!rrm}Qntg}*E;>}JF%_v*PKxlB!Kb%Z|%3@9ah_qcD_A?(84~>L~al5_oCmmHBfFyTYWhc_9o%9 zoe_&*$Mn_a_liFn8vHaA6#K<;N6mN3Z@Xm2Q^&8f@~ss6OcVP!l^^#!b;pF^Qt_*tbwHrz}ojqJQ6uS}jaP5W?PG=7n4#jSSJzTq?gwxr>g+s9$ zVGq}CDB*PWaN$twM%cr(8%j8xJzO{xyAk$q?S>LgXAc(+#cqT>T)Ux!)7is?L$MoS z57%xe;dJ(J;ZW>G*u%9ON;sW8TsRcF5%zHHh7wL^4;K!_ZiGEtyP<^B*~5iHu^V9z z*KR1`boOxJQ0zw7!?hbqIGsIQI25}P_HgZn5>96i7Y@a4ggsolp@h@f!-Ye!8(|OE zZYbe&_Hf})>_*tbwHrz}ojqJQ6uS}jaP5W?PG=7n4#jSSJzTq?gwxr>g+s9$;eW(M z{PPVZNIUFnNnEk-AE_?OjKjXWgdGmmR0RN!V*ucD4FJ}*u)psCz*ztQK9~UjBpd+f z?eCgaDgXfG9VNN5+HSqm(O&x6&b`$o$@m8l{t^2~70xqgP(ev5h+im{zYYVD-fXl* zf?Jh4G-;l*HeN_qO;c3=id`PT9)kB`VCkTx zpE!7e)Y7DhP<^8KnUkPXzx0yltGSKU4H+t#d7~`Pd1f$`{yw@Z@@8Lu=3?JXOp;|K z$Tqsx;>oqgB{T-5OqMWt$lgu$FvDxtSolb%O0bkuI6c`S0i+()agOEoIq7-nJ@$V} zzzN{lM>(A6io(mFDQ!Bclapi$v_E7NdJ>XLQ)W*ir=wF9wxn11kyb*I~alR(D zN@Yu!ZfMLAIOCs7&eF@aRybh6R9J~D?P-l~1+w%Z?0`>loU~t+diCH%!TDgXeY2X3 zl@n!om+g*-@;w-?a(!$iq2(juOxvBp1k@^}T89p9+b#g)na*{YEd(w(LT+BVA-RDJuEEp)9NWEK>-VHV> zRppFt2p;HiZL5|T;<}@eBi0 zzR`5I>1=*`Y;1Web;7#?s!?P2Is6;XeOb{9@G{nW%9EN;8{m3CV1(-|IF=?6V{auS z=V>N7mDxn+orBqo>sQan`J9ylQ($K&Bce^jG+SWb`I9zc0Zzoj(|yjy6lb>T`R*Wn zR6&Lh#(2j0Nb+GZzs>s*Rde0-^;DEpsAX1kU|?d>6Uv!h55VVDFomDgA_G1r=ShE` zIgIO&i7Q32i*~B$1BQ}=$wdbSLMVxSGT$+=ze#(QLu+LQ%s0&djcgaPIg`kt@a}QMh)1n> z^8Lk^uKgBb40Xr3n4iXAdp)<|MoJ-T-kL`kCwTAffqfcyRChYk$`wzdrbmjT?P^hP zTdbgQrP*3dPrAasEb@8J%(@Wf&dLy>xW&<%ta)p)RSO&xL2z;->)DF_4)qoN{5W8K zbfYfbe>V3{#*i7$u~?z z%{lKw9S?|?nrJL6#OlQe9>lZ8$L@s0O(*WQ8^tecE#{REQV2YId0AWR1K)kh_Vo9l z_AB`-pXIwe8B>d21@qjR$zPoxDw>P-jNZz)pO|VQTV1h`)KXB#CSdK&be^jOasDyH z$T_h%FFra^4O)Z%V+&l0&;dSe~emeu5qN0n-rlw`taAlr#Iy-72XIQtI zIUTE`RQtyZ^5;$s>lU8v8AY|eZ$&^(hQOF0)>*4ZE|pO?*{H%K{roef-lnaCJr?`c z)$)~&HjvhIKGjw3$bRQY=3IE`{ZXCeacl@H$Iw#X`7|X>S#4zoxlxdTu41gFYS}9V zJ}fT4Z(G9|{Fnk3Z(_L)e<{1kukq#1oqTf$#42b0uHe1LsxK8=a>Zhx1o$U%2^%^T z+16{|LHjANA&Jbm((|%B= zT*a=oclr9~_=-x1CY7E%Rl%oitdZu?xR_h5m!F(rot4YzWSk^oJ!VA6#HK91FPen~ zQjKvd=$5@&CwcmIwO4iJ$J?2nE`raP!BgVp7jN0He$tp`xE)(Uh@H%1fnIOlTy!UO z_n9qweEZGIB=%t14$6@5^~u7eHj507$%re1(W@-4ta)F1OAkEbsfd3gD3WYw|K1Qf z@;G49ZVmuQ7grU}bX-f5%2h4xil$gPVKd%6fPo&^c>E}?&x`!^c)TS9OhHhQmNP`k zopBoPFe~)oB_CCAI4{QWjQq7+GoMJ|L7{@9!d(woGt!1LYcCYt@~5W15m3sRLCAyu zcRvnWBL3ZmN!+yKuWZ{`EmCs`NEpbiDcVDCVGl@^oZPK#nfPpue}px9tA(}gAzwQy zF?u>)odpS#VL#|8)hyN>Som&HNN8|b7m<77z{y;Et{6kdL$ zWwPzDS3q2J39NzF!fwZ{WV}cZe4?zZ;T6w7yZ?BrzO(O?Hkr?;N{+7E46H!2EJczu zYW{?ItZGGhd)$@ej*A>MJp>y{s3t0H+RNpg#qFR@!=Y?{Os%061#LpPAj;&_u;w^% zg1=Zs+@YCwWa+hcWoeXM4n@+2`{lH-s;PO=Hb3|3JLXt;+14ZK(DavmCLqSbL@7Uu zhf^&%6{j_eUi$E6`-4r4d{N4#t|=??9_fCcg3b7Z`S`_p4vViTO`x_(kj%t~9P2~o zz8xsHg`EpCQ7?daX8W_o#?FU8pDgtpbXq~CxplFs2R4Q^Inde;>4_td*Qx!`BTLN& z(N3E$B;CMV)b>?!!=EfY0l-8`O1*EgHIpEjoA!36%c9R271LaNnb7H>Zn{3_8J75L z{}IbZm%5O03xBCzyG(UG1B>&O>ETN`{+TzMNi++Vt%XlEt>0MI?`w=IoLyMl=%bmw znTX*8E zUF=dEwBGPjn`;b*X6L*~kxUbFZbN0Ll9AoM>%P`rq;MSGL30m1n=)a$!ImcNg;yUu z4)PWN-eh{vem&OWnx$@VPc(@k$9iX%r*6j~6A~y-yWh&}CCfVNd4ie6m*P~1+i-;C z$&%7Dr+7fOdNC4V#F2N+B$D~0>6fjY2YO|DPg-`2@DI2%mtb5^?=#lDpz>kSDR7`& zYCW9MI>__JLeaCxrL9G?dEz z?ExbswO?}yX-%=rGTmEFgsNu`txq904)9%Rk>!l%yla~EE-dMVKj~yv;qyD856<;Q zKI^;C_R{oHQ$E)TiNnas$_h;TrbbzQ(uZN!v{jJy=d&R3seECCT*ksup7_?NG!HU0 z$7V8ItpCt@^({vgRU;X$#upc6w_d0z*4=6bue`Iiug=V|7dTDC`o&59tkk7TUN@8T zL_er_-?l4ao%j+{zn0)SwOo{w_?WRblIam4`S|h51RB>g?&0GNvDe&<@&xS?(^EJu z2gTj^g5dvxrf2npTq#)z@w4b;ZMu-jM5O${iF{sX42jrC+o!NWLQJ7}JYc1zy^pz4 zToKlr>7^0x=PxJY6_Imo)V{|GqivDQJA5hW{Yxw!SpNsoKI}&I5QFEIn}-ycExOL%$XU-JiZz)XwS^}xd+g^=-e2*^#JQs63UK0atI@U*#?XpJa=cv8a;8P46tgPIOr> zbNrsCf;Na{;n(YF4rrJzL<`CiQ<05rQ)FC z8U9Qg3mtnz75Crii4wkXb3br+19N<&p!TLD>jMzigW)>0L~dF)>+=waqtvIY&RxwM zxqIN$q{R_rMHBs^T4@W75#p@WyZZT7_ld`iCQsC7VAvjgdcH<7eJctZ5Tmrx(Y(Bg zi^Hx}9JAhA91P+vJWqqsG#SDZSXa_W&_z-N6fr-H^~1SCqwj)0A`kg|gSc zQFw3CB}eZL%fHGeja`{=}uMDM33H?1s}$$eKmd$y<7 z&(}@d$P=mPEzs6|+NhJ2-0X$AryISpUPdKcH^(1eI@o4LE?I;oTpV~YjTN#(w48))2Y6Q6$dRbHKZwks6!ec*J^73&x;PUE?XO@lCtLGH@CcWiX?u$7i+`NV#f9W literal 0 HcmV?d00001 diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index 1d1900c90c..e6f5d5e2ba 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -762,6 +762,10 @@ .toolbar .btn-full-height:active & { background-position-y: -60px; } + + @media (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { + background-image: url('/img/review-icon-sprite@2x.png'); + } } .resolved-comments-toggle { From e6997a8af05f4480d00ace9398a297bc52f9688e Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 20 Feb 2017 16:14:23 +0000 Subject: [PATCH 16/17] Add jank-free image. --- .../web/public/img/review-icon-sprite@2x.png | Bin 24635 -> 25495 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/services/web/public/img/review-icon-sprite@2x.png b/services/web/public/img/review-icon-sprite@2x.png index 20c66b093946cecba13b8357612f307eaceb544e..7a76326d63802d3c4f599f0835da77c666d45649 100644 GIT binary patch delta 5462 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 delta 4593 zcma)AcQ72>yIv(hlvT32MIuBER@q%G(R&M`cdLuUYT2wM!RiDFL5NQaA<9$+|p85m9PE_RGKj;JnatXTADpuWX)?1e)9he)Bkya zO4=58#LfQzKut0aUW&4>vnnqQVI+ZJe4(R$&n$$norAVC3ncWlmylm|#lEJb(==f> zX40nZzE-2v^(jM|E_T?*4Kk)TVaoCmJZxKGP+?$0&=TYIoji;he)+>%j)~HN*;SW< znGJE*gHOYiFNLgT@rcSj8U|UXbGIL%Hd=4{5Fiz>pmKz2-a9`zS7lP&x2eXU_PHQT zmXxd!8jk;jz1;cr4f^T=wc+4?GIe}j!EjRPMmy&dwbZgFj%0Y_gCDF06i2w0?Tt}I zK$(DfV6JGmFzV^|%bF1o01%^OTrLduB&%fU7!feX6*~a%Z#iV%rPQ%>Aox2%$=tQD z1D>M^Z6kr_Z>}Hif5znY>R-sRF0DQW+{M;0@DO-UTNV+VEj?}>vt#*VfND!PA0WIW zPbIq7sPEe&sr_U$<*q45&w6J)#_y)Q#H;1r;35yj`{8ndpy^UhK)+6z*UN8zpFIFD zR0XPsja5-+$V>J6WqMk`7{3O4nPOP}xXvX_BeyU8juB$&uwT2vDDKw-fx7}lwV0XHB-PSQfIRtBlZsWSd z^R>tnaQEbkZ_}=YUCYhMY}$s2mf<9;T5cD6yG>@x=eX%f=DoK}3GQ;a!X6Bn(9lYJ zcuj#C1b}H-FH3E$n1ZHNqN(L;lKJFsj7;uEsfO^6}BrfC`ac5G^C2iY>dTG8}2Q6L_K70y}FpfcrCnYo|A8;ycq{_zo>qR zgH5>lKJVL?ls-;V+E48lZu8A#ij-#sG4d;vJqmD;W6REdAA!`2$qQOVyjnb;jOkJ<0X21GF%Qzc(GNu<3 z|m@f3ym{sPyZs`VaV_<>0- z3^rc7-3t>&B+G_8!2Zhl+-u(^zT^iqT-9`%-W6rtr?PrHBCAJwYg{U#rl#~fFUMN0 zo=Yp#+tgd`6=>^3W#}6Q)^84oNsBYntY)Nm)DX$wsL$bkw-sXpM8{*=8v7CZdQ?Ek z4~-Zz=%z$EBfjFhG(Mt%^jiZnh2kh{Yfcu6+i5u2UuxaULFHUjrWcmktMzps6puCy z@Jf1xaheFWyP6ciZ2}A13Nv8|we`dSDva|sk*MOJa6jg-v#lFF%C{kM=Y%2cOybvi zcRLL8L*Yzx9@-$PMBh5Ns(bB}wutX3-So~e^X>5MM&&s^D_0h3|Luajv zp4b_yA2Us$)3l*8EBLW8{)erGuE?@Q%e~nZ&#~`gu5jTLCr-Fm^~ueroy;TN22M)R z*ed0()Nd6TMvz3ZnsUoU$ko^xeF0#CZIY8BnY|(bJB6s7*a- z|3I(p_YoXv-`>mpTu5Ktf0@?*=!f(6^yF0aRi-P0tWIYO&%2RgZ57ijcmO59ov#zs zG@;0K!#ujvPNZN0OM3C?if~FI9TgxaH25a5iAL1oIDL2aK5OOOJ)cM;N4}b~KNB6_ z@9@6E0*(G zwV~$Z)q_#y@bJLhW88pF|l6kh#ax{*pxbX1wTVUX8-9BL0Nvq<*4>Hc<;ryi9aA~LqubtV(~C&$tLH_3<;|fPKCR`u z!y!NlOm{hMiB7aqfs7lh{q||N0VGo#`S`BJ^E$`yEZJ`|O#-r0ufUb%%T@iht#Mdp zwwU;i8AFnUPx%0j?7ycSk5?Bd0DcqG`HgK!U(S7tJMBu8 z^dE?ndjZkWbe(GW+z4qw)&g+i^NfT%Qe{m=;yXP(V{|?{=!(#oWnk2n8GZPQKF%U! z$EnG*vs8&Ld;hj`u0eMfJ};tV;t~JnS&DOvj^_xI83@xg*@l;%v|g&kBKxg9fS`gd zDNlQmWz)551z2ch-u0b%`ilNkH5R>~>sg@8Xxu2+&=3v!@)13E>v0Rl=SlYU?LU{Msn6NtGa zgLWrB<<^{A-Pgq~A1B=md!r^esul~*&D~GYes?rW6+m(;519fRB@Snd_=9|w9>84P zBAKIoiAP_oasqzUD1|@-nIHD5FaLB$0RZ;O%0_b=V^tI-qM(Gypu_OH`VMvEsxP;f zrdj6#cX;w^u|)Ubpn;Sw1Xh`V@vAa=V1+R0smMISVXI=l(3&>eDR&#`RB)?TvCOU)y!{T(4rw0Ey)o~2W%i7H+rjn;BdXrU}kQ;d)=TmMQ=_!wV# zTB_5#w^=P6siA4rs&!wD!UUA7dLNza^DreD_}B6>BP+*hCTTzD0oxcRs-t3wgbLfSSKuN+jUenkLA5-ck@R(*?u6;(r-;HWY6z2bZ5noBh5g4clsvbycrCII4$T ztf+{&mEkbn8=26B>t}s&kM#{~R0W4?Y4@>ZC1+V{kGk97Mymj1)D=gw5WO4pQ&9ElaQ@|2jF1jo0o?re4ag zu%eV7lav?p$Mw!1Up6ob9??!piAGFPpja64gzs5aZc{uBVG((h#FF!5*-grrn)50d*+~vGJk$G)+O|lkS za)ODDyfp~>C>!-MG07PXy%|5dFtX9#3|ClkDpqQ-uyMhu8_ezSY1Lke&(0dM=vlrJ z#-}xiUViff^Wxhj&6Kq>xO9jmqxnyBh5`b6bbfW3khTpzF#f!+Xs9UNWGHMSi=?H! zI>g?-JgO`sZfE$5oI>~?hf9u&4-gCaZ00SC1j%RdHd)=f57cqesKZT@t;+uawapnvM ze4`TxG0MntS0n$V*{LU35J%eO=Pe%U9o?q}bX@pZerfRA-IUdopX6o*Y;Md_W3B|S zRyXEH;2rEa^1Cyv6tvAlIiw0>*=0A6?z~|JORuH@XxK5zg0XSEr#wHnKNh-PG;IIQXvb;1iT>xuQ`+sg>`Q6PzF*-h zE?#)J9Nf#l8+O6Z4hs@{pX|$0DZAdKIPm1;S1^yM%0v0gn53`@;Nt*>S^PMV^1knoy|39n-PsJ8E%&mu)x$Xy(#cdYovH(;lQsCG0&pIs!sTv%5x>W1t z+jj5GVhGVuAut=1n^u_Q__Tt}B$&am#t0R{ruU$-$HfANC0EIL{OP!u>*EPRbV-ry ztq$h2>TCi`>KZQsq|c&^lzCDskq{FfbrrIX$Jy?-@_M`dTpx+MvpxSAAY81(s@8Zql z>mdw3jc_wtRG&=rvm_1D%$ zK^Y+eL7u=j-vZ}bwLj^WxLGC!Oj~^Y>N|aS5fv+Xp#HCaf&cy Date: Tue, 21 Feb 2017 09:58:49 +0100 Subject: [PATCH 17/17] Make sure first change isn't hidden under toolbar --- .../coffee/ide/review-panel/directives/reviewPanelSorted.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee index f64b014410..b76f891e7f 100644 --- a/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelSorted.coffee @@ -62,7 +62,7 @@ define [ $callout_el.css(top: top + line_height, height: original_top - top) # Put the focused entry as close to where it wants to be as possible - focused_entry_top = focused_entry.scope.entry.screenPos.y + focused_entry_top = Math.max(focused_entry.scope.entry.screenPos.y, TOOLBAR_HEIGHT) focused_entry.$box_el.css(top: focused_entry_top) focused_entry.$indicator_el.css(top: focused_entry_top) positionLayoutEl(focused_entry.$callout_el, focused_entry.scope.entry.screenPos.y, focused_entry_top)