move text area to cursor only when cursor is moved

This commit is contained in:
nightwing 2012-04-02 23:55:15 +04:00
commit 2f6a6ce7e0
5 changed files with 30 additions and 29 deletions

View file

@ -94,8 +94,8 @@
.ace_editor textarea { .ace_editor textarea {
position: fixed; position: fixed;
z-index: 0; z-index: 0;
width: 10px; width: 0.5em;
height: 30px; height: 1em;
opacity: 0; opacity: 0;
background: transparent; background: transparent;
appearance: none; appearance: none;

View file

@ -80,6 +80,7 @@ var Editor = function(renderer, session) {
this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
this.textInput = new TextInput(renderer.getTextAreaContainer(), this); this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
this.renderer.textarea = this.textInput.getElement();
this.keyBinding = new KeyBinding(this); this.keyBinding = new KeyBinding(this);
// TODO detect touch event support // TODO detect touch event support
@ -385,11 +386,7 @@ var Editor = function(renderer, session) {
this.$cursorChange = function() { this.$cursorChange = function() {
this.renderer.updateCursor(); this.renderer.updateCursor();
};
// move text input over the cursor
// this is required for iOS and IME
this.renderer.moveTextAreaToCursor(this.textInput.getElement());
}
/** /**
* Editor@onDocumentChange(e) * Editor@onDocumentChange(e)

View file

@ -50,6 +50,8 @@ var TextInput = function(parentNode, host) {
if (useragent.isTouchPad) if (useragent.isTouchPad)
text.setAttribute("x-palm-disable-auto-cap", true); text.setAttribute("x-palm-disable-auto-cap", true);
text.setAttribute("wrap", "off");
text.style.left = "-10000px"; text.style.left = "-10000px";
text.style.position = "fixed"; text.style.position = "fixed";
parentNode.insertBefore(text, parentNode.firstChild); parentNode.insertBefore(text, parentNode.firstChild);

View file

@ -175,6 +175,9 @@ var Cursor = function(parentEl) {
if (overwrite != this.overwrite) if (overwrite != this.overwrite)
this.$setOverite(overwrite); this.$setOverite(overwrite);
// cache for textarea and gutter highlight
this.$pixelPos = pixelPos;
this.restartTimer(); this.restartTimer();
}; };

View file

@ -83,6 +83,9 @@ var VirtualRenderer = function(container, theme) {
// // Imports CSS once per DOM document ('ace_editor' serves as an identifier). // // Imports CSS once per DOM document ('ace_editor' serves as an identifier).
// dom.importCssString(editorCss, "ace_editor", container.ownerDocument); // dom.importCssString(editorCss, "ace_editor", container.ownerDocument);
// in IE <= 9 the native cursor always shines through
this.$keepTextAreaAtCursor = !useragent.isIE;
dom.addCssClass(container, "ace_editor"); dom.addCssClass(container, "ace_editor");
this.setTheme(theme); this.setTheme(theme);
@ -496,30 +499,22 @@ var VirtualRenderer = function(container, theme) {
return this.container; return this.container;
}; };
/** // move text input over the cursor
* VirtualRenderer.moveTextAreaToCursor(textarea) -> Void // this is required for iOS and IME
* - textarea (DOMElement): A text area to work with this.$moveTextAreaToCursor = function() {
* if (!this.$keepTextAreaAtCursor)
* Changes the position of `textarea` to where the cursor is pointing.
**/
this.moveTextAreaToCursor = function(textarea) {
// in IE the native cursor always shines through
// this persists in IE9
if (useragent.isIE)
return; return;
if (this.layerConfig.lastRow === 0) var pos = this.$cursorLayer.$pixelPos;
pos.top -= this.layerConfig.offset;
if (pos.top < 0 || pos.top > this.layerConfig.height)
return; return;
var pos = this.$cursorLayer.getPixelPosition(); pos.left += (this.showGutter ? this.$gutterLayer.gutterWidth : 0) - this.scrollLeft;
if (!pos) var bounds = this.container.getBoundingClientRect();
return; this.textarea.style.left = (bounds.left + pos.left) + "px";
this.textarea.style.top = (bounds.top + pos.top) + "px";
var bounds = this.content.getBoundingClientRect();
var offset = this.layerConfig.offset;
textarea.style.left = (bounds.left + pos.left) + "px";
textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px";
}; };
/** /**
@ -640,6 +635,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig); this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig); this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
return; return;
} }
@ -656,6 +652,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig); this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig); this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
return; return;
} }
@ -675,8 +672,10 @@ var VirtualRenderer = function(container, theme) {
this.$gutterLayer.update(this.layerConfig); this.$gutterLayer.update(this.layerConfig);
} }
if (changes & this.CHANGE_CURSOR) if (changes & this.CHANGE_CURSOR) {
this.$cursorLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
}
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
this.$markerFront.update(this.layerConfig); this.$markerFront.update(this.layerConfig);