You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by mo...@apache.org on 2015/11/10 13:47:13 UTC
incubator-zeppelin git commit: ZEPPELIN-401 Improve autoscroll
Repository: incubator-zeppelin
Updated Branches:
refs/heads/master f3de6cd7e -> 6ba4cf96a
ZEPPELIN-401 Improve autoscroll
Addresses https://issues.apache.org/jira/browse/ZEPPELIN-401
This PR improves autoscroll behavior when using keyboard navigation (up/down key)
* When cursor closes to edge of top/bottom of notebook, autoscroll triggers
* Autoscroll will scroll notebook to position cursor to the middle of browser window
* When last paragraph is executed, a new paragraph is inserted after. now notebook autoscrolls to newly inserted paragraph.
Author: Lee moon soo <mo...@apache.org>
This patch had conflicts when merged, resolved by
Committer: Lee moon soo <mo...@apache.org>
Closes #400 from Leemoonsoo/improve_scroll and squashes the following commits:
e1170b4 [Lee moon soo] Do not skip paragraph only hides result when move cursor
3d6a3e1 [Lee moon soo] fix style and condition for tail last paragraph
53d48ac [Lee moon soo] Remove unncessary console.log
9229bd2 [Lee moon soo] Uncomment cursor force positioning
46055f5 [Lee moon soo] Replace hardcoded value
71be96b [Lee moon soo] tail last paragraph
ca865fa [Lee moon soo] Moving focus of paragraph by keyboard reset cursor to the beginning (or ending) position of the editor
39108a0 [Lee moon soo] Scroll to cursor position
Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/6ba4cf96
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/6ba4cf96
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/6ba4cf96
Branch: refs/heads/master
Commit: 6ba4cf96aecad6a316d6c74f9a336a20585044c6
Parents: f3de6cd
Author: Lee moon soo <mo...@apache.org>
Authored: Sun Nov 8 21:00:26 2015 +0900
Committer: Lee moon soo <mo...@apache.org>
Committed: Tue Nov 10 21:47:27 2015 +0900
----------------------------------------------------------------------
.../src/app/notebook/notebook.controller.js | 8 +-
.../notebook/paragraph/paragraph.controller.js | 78 +++++++++++++++++++-
2 files changed, 80 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/6ba4cf96/zeppelin-web/src/app/notebook/notebook.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js
index d8ee83f..dc986a9 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -313,8 +313,8 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
}
} else {
var p = $scope.note.paragraphs[i];
- if (!p.config.hide && !p.config.editorHide && !p.config.tableHide) {
- $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id);
+ if (!p.config.hide && !p.config.editorHide) {
+ $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id, -1);
break;
}
}
@@ -331,8 +331,8 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro
}
} else {
var p = $scope.note.paragraphs[i];
- if (!p.config.hide && !p.config.editorHide && !p.config.tableHide) {
- $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id);
+ if (!p.config.hide && !p.config.editorHide) {
+ $scope.$broadcast('focusParagraph', $scope.note.paragraphs[i].id, 0);
break;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/6ba4cf96/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
index 63c30c4..0ba155f 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -167,6 +167,7 @@ angular.module('zeppelinWebApp')
var oldGraphMode = $scope.getGraphMode();
var newGraphMode = $scope.getGraphMode(data.paragraph);
var resultRefreshed = (data.paragraph.dateFinished !== $scope.paragraph.dateFinished);
+ var statusChanged = (data.paragraph.status !== $scope.paragraph.status);
//console.log("updateParagraph oldData %o, newData %o. type %o -> %o, mode %o -> %o", $scope.paragraph, data, oldType, newType, oldGraphMode, newGraphMode);
@@ -223,7 +224,14 @@ angular.module('zeppelinWebApp')
} else if (newType === 'ANGULAR' && resultRefreshed) {
$scope.renderAngular();
}
+
+ if (statusChanged || resultRefreshed) {
+ // when last paragraph runs, zeppelin automatically appends new paragraph.
+ // this broadcast will focus to the newly inserted paragraph
+ $rootScope.$broadcast('scrollToCursor');
+ }
}
+
});
$scope.isRunning = function() {
@@ -586,12 +594,15 @@ angular.module('zeppelinWebApp')
} else {
var numRows;
var currentRow;
+
if (keyCode === 38 || (keyCode === 80 && e.ctrlKey)) { // UP
numRows = $scope.editor.getSession().getLength();
currentRow = $scope.editor.getCursorPosition().row;
if (currentRow === 0) {
// move focus to previous paragraph
$scope.$emit('moveFocusToPreviousParagraph', $scope.paragraph.id);
+ } else {
+ $scope.scrollToCursor($scope.paragraph.id, -1);
}
} else if (keyCode === 40 || (keyCode === 78 && e.ctrlKey)) { // DOWN
numRows = $scope.editor.getSession().getLength();
@@ -599,6 +610,8 @@ angular.module('zeppelinWebApp')
if (currentRow === numRows-1) {
// move focus to next paragraph
$scope.$emit('moveFocusToNextParagraph', $scope.paragraph.id);
+ } else {
+ $scope.scrollToCursor($scope.paragraph.id, 1);
}
}
}
@@ -615,6 +628,54 @@ angular.module('zeppelinWebApp')
editor.resize();
};
+ $rootScope.$on('scrollToCursor', function(event) {
+ $scope.scrollToCursor($scope.paragraph.id, 0);
+ });
+
+ /** scrollToCursor if it is necessary
+ * when cursor touches scrollTriggerEdgeMargin from the top (or bottom) of the screen, it autoscroll to place cursor around 1/3 of screen height from the top (or bottom)
+ * paragraphId : paragraph that has active cursor
+ * lastCursorMove : 1(down), 0, -1(up) last cursor move event
+ **/
+ $scope.scrollToCursor = function(paragraphId, lastCursorMove) {
+ if (!$scope.editor.isFocused()) {
+ // only make sense when editor is focused
+ return;
+ }
+ var lineHeight = $scope.editor.renderer.lineHeight;
+ var headerHeight = 103; // menubar, notebook titlebar
+ var scrollTriggerEdgeMargin = 50;
+
+ var documentHeight = angular.element(document).height();
+ var windowHeight = angular.element(window).height(); // actual viewport height
+
+ var scrollPosition = angular.element(document).scrollTop();
+ var editorPosition = angular.element('#'+paragraphId+'_editor').offset();
+ var position = $scope.editor.getCursorPosition();
+ var lastCursorPosition = $scope.editor.renderer.$cursorLayer.getPixelPosition(position, true);
+
+ var calculatedCursorPosition = editorPosition.top + lastCursorPosition.top + 16*lastCursorMove;
+
+ var scrollTargetPos;
+ if (calculatedCursorPosition < scrollPosition + headerHeight + scrollTriggerEdgeMargin) {
+ scrollTargetPos = calculatedCursorPosition - headerHeight - ((windowHeight-headerHeight)/3);
+ if (scrollTargetPos < 0) {
+ scrollTargetPos = 0;
+ }
+ } else if(calculatedCursorPosition > scrollPosition + scrollTriggerEdgeMargin + windowHeight - headerHeight) {
+ scrollTargetPos = calculatedCursorPosition - headerHeight - ((windowHeight-headerHeight)*2/3);
+
+ if (scrollTargetPos > documentHeight) {
+ scrollTargetPos = documentHeight;
+ }
+ }
+ angular.element('body').scrollTo(scrollTargetPos, {duration:200});
+ };
+
+ var setEditorHeight = function(id, height) {
+ angular.element('#' + id).height(height.toString() + 'px');
+ };
+
$scope.getEditorValue = function() {
return $scope.editor.getValue();
};
@@ -653,10 +714,23 @@ angular.module('zeppelinWebApp')
}
});
- $scope.$on('focusParagraph', function(event, paragraphId) {
+ $scope.$on('focusParagraph', function(event, paragraphId, cursorPos) {
if ($scope.paragraph.id === paragraphId) {
+ // focus editor
$scope.editor.focus();
- $('body').scrollTo('#'+paragraphId+'_editor', 300, {offset:-60});
+
+ // move cursor to the first row (or the last row)
+ var row;
+ if (cursorPos >= 0) {
+ row = cursorPos;
+ var column = 0;
+ $scope.editor.gotoLine(row, 0);
+ } else {
+ row = $scope.editor.session.getLength() - 1;
+ $scope.editor.gotoLine(row + 1, 0);
+ }
+
+ $scope.scrollToCursor($scope.paragraph.id, 0);
}
});