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 2017/05/28 00:34:33 UTC
zeppelin git commit: [ZEPPELIN-2460] Highlight active line in editor
Repository: zeppelin
Updated Branches:
refs/heads/master cc0839efd -> ecb688f45
[ZEPPELIN-2460] Highlight active line in editor
### What is this PR for?
Highlight active line.
### What type of PR is it?
[Improvement]
### Todos
* [x] - Added ui-ace option
* [x] - Fix css for paragraph control not to be overrided by active line
### What is the Jira issue?
[ZEPPELIN-2460](https://issues.apache.org/jira/browse/ZEPPELIN-2460)
### How should this be tested?
1. Build: `mvn clean package -DskipTests; ./bin/zeppelin-daemon.sh restart`
2. Open a note and write some text.
### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? - NO
* Is there breaking changes for older versions? - NO
* Does this needs documentation? - NO
Author: 1ambda <1a...@gmail.com>
Closes #2356 from 1ambda/ZEPPELIN-2460/highlight-active-line and squashes the following commits:
2809093 [1ambda] fix: xpath for select, checkbox DOM
087942b [1ambda] fix: Use ng-if for title
e60f9a2 [1ambda] feat: Display title, control in the same line
bfa2fed [1ambda] fix: Set active line when note is created
ade9179 [1ambda] fix: Use blue-light color for active line
0366948 [1ambda] fix: Show single active line in a note
dfcb8aa [1ambda] fix: Control setting CSS not to overwrite active line
6424db5 [1ambda] feat: Highlight active line in editor
Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/ecb688f4
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/ecb688f4
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/ecb688f4
Branch: refs/heads/master
Commit: ecb688f45397be8c2e879663908b95c8a35964ec
Parents: cc0839e
Author: 1ambda <1a...@gmail.com>
Authored: Mon May 22 08:14:25 2017 +0900
Committer: Lee moon soo <mo...@apache.org>
Committed: Sun May 28 09:34:12 2017 +0900
----------------------------------------------------------------------
.../integration/ParagraphActionsIT.java | 16 ++++----
.../src/app/notebook/notebook.controller.js | 6 ++-
.../notebook/paragraph/paragraph-control.html | 7 ++--
.../notebook/paragraph/paragraph.controller.js | 9 +++--
.../src/app/notebook/paragraph/paragraph.css | 35 +++++++++--------
.../src/app/notebook/paragraph/paragraph.html | 41 +++++++++++---------
.../components/editor/ace.editor.directive.html | 5 +--
7 files changed, 64 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java
index add23ac..414460b 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java
@@ -253,7 +253,6 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
} catch (Exception e) {
handleException("Exception in ParagraphActionsIT while testDisableParagraphRunButton ", e);
}
-
}
@Test
@@ -263,7 +262,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
}
try {
String xpathToRunOnSelectionChangeCheckbox = getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-checked, 'true')]";
- String xpathToDropdownMenu = getParagraphXPath(1) + "//select";
+ String xpathToDropdownMenu = "(" + (getParagraphXPath(1) + "//select)[2]");
String xpathToResultText = getParagraphXPath(1) + "//div[contains(@id,\"_html\")]";
createNewNote();
@@ -593,7 +592,8 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
CoreMatchers.equalTo("Howdy "));
- Select dropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[1]"))));
+ Select dropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[2]"))));
+
dropDownMenu.selectByVisibleText("Alice");
collector.checkThat("After selection in drop down menu, output should display the newly selected option",
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
@@ -602,7 +602,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click();
clickAndWait(By.xpath(getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-checked, 'true')]"));
- Select sameDropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[1]"))));
+ Select sameDropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[2]"))));
sameDropDownMenu.selectByVisibleText("Bob");
collector.checkThat("After 'Run on selection change' checkbox is unchecked, the paragraph should not run if selecting a different option",
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
@@ -632,7 +632,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
CoreMatchers.containsString("Greetings han and leia and luke"));
- WebElement firstCheckbox = driver.findElement(By.xpath("(" + getParagraphXPath(1) + "//input[@type='checkbox'])[1]"));
+ WebElement firstCheckbox = driver.findElement(By.xpath("(" + getParagraphXPath(1) + "//input[@type='checkbox'])[2]"));
firstCheckbox.click();
collector.checkThat("After unchecking one of the boxes, we can see the newly updated output without the option we unchecked",
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
@@ -641,7 +641,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click();
clickAndWait(By.xpath(getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-checked, 'true')]"));
- WebElement secondCheckbox = driver.findElement(By.xpath("(" + getParagraphXPath(1) + "//input[@type='checkbox'])[2]"));
+ WebElement secondCheckbox = driver.findElement(By.xpath("(" + getParagraphXPath(1) + "//input[@type='checkbox'])[3]"));
secondCheckbox.click();
collector.checkThat("After 'Run on selection change' checkbox is unchecked, the paragraph should not run if check box state is modified",
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
@@ -676,7 +676,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
CoreMatchers.equalTo("Howdy \nHowdy "));
- Select dropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[1]"))));
+ Select dropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[2]"))));
dropDownMenu.selectByVisibleText("Apple");
collector.checkThat("After selection in drop down menu, output should display the new option we selected",
driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'text plainTextContent')]")).getText(),
@@ -685,7 +685,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT {
driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click();
clickAndWait(By.xpath(getParagraphXPath(1) + "//ul/li/form/input[contains(@ng-checked, 'true')]"));
- Select sameDropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[2]"))));
+ Select sameDropDownMenu = new Select(driver.findElement(By.xpath("(" + (getParagraphXPath(1) + "//select)[3]"))));
sameDropDownMenu.selectByVisibleText("Earth");
waitForParagraph(1, "FINISHED");
collector.checkThat("After 'Run on selection change' checkbox is unchecked, the paragraph should not run if selecting a different option",
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/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 3944326..a512664 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -469,10 +469,12 @@ function NotebookCtrl ($scope, $route, $routeParams, $location, $rootScope,
let addPara = function (paragraph, index) {
$scope.note.paragraphs.splice(index, 0, paragraph)
- _.each($scope.note.paragraphs, function (para) {
+ $scope.note.paragraphs.map(para => {
if (para.id === paragraph.id) {
para.focus = true
- $scope.$broadcast('focusParagraph', para.id, 0, false)
+
+ // we need `$timeout` since angular DOM might not be initialized
+ $timeout(() => { $scope.$broadcast('focusParagraph', para.id, 0, false) })
}
})
}
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
index 222b3b3..5523609 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph-control.html
@@ -44,11 +44,12 @@ limitations under the License.
<!-- Run / Cancel button -->
<span ng-if="!revisionView">
- <span class="icon-control-play" style="cursor:pointer;color:#3071A9" tooltip-placement="top" uib-tooltip="Run this paragraph (Shift+Enter)"
+ <span class="icon-control-play" style="cursor:pointer;color:#3071A9"
+ tooltip-placement="top" uib-tooltip="Run this paragraph (Shift+Enter)"
ng-click="runParagraphFromButton(getEditorValue())"
ng-show="paragraph.status!='RUNNING' && paragraph.status!='PENDING' && paragraph.config.enabled"></span>
- <span class="icon-control-pause" style="cursor:pointer;color:#CD5C5C" tooltip-placement="top"
- uib-tooltip="Cancel (Ctrl+{{ (isMac ? 'Option' : 'Alt') }}+C)"
+ <span class="icon-control-pause" style="cursor:pointer;color:#CD5C5C"
+ tooltip-placement="top" uib-tooltip="Cancel (Ctrl+{{ (isMac ? 'Option' : 'Alt') }}+C)"
ng-click="cancelParagraph(paragraph)"
ng-show="paragraph.status=='RUNNING' || paragraph.status=='PENDING'"></span>
<span ng-show="paragraph.runtimeInfos.jobUrl.length == 1">
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/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 e333084..00be23e 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js
@@ -647,10 +647,10 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca
$scope.editor.renderer.setShowGutter($scope.paragraph.config.lineNumbers)
$scope.editor.setShowFoldWidgets(false)
$scope.editor.setHighlightActiveLine(false)
- $scope.editor.setHighlightGutterLine(false)
$scope.editor.getSession().setUseWrapMode(true)
$scope.editor.setTheme('ace/theme/chrome')
$scope.editor.setReadOnly($scope.isRunning($scope.paragraph))
+ $scope.editor.setHighlightActiveLine($scope.paragraphFocused)
if ($scope.paragraphFocused) {
let prefix = '%' + getInterpreterName($scope.paragraph.text)
@@ -853,8 +853,11 @@ function ParagraphCtrl ($scope, $rootScope, $route, $window, $routeParams, $loca
}
}
- const handleFocus = function (value, isDigestPass) {
- $scope.paragraphFocused = value
+ const handleFocus = function (focused, isDigestPass) {
+ $scope.paragraphFocused = focused
+
+ if ($scope.editor) { $scope.editor.setHighlightActiveLine(focused) }
+
if (isDigestPass === false || isDigestPass === undefined) {
// Protect against error in case digest is already running
$timeout(function () {
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/zeppelin-web/src/app/notebook/paragraph/paragraph.css
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.css b/zeppelin-web/src/app/notebook/paragraph/paragraph.css
index b17acf7..1a5e992 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.css
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.css
@@ -113,7 +113,6 @@
display: none;
float: right;
color: #999;
- margin-top: -9px;
margin-right: 0;
position: absolute;
clear: both;
@@ -175,18 +174,12 @@
}
.paragraph .control {
- background: rgba(255,255,255,0.85);
+ display: inline-block;
float: right;
+ background: rgba(255,255,255,0.85);
color: #999;
- margin-top: 1px;
- margin-right: 5px;
- position: absolute;
- clear: both;
- right: 15px;
- top: 16px;
- text-align: right;
font-size: 12px;
- padding: 4px;
+ margin-top: 5px;
}
.paragraph .control li {
@@ -275,8 +268,11 @@ table.table-shortcut {
*/
.paragraph .title {
- margin: 0;
+ display: inline-block;
+ float: left;
font-size: 12px;
+ margin-bottom: 7px;
+ min-height: 24px;
}
.paragraph .title div {
@@ -370,10 +366,22 @@ table.table-shortcut {
direction: ltr;
}
+/** set highlight line color */
+#main .ace-chrome .ace_marker-layer .ace_active-line {
+ background: rgba(114, 127, 222, 0.08);
+}
+
+/** hide not focused cursors */
.ace_hidden-cursors {
opacity: 0;
}
+/** set cursor color */
+#main .emacs-mode .ace_cursor {
+ background: #C0C0C0!important;
+ border: none !important;
+}
+
.ace_text-input, .ace_gutter, .ace_layer,
.emacs-mode, .ace_text-layer, .ace_cursor-layer,
.ace_cursor, .ace_scrollbar {
@@ -384,11 +392,6 @@ table.table-shortcut {
opacity: 0 !important;
}
-#main .emacs-mode .ace_cursor {
- background: #C0C0C0!important;
- border: none !important;
-}
-
/*
Table Display CSS
*/
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/zeppelin-web/src/app/notebook/paragraph/paragraph.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.html b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
index 0de5e64..367d3e7 100644
--- a/zeppelin-web/src/app/notebook/paragraph/paragraph.html
+++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.html
@@ -15,24 +15,29 @@ limitations under the License.
<div id="{{paragraph.id}}_container"
ng-class="{'paragraph': !asIframe, 'paragraphAsIframe': asIframe}">
- <div ng-if="paragraph.config.title"
- id="{{paragraph.id}}_title"
- ng-controller="ElasticInputCtrl as input"
- class="title">
- <input type="text"
- pu-elastic-input
- style="min-width: 400px; max-width: 80%;"
- placeholder="Untitled"
- ng-model="paragraph.title"
- ng-if="input.showEditor"
- ng-escape="input.showEditor = false; paragraph.title = oldTitle;"
- ng-blur="setTitle(paragraph); input.showEditor = false"
- ng-enter="setTitle(paragraph); input.showEditor = false"
- focus-if="input.showEditor" />
- <div ng-click="input.showEditor = !asIframe && !viewOnly && !revisionView; oldTitle = paragraph.title;"
- ng-show="!input.showEditor"
- ng-bind-html="paragraph.title || 'Untitled'">
+ <div>
+ <div ng-if="paragraph.config.title"
+ id="{{paragraph.id}}_title"
+ ng-controller="ElasticInputCtrl as input"
+ class="title">
+ <input type="text"
+ pu-elastic-input
+ style="min-width: 400px; max-width: 80%;"
+ placeholder="Untitled"
+ ng-model="paragraph.title"
+ ng-if="input.showEditor"
+ ng-escape="input.showEditor = false; paragraph.title = oldTitle;"
+ ng-blur="setTitle(paragraph); input.showEditor = false"
+ ng-enter="setTitle(paragraph); input.showEditor = false"
+ focus-if="input.showEditor" />
+ <div ng-click="input.showEditor = !asIframe && !viewOnly && !revisionView; oldTitle = paragraph.title;"
+ ng-show="!input.showEditor"
+ ng-bind-html="paragraph.title || 'Untitled'">
+ </div>
</div>
+
+ <div ng-include src="'app/notebook/paragraph/paragraph-control.html'"></div>
+ <div style="display: inline-block; clear: both;"></div>
</div>
<div>
@@ -63,8 +68,6 @@ limitations under the License.
</div>
</div>
- <div ng-include src="'app/notebook/paragraph/paragraph-control.html'"></div>
-
<div ng-if="!asIframe" class="paragraphFooter">
<div ng-show="!paragraph.config.tableHide && !viewOnly"
id="{{paragraph.id}}_executionTime"
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ecb688f4/zeppelin-web/src/components/editor/ace.editor.directive.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/editor/ace.editor.directive.html b/zeppelin-web/src/components/editor/ace.editor.directive.html
index 4729e4b..1c0a1f0 100644
--- a/zeppelin-web/src/components/editor/ace.editor.directive.html
+++ b/zeppelin-web/src/components/editor/ace.editor.directive.html
@@ -13,10 +13,7 @@ limitations under the License.
-->
<div class="editor"
- ui-ace="{
- onLoad : onLoad,
- require : ['ace/ext/language_tools']
- }"
+ ui-ace="{ onLoad : onLoad, require : ['ace/ext/language_tools'] }"
ng-model="paragraph.text"
ng-class="{'paragraph-disable': paragraph.status == 'RUNNING' || paragraph.status == 'PENDING' || revisionView === true,
'paragraph-text--dirty' : dirtyText !== originalText && dirtyText !== undefined}">