From fcc37e2068d90f3b1ce4eec10f32ad26998b9440 Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Fri, 25 Feb 2011 16:53:02 +0100 Subject: [PATCH 1/7] Avoid polling every 500ms for font size changes --- lib/ace/layer/text.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 953d4411..a79a4acf 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -77,13 +77,13 @@ var Text = function(parentEl) { this.$pollSizeChanges = function() { var self = this; - setInterval(function() { + //setInterval(function() { var size = self.$measureSizes(); if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { self.$characterSize = size; self._dispatchEvent("changeCharaterSize", {data: size}); } - }, 500); + //}, 500); }; this.$fontStyles = { From c50a7651767ebd5afe1f3e2b5b9c3b4751ade431 Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Fri, 25 Feb 2011 17:03:00 +0100 Subject: [PATCH 2/7] Avoid polling for font size changes every 500ms --- lib/ace/layer/text.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 953d4411..0fd04272 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -1,4 +1,5 @@ /* vim:ts=4:sts=4:sw=4: + * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -77,13 +78,13 @@ var Text = function(parentEl) { this.$pollSizeChanges = function() { var self = this; - setInterval(function() { + //setInterval(function() { var size = self.$measureSizes(); if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { self.$characterSize = size; self._dispatchEvent("changeCharaterSize", {data: size}); } - }, 500); + //}, 500); }; this.$fontStyles = { From ff7c1b5182d99d562aaadd124404eb3c2a8ad352 Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Sun, 27 Feb 2011 12:44:43 +0100 Subject: [PATCH 3/7] |pollSizeChanges| is called only on resize, not every 500ms --- lib/ace/editor.js | 55 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index b204a8f8..d85d95e8 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -63,7 +63,7 @@ var Editor =function(renderer, session) { this.textInput = new TextInput(renderer.getTextAreaContainer(), this); this.keyBinding = new KeyBinding(this); - + // TODO detect touch event support if (useragent.isIPad) { //this.$mouseHandler = new TouchHandler(this); @@ -158,16 +158,16 @@ var Editor =function(renderer, session) { this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this); this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker); - + this.$onChangeBackMarker = this.onChangeBackMarker.bind(this); this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker); - + this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this); this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint); this.$onChangeAnnotation = this.onChangeAnnotation.bind(this); this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation); - + this.$onCursorChange = this.onCursorChange.bind(this); this.session.addEventListener("changeOverwrite", this.$onCursorChange); @@ -206,6 +206,7 @@ var Editor =function(renderer, session) { this.resize = function() { this.renderer.onResize(); + this.renderer.$textLayer.$pollSizeChanges(); }; this.setTheme = function(theme) { @@ -308,7 +309,7 @@ var Editor =function(renderer, session) { this.$updateHighlightActiveLine = function() { var session = this.getSession(); - + if (session.$highlightLineMarker) { session.removeMarker(session.$highlightLineMarker); } @@ -323,7 +324,7 @@ var Editor =function(renderer, session) { this.onSelectionChange = function(e) { var session = this.getSession(); - + if (session.$selectionMarker) { session.removeMarker(session.$selectionMarker); } @@ -344,11 +345,11 @@ var Editor =function(renderer, session) { this.onChangeFrontMarker = function() { this.renderer.updateFrontMarkers(); }; - + this.onChangeBackMarker = function() { this.renderer.updateBackMarkers(); }; - + this.onChangeBreakpoint = function() { this.renderer.setBreakpoints(this.session.getBreakpoints()); }; @@ -429,18 +430,18 @@ var Editor =function(renderer, session) { var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString()); var end = this.session.insert(cursor, text); - + var lineState = this.bgTokenizer.getState(cursor.row); // TODO disabled multiline auto indent // possibly doing the indent before inserting the text // if (cursor.row !== end.row) { if (this.session.getDocument().isNewLine(text)) { this.moveCursorTo(cursor.row+1, 0); - + var size = this.session.getTabSize(), minIndent = Number.MAX_VALUE; - + for (var row = cursor.row + 1; row <= end.row; ++row) { var indent = 0; @@ -472,7 +473,7 @@ var Editor =function(renderer, session) { if (shouldOutdent) { this.mode.autoOutdent(lineState, this.session, cursor.row); } - }; + }; } this.onTextInput = function(text) { @@ -484,7 +485,7 @@ var Editor =function(renderer, session) { }; this.setOverwrite = function(overwrite) { - this.session.setOverwrite(); + this.session.setOverwrite(); }; this.getOverwrite = function() { @@ -601,7 +602,7 @@ var Editor =function(renderer, session) { this.session.remove(this.getSelectionRange()); this.clearSelection(); }; - + this.removeWordRight = function() { if (this.$readOnly) return; @@ -612,7 +613,7 @@ var Editor =function(renderer, session) { this.session.remove(this.getSelectionRange()); this.clearSelection(); }; - + this.removeWordLeft = function() { if (this.$readOnly) return; @@ -623,7 +624,7 @@ var Editor =function(renderer, session) { this.session.remove(this.getSelectionRange()); this.clearSelection(); }; - + this.removeToLineStart = function() { if (this.$readOnly) return; @@ -634,7 +635,7 @@ var Editor =function(renderer, session) { this.session.remove(this.getSelectionRange()); this.clearSelection(); }; - + this.removeToLineEnd = function() { if (this.$readOnly) return; @@ -649,30 +650,30 @@ var Editor =function(renderer, session) { this.splitLine = function() { if (this.$readOnly) return; - + if (!this.selection.isEmpty()) { this.session.remove(this.getSelectionRange()); this.clearSelection(); } - + var cursor = this.getCursorPosition(); this.insert("\n"); this.moveCursorToPosition(cursor); }; - + this.transposeLetters = function() { if (this.$readOnly) return; - + if (!this.selection.isEmpty()) { return; } - + var cursor = this.getCursorPosition(); var column = cursor.column; if (column == 0) return; - + var line = this.session.getLine(cursor.row); if (column < line.length) { var swap = line.charAt(column) + line.charAt(column-1); @@ -684,7 +685,7 @@ var Editor =function(renderer, session) { } this.session.replace(range, swap); }; - + this.indent = function() { if (this.$readOnly) return; @@ -897,7 +898,7 @@ var Editor =function(renderer, session) { this.scrollToLine = function(line, center) { this.renderer.scrollToLine(line, center); }; - + this.centerSelection = function() { var range = this.getSelectionRange(); var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2); @@ -922,7 +923,7 @@ var Editor =function(renderer, session) { this.selection.selectAll(); this.$blockScrolling -= 1; }; - + this.clearSelection = function() { this.selection.clearSelection(); }; @@ -1049,7 +1050,7 @@ var Editor =function(renderer, session) { this.$blockScrolling += 1; for (var i = ranges.length - 1; i >= 0; --i) this.$tryReplace(ranges[i], replacement); - + this.selection.setSelectionRange(selection); this.$blockScrolling -= 1; }, From 0ca1e2cf2dde775443f4f5b16ceb0b6afe5cff77 Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Sun, 27 Feb 2011 19:25:15 +0100 Subject: [PATCH 4/7] Fixed cursor positioning --- lib/ace/keyboard/textinput.js | 9 +++++++- lib/ace/layer/cursor.js | 10 +++++---- lib/ace/virtual_renderer.js | 42 ++++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index 2ecb1b6e..b793a280 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -46,6 +46,13 @@ var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); text.style.left = "-10000px"; + // We have too many moving parts in the iPad, so we set the text + // positioning to absolute to be able to calculate the precise position for + // cursor. Otherwise the cursor position would be relative to the screen + // coordinates (position: fixed). + if (useragent.isIPad) + text.style.position = "absolute"; + parentNode.appendChild(text); var PLACEHOLDER = String.fromCharCode(0); @@ -164,7 +171,7 @@ var TextInput = function(parentNode, host) { }; if (useragent.isIE) { - event.addListener(text, "beforecopy", function(e) { + event.addListener(text, "beforecopy", function(e) { var copyText = host.getCopyText(); if(copyText) clipboardData.setData("Text", copyText); diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index a1cd4698..d62346c9 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -68,7 +68,9 @@ var Cursor = function(parentEl) { this.showCursor = function() { this.isVisible = true; - this.element.appendChild(this.cursor); + if (!useragent.isIPad) + this.element.appendChild(this.cursor); + var cursor = this.cursor; cursor.style.visibility = "visible"; @@ -120,16 +122,16 @@ var Cursor = function(parentEl) { this.cursor.style.width = config.characterWidth + "px"; this.cursor.style.height = config.lineHeight + "px"; - if (this.isVisible) { + if (this.isVisible && !useragent.isIPad) { this.element.appendChild(this.cursor); } - + if (this.session.getOverwrite()) { dom.addCssClass(this.cursor, "ace_overwrite"); } else { dom.removeCssClass(this.cursor, "ace_overwrite"); } - + this.restartTimer(); }; diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 0027d18c..385348d8 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -277,7 +277,7 @@ var VirtualRenderer = function(container, theme) { this.getPrintMarginColumn = function() { return this.$printMarginColumn; }; - + this.getShowGutter = function(){ return this.showGutter; } @@ -319,23 +319,39 @@ var VirtualRenderer = function(container, theme) { }; this.getTextAreaContainer = function() { - return this.container; + // Let's make it play nice wit iPad. Otherwise the default padding of + // the container will make the cursor shift to the left. + return useragent.isIPad ? this.content : this.container; + }; this.moveTextAreaToCursor = function(textarea) { - // in IE the native cursor always shines through - if (useragent.isIE) + if (!this.layerConfig) return; - var pos = this.$cursorLayer.getPixelPosition(); - if (!pos) - return; + var pos, left, top; + if (useragent.isIPad) { + pos = this.$cursorLayer.getPixelPosition(true); + if (!pos) + return; - var bounds = this.content.getBoundingClientRect(); - var offset = (this.layerConfig && this.layerConfig.offset) || 0; + left = pos.left + this.$padding - 3; + top = pos.top; + } else { + pos = this.$cursorLayer.getPixelPosition(); + if (!pos) + return; - textarea.style.left = (bounds.left + pos.left + this.$padding) + "px"; - textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px"; + var bounds = this.content.getBoundingClientRect(); + var offset = this.layerConfig.offset; + + left = bounds.left + pos.left + this.$padding; + top = bounds.top + pos.top - this.scrollTop + offset; + } + + textarea.style.left = left + "px"; + textarea.style.top = top + "px"; + textarea.style.lineHeight = this.layerConfig.lineHeight + "px"; }; this.getFirstVisibleRow = function() { @@ -592,7 +608,7 @@ var VirtualRenderer = function(container, theme) { // the editor is not visible if (this.$size.scrollerHeight === 0) return; - + var pos = this.$cursorLayer.getPixelPosition(); var left = pos.left + this.$padding; @@ -646,7 +662,7 @@ var VirtualRenderer = function(container, theme) { for (var l = 1; l < line; l++) { offset += this.session.getRowHeight(lineHeight, l-1); } - + if (center) { offset -= this.$size.scrollerHeight / 2; } From 1d05dc78beed25e81ec912ab0ba4115be382412a Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Sun, 27 Feb 2011 19:38:22 +0100 Subject: [PATCH 5/7] Forgot to include a require for pilot/useragent --- lib/ace/layer/cursor.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index d62346c9..4bdf012a 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -40,6 +40,7 @@ define(function(require, exports, module) { var dom = require("pilot/dom"); +var useragent = require("pilot/useragent"); var Cursor = function(parentEl) { this.element = dom.createElement("div"); From fbdfaaf0fce2dbb1803830724173e24f8a24bde3 Mon Sep 17 00:00:00 2001 From: Sergi Mansilla Date: Mon, 28 Feb 2011 12:33:12 +0100 Subject: [PATCH 6/7] Stop trying to use workers and word highlighting. --- lib/ace/edit_session.js | 22 +++++++++++----------- lib/ace/editor.js | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 6c33c449..5a886b63 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -344,20 +344,20 @@ var EditSession = function(text, mode) { return this.doc.getNewLineMode(); }; - this.$useWorker = true; + this.$useWorker = false; this.setUseWorker = function(useWorker) { if (this.$useWorker == useWorker) return; - + if (useWorker && !this.$worker && window.Worker) this.$worker = mode.createWorker(this); - + if (!useWorker && this.$worker) { this.$worker.terminate(); this.$worker = null; } }; - + this.getUseWorker = function() { return this.$useWorker; }; @@ -601,7 +601,7 @@ var EditSession = function(text, mode) { var actions = [{}]; - + // collapse insert and remove operations for (var i=0; i Date: Mon, 28 Feb 2011 14:24:38 +0100 Subject: [PATCH 7/7] Added Droid Sans Mono as the first font to use by mobile Ace --- lib/ace/css/editor.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index 06bc87b9..6d94ba83 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -2,14 +2,14 @@ position: absolute; overflow: hidden; - font-family: "Menlo", "Monaco", "Courier New", monospace; - font-size: 12px; + font-family: "Droid Sans Mono", "Monaco", "Courier New", monospace; + font-size: 16px; } .ace_scroller { position: absolute; overflow-x: scroll; - overflow-y: hidden; + overflow-y: hidden; } .ace_content { @@ -90,14 +90,14 @@ .ace_layer { z-index: 1; position: absolute; - overflow: hidden; + overflow: hidden; white-space: nowrap; height: 100%; width: 100%; } .ace_text-layer { - font-family: Monaco, "Courier New", monospace; + font-family: "Droid Sans Mono", Monaco, "Courier New", monospace; color: black; }