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 {
position: fixed;
z-index: 0;
width: 10px;
height: 30px;
width: 0.5em;
height: 1em;
opacity: 0;
background: transparent;
appearance: none;

View file

@ -80,6 +80,7 @@ var Editor = function(renderer, session) {
this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
this.renderer.textarea = this.textInput.getElement();
this.keyBinding = new KeyBinding(this);
// TODO detect touch event support
@ -385,11 +386,7 @@ var Editor = function(renderer, session) {
this.$cursorChange = function() {
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)

View file

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

View file

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

View file

@ -82,6 +82,9 @@ var VirtualRenderer = function(container, theme) {
// TODO: this breaks rendering in Cloud9 with multiple ace instances
// // Imports CSS once per DOM document ('ace_editor' serves as an identifier).
// 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");
@ -496,30 +499,22 @@ var VirtualRenderer = function(container, theme) {
return this.container;
};
/**
* VirtualRenderer.moveTextAreaToCursor(textarea) -> Void
* - textarea (DOMElement): A text area to work with
*
* 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)
// move text input over the cursor
// this is required for iOS and IME
this.$moveTextAreaToCursor = function() {
if (!this.$keepTextAreaAtCursor)
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;
var pos = this.$cursorLayer.getPixelPosition();
if (!pos)
return;
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";
pos.left += (this.showGutter ? this.$gutterLayer.gutterWidth : 0) - this.scrollLeft;
var bounds = this.container.getBoundingClientRect();
this.textarea.style.left = (bounds.left + pos.left) + "px";
this.textarea.style.top = (bounds.top + pos.top) + "px";
};
/**
@ -640,6 +635,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
return;
}
@ -656,6 +652,7 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
return;
}
@ -675,8 +672,10 @@ var VirtualRenderer = function(container, theme) {
this.$gutterLayer.update(this.layerConfig);
}
if (changes & this.CHANGE_CURSOR)
if (changes & this.CHANGE_CURSOR) {
this.$cursorLayer.update(this.layerConfig);
this.$moveTextAreaToCursor();
}
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
this.$markerFront.update(this.layerConfig);