From 599c540c20c084732d5bd905fa826309b69e8b86 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 28 Jul 2012 17:38:04 +0400 Subject: [PATCH 1/4] move gutterDecorations to session --- lib/ace/edit_session.js | 27 +++++++++++++++++++++++++++ lib/ace/layer/gutter.js | 26 +++++++++++++------------- lib/ace/virtual_renderer.js | 10 ++-------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 144f2aff..b9abb59d 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -72,6 +72,7 @@ var SearchHighlight = require("./search_highlight").SearchHighlight; var EditSession = function(text, mode) { this.$modified = true; this.$breakpoints = []; + this.$decorations = []; this.$frontMarkers = {}; this.$backMarkers = {}; this.$markerId = 1; @@ -489,7 +490,33 @@ var EditSession = function(text, mode) { this.toggleOverwrite = function() { this.setOverwrite(!this.$overwrite); }; + + /** + * EditSession.addGutterDecoration(row, className) -> Void + * - row (Number): The row number + * - className (String): The class to add + * + * Adds `className` to the `row`, to be used for CSS stylings and whatnot. + **/ + this.addGutterDecoration = function(row, className) { + if (!this.$decorations[row]) + this.$decorations[row] = ""; + this.$decorations[row] += " " + className; + this._emit("changeBreakpoint", {}); + }; + /** + * EditSession.removeGutterDecoration(row, className)-> Void + * - row (Number): The row number + * - className (String): The class to add + * + * Removes `className` from the `row`. + **/ + this.removeGutterDecoration = function(row, className) { + this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, ""); + this._emit("changeBreakpoint", {}); + }; + /** * EditSession.getBreakpoints() -> Array * diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index 2bf3bc53..7c70bbd3 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -52,9 +52,7 @@ var Gutter = function(parentEl) { this.gutterWidth = 0; - this.$breakpoints = []; this.$annotations = []; - this.$decorations = []; }; (function() { @@ -66,13 +64,15 @@ var Gutter = function(parentEl) { }; this.addGutterDecoration = function(row, className){ - if (!this.$decorations[row]) - this.$decorations[row] = ""; - this.$decorations[row] += " " + className; + if (window.console) + console.warn && console.warn("deprecated use session.addGutterDecoration"); + this.session.addGutterDecoration(row, className); }; this.removeGutterDecoration = function(row, className){ - this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, ""); + if (window.console) + console.warn && console.warn("deprecated use session.removeGutterDecoration"); + this.session.removeGutterDecoration(row, className); }; this.setAnnotations = function(annotations) { @@ -103,8 +103,6 @@ var Gutter = function(parentEl) { }; this.update = function(config) { - this.$config = config; - var emptyAnno = {className: "", text: []}; var html = []; var i = config.firstRow; @@ -113,6 +111,7 @@ var Gutter = function(parentEl) { var foldStart = fold ? fold.start.row : Infinity; var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets; var breakpoints = this.session.$breakpoints; + var decorations = this.session.$decorations; while (true) { if(i > foldStart) { @@ -124,12 +123,13 @@ var Gutter = function(parentEl) { break; var annotation = this.$annotations[i] || emptyAnno; - html.push("
", (i)); + "' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", + i + 1 + ); if (foldWidgets) { var c = foldWidgets[i]; diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 6a6dae4b..db5e5435 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -875,26 +875,20 @@ var VirtualRenderer = function(container, theme) { /** * VirtualRenderer.addGutterDecoration(row, className) -> Void - * - row (Number): The row number - * - className (String): The class to add * - * Adds `className` to the `row`, to be used for CSS stylings and whatnot. + * Deprecated (moved to EditSession) **/ this.addGutterDecoration = function(row, className){ this.$gutterLayer.addGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); }; /** * VirtualRenderer.removeGutterDecoration(row, className)-> Void - * - row (Number): The row number - * - className (String): The class to add * - * Removes `className` from the `row`. + * Deprecated (moved to EditSession) **/ this.removeGutterDecoration = function(row, className){ this.$gutterLayer.removeGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); }; /** From 542364bf325b87c623212359d69e73e2c2c20287 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 30 Jul 2012 18:57:22 +0400 Subject: [PATCH 2/4] add support for breakpoint types (condition/disabled etc.) --- lib/ace/edit_session.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index b9abb59d..886d3719 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -490,7 +490,7 @@ var EditSession = function(text, mode) { this.toggleOverwrite = function() { this.setOverwrite(!this.$overwrite); }; - + /** * EditSession.addGutterDecoration(row, className) -> Void * - row (Number): The row number @@ -533,11 +533,8 @@ var EditSession = function(text, mode) { * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event. * **/ - this.setBreakpoints = function(rows) { - this.$breakpoints = []; - for (var i=0; i Date: Mon, 6 Aug 2012 22:15:49 +0400 Subject: [PATCH 3/4] show tooltips immediately --- lib/ace/css/editor.css | 15 ++++ lib/ace/layer/gutter.js | 3 +- lib/ace/mouse/default_gutter_handler.js | 96 ++++++++++++++++++++++++- lib/ace/mouse/mouse_handler.js | 2 +- 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index f0d31f10..ac64e002 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -237,6 +237,21 @@ cursor: move; } +.ace_gutter_tooltip { + background-color: #FFFFD5; + border: 1px solid gray; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4); + color: black; + display: inline-block; + padding: 4px; + position: absolute; + z-index: 300; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + cursor: default; +} + .ace_folding-enabled > .ace_gutter-cell { padding-right: 13px; } diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index 7c70bbd3..1c6607cb 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -103,7 +103,7 @@ var Gutter = function(parentEl) { }; this.update = function(config) { - var emptyAnno = {className: "", text: []}; + var emptyAnno = {className: ""}; var html = []; var i = config.firstRow; var lastRow = config.lastRow; @@ -126,7 +126,6 @@ var Gutter = function(parentEl) { html.push( "
", i + 1 ); diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index 0fbadfb7..813f68e9 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -39,14 +39,16 @@ define(function(require, exports, module) { "use strict"; var dom = require("../lib/dom"); +var event = require("../lib/event"); function GutterHandler(mouseHandler) { var editor = mouseHandler.editor; + var gutter = editor.renderer.$gutterLayer; mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) { if (!editor.isFocused()) return; - var gutterRegion = editor.renderer.$gutterLayer.getRegion(e); + var gutterRegion = gutter.getRegion(e); if (gutterRegion) return; @@ -62,6 +64,98 @@ function GutterHandler(mouseHandler) { mouseHandler.captureMouse(e, "selectByLines"); return e.preventDefault(); }); + + + var tooltipTimeout, mouseEvent, tooltip, tooltipAnnotation; + function createTooltip() { + tooltip = dom.createElement("div"); + tooltip.className = "ace_gutter_tooltip"; + tooltip.style.maxWidth = "500px"; + tooltip.style.display = "none"; + editor.container.appendChild(tooltip); + } + + function showTooltip() { + if (!tooltip) { + createTooltip(); + } + var row = mouseEvent.getDocumentPosition().row; + var annotation = gutter.$annotations[row]; + if (!annotation) + return hideTooltip(); + + var maxRow = editor.session.getLength(); + if (row == maxRow) { + var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row; + var pos = mouseEvent.$pos; + if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column)) + return hideTooltip(); + } + + if (tooltipAnnotation == annotation) + return; + tooltipAnnotation = annotation.text.join("\n"); + + tooltip.style.display = "block"; + tooltip.innerHTML = tooltipAnnotation; + editor.on("mousewheel", hideTooltip); + + moveTooltip(mouseEvent); + } + + function hideTooltip() { + if (tooltipTimeout) + tooltipTimeout = clearTimeout(tooltipTimeout); + if (tooltipAnnotation) { + tooltip.style.display = "none"; + tooltipAnnotation = null; + editor.removeEventListener("mousewheel", hideTooltip); + } + } + + function moveTooltip(e) { + var rect = editor.renderer.$gutter.getBoundingClientRect(); + tooltip.style.left = e.x - rect.left + 15 + "px"; + if (e.y + 3 * editor.renderer.lineHeight + 15 < rect.bottom) { + tooltip.style.bottom = ""; + tooltip.style.top = e.y - rect.top + 15 + "px"; + } else { + tooltip.style.top = ""; + tooltip.style.bottom = rect.bottom - e.y + 5 + "px"; + } + } + + mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) { + var target = e.domEvent.target || e.domEvent.srcElement; + if (dom.hasCssClass(target, "ace_fold-widget")) + return hideTooltip(); + + if (tooltipAnnotation) + moveTooltip(e); + + mouseEvent = e; + if (tooltipTimeout) + return; + tooltipTimeout = setTimeout(function() { + tooltipTimeout = null; + if (mouseEvent) + showTooltip(); + else + hideTooltip(); + }, 50); + }); + + event.addListener(editor.renderer.$gutter, "mouseout", function(e) { + mouseEvent = null; + if (!tooltipAnnotation || tooltipTimeout) + return; + + tooltipTimeout = setTimeout(function() { + tooltipTimeout = null; + hideTooltip(); + }, 50); + }); + } exports.GutterHandler = GutterHandler; diff --git a/lib/ace/mouse/mouse_handler.js b/lib/ace/mouse/mouse_handler.js index b8e992a3..bf708ee2 100644 --- a/lib/ace/mouse/mouse_handler.js +++ b/lib/ace/mouse/mouse_handler.js @@ -69,7 +69,7 @@ var MouseHandler = function(editor) { event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown")); event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick")); event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick")); - event.addListener(gutterEl, "mousemove", this.onMouseMove.bind(this, "gutter")); + event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove")); }; (function() { From 97e40eb58050f7ee9dee435f9e2cf7fc0956a108 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 8 Aug 2012 19:54:18 +0400 Subject: [PATCH 4/4] do not break old breakpoint api --- lib/ace/edit_session.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 886d3719..6559df98 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -533,8 +533,11 @@ var EditSession = function(text, mode) { * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event. * **/ - this.setBreakpoints = function(breakpoints) { - this.$breakpoints = breakpoints; + this.setBreakpoints = function(rows) { + this.$breakpoints = []; + for (var i=0; i