Merge branch 'textinput' into master

This commit is contained in:
nightwing 2012-10-26 19:34:47 +04:00
commit 8d9f0e28eb
2 changed files with 192 additions and 153 deletions

View file

@ -656,6 +656,11 @@ var Editor = function(renderer, session) {
this.insert(text); this.insert(text);
}; };
this.execCommand = function(command, args) {
this.commands.exec(command, this, args);
};
/** /**
* Editor.insert(text) * Editor.insert(text)
* - text (String): The new text to add * - text (String): The new text to add
@ -2126,4 +2131,4 @@ var Editor = function(renderer, session) {
exports.Editor = Editor; exports.Editor = Editor;
}); });

View file

@ -48,75 +48,98 @@ var TextInput = function(parentNode, host) {
text.setAttribute("x-palm-disable-auto-cap", true); text.setAttribute("x-palm-disable-auto-cap", true);
text.wrap = "off"; text.wrap = "off";
text.autocorrect = "off";
text.autocapitalize = "off";
text.spellcheck = false; text.spellcheck = false;
text.style.top = "-2em"; text.style.top = "-2em";
parentNode.insertBefore(text, parentNode.firstChild); parentNode.insertBefore(text, parentNode.firstChild);
var PLACEHOLDER = useragent.isIE ? "\x01" : "\x00"; var PLACEHOLDER = useragent.isIE || useragent.isOpera ? "\x01\x01" : "\x00\x00";
reset(true);
resetValue();
if (isFocused()) if (isFocused())
host.onFocus(); host.onFocus();
var inCompostion = false; // Somehow fixes problem with firing onpropertychange on first typed char
if (useragent.isOldIE) {
resetSelection();
resetValue();
setTimeout(resetSelection);
}
var cut = false
var copied = false; var copied = false;
var pasted = false; var pasted = false;
var inCompostion = false;
var isSelectionEmpty = true;
var tempStyle = ''; var tempStyle = '';
function reset(full) { function resetValue() {
try { text.value = PLACEHOLDER;
if (full) { //http://code.google.com/p/chromium/issues/detail?id=76516
if (useragent.isWebKit)
setTimeout(function(){
text.value = PLACEHOLDER; text.value = PLACEHOLDER;
text.selectionStart = 0; resetSelection();
text.selectionEnd = 1; });
} else
text.select();
} catch (e) {}
}
function sendText(valueToSend) {
if (!copied) {
var value = valueToSend || text.value;
if (value) {
if (value.length > 1) {
if (value.charAt(0) == PLACEHOLDER)
value = value.substr(1);
else if (value.charAt(value.length - 1) == PLACEHOLDER)
value = value.slice(0, -1);
}
if (value && value != PLACEHOLDER) {
if (pasted)
host.onPaste(value);
else
host.onTextInput(value);
}
}
}
copied = false;
pasted = false;
// Safari doesn't fire copy events if no text is selected
reset(true);
}
var onTextInput = function(e) {
if (!inCompostion)
sendText(e.data);
setTimeout(function () {
if (!inCompostion)
reset(true);
}, 0);
}; };
var onPropertyChange = function(e) { function resetSelection() {
setTimeout(function() { var selectionStart = isSelectionEmpty ? 2 : 1;
if (!inCompostion) var selectionEnd = 2;
if(text.value != "") {
sendText(); if (text.setSelectionRange) {
} text.setSelectionRange(selectionStart, selectionEnd);
}, 0); }
// IE8 does not support setSelectionRange
else if (text.createTextRange) {
var range = text.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
};
var onSelect = function(e) {
if (cut) {
cut = false;
return;
}
if (copied) {
copied = false;
return;
}
if (text.selectionStart === 0 && text.selectionEnd === text.value.length) {
host.selectAll();
resetSelection();
}
};
var onInput = function(e) {
if (inCompostion)
return;
if (pasted) {
var data = text.value;
resetValue();
if (data)
host.onPaste(data);
pasted = false;
return;
}
var data = text.value.substring(isSelectionEmpty ? 2 : 1);
resetValue();
if (data)
host.onTextInput(data);
else
host.execCommand("del", {source: "ace"});
}; };
var onCompositionStart = function(e) { var onCompositionStart = function(e) {
@ -135,37 +158,111 @@ var TextInput = function(parentNode, host) {
host.onCompositionEnd(); host.onCompositionEnd();
}; };
var onCopy = function(e) { var onCut = function(e) {
copied = true; var data = host.getCopyText();
var copyText = host.getCopyText(); if (!data) {
if(copyText) event.preventDefault(e);
text.value = copyText; return;
else }
e.preventDefault();
reset(); var clipboardData = e.clipboardData || window.clipboardData;
setTimeout(function () {
sendText(); if (clipboardData) {
}, 0); // Safari 5 has clipboardData object, but does not handle setData()
var supported = clipboardData.setData("Text", data);
if (supported) {
host.onCut();
event.preventDefault(e);
}
}
if (!supported) {
cut = true;
text.value = data;
text.select();
setTimeout(function(){ host.onCut() });
}
}; };
var onCut = function(e) { var onCopy = function(e) {
copied = true; var data = host.getCopyText();
var copyText = host.getCopyText(); if (!data) {
if(copyText) { event.preventDefault(e);
text.value = copyText; return;
host.onCut(); }
} else
e.preventDefault(); var clipboardData = e.clipboardData || window.clipboardData;
reset();
setTimeout(function () { if (clipboardData) {
sendText(); // Safari 5 has clipboardData object, but does not handle setData()
}, 0); var supported = clipboardData.setData("Text", data);
if (supported) {
host.onCopy();
event.preventDefault(e);
}
}
if (!supported) {
copied = true;
text.value = data;
text.select();
setTimeout(function(){ host.onCopy() });
}
};
var onPaste = function(e) {
var clipboardData = e.clipboardData || window.clipboardData;
if (clipboardData) {
var data = clipboardData.getData("Text");
if (data)
host.onPaste(data);
event.preventDefault(e);
}
else {
text.value = "";
pasted = true;
}
}; };
event.addCommandKeyListener(text, host.onCommandKey.bind(host)); event.addCommandKeyListener(text, host.onCommandKey.bind(host));
event.addListener(text, "input", onTextInput);
event.addListener(text, "select", onSelect);
event.addListener(text, "input", onInput);
event.addListener(text, "cut", onCut);
event.addListener(text, "copy", onCopy);
event.addListener(text, "paste", onPaste);
// Opera has no clipboard events
if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){
event.addListener(parentNode, "keydown", function(e) {
if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
return;
switch (e.keyCode) {
case 67:
onCopy(e);
break;
case 86:
onPaste(e);
break;
case 88:
onCut(e);
break;
}
});
}
if (useragent.isOldIE) { if (useragent.isOldIE) {
event.addListener(text, "propertychange", function(e){
if (text.value != "" && text.value != PLACEHOLDER)
onInput(e);
});
var keytable = { 13:1, 27:1 }; var keytable = { 13:1, 27:1 };
event.addListener(text, "keyup", function (e) { event.addListener(text, "keyup", function (e) {
if (inCompostion && (!text.value || keytable[e.keyCode])) if (inCompostion && (!text.value || keytable[e.keyCode]))
@ -175,70 +272,6 @@ var TextInput = function(parentNode, host) {
} }
inCompostion ? onCompositionUpdate() : onCompositionStart(); inCompostion ? onCompositionUpdate() : onCompositionStart();
}); });
event.addListener(text, "propertychange", function() {
if (text.value != PLACEHOLDER)
setTimeout(sendText, 0);
});
}
event.addListener(text, "paste", function(e) {
// Mark that the next input text comes from past.
pasted = true;
// Some browsers support the event.clipboardData API. Use this to get
// the pasted content which increases speed if pasting a lot of lines.
if (e.clipboardData && e.clipboardData.getData) {
sendText(e.clipboardData.getData("text/plain"));
e.preventDefault();
}
else {
// If a browser doesn't support any of the things above, use the regular
// method to detect the pasted input.
onPropertyChange();
}
});
if ("onbeforecopy" in text && typeof clipboardData !== "undefined") {
event.addListener(text, "beforecopy", function(e) {
if (tempStyle)
return; // without this text is copied when contextmenu is shown
var copyText = host.getCopyText();
if (copyText)
clipboardData.setData("Text", copyText);
else
e.preventDefault();
});
event.addListener(parentNode, "keydown", function(e) {
if (e.ctrlKey && e.keyCode == 88) {
var copyText = host.getCopyText();
if (copyText) {
clipboardData.setData("Text", copyText);
host.onCut();
}
event.preventDefault(e);
}
});
event.addListener(text, "cut", onCut); // for ie9 context menu
}
else if (useragent.isOpera && !("KeyboardEvent" in window)) {
event.addListener(parentNode, "keydown", function(e) {
if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
return;
if ((e.keyCode == 88 || e.keyCode == 67)) {
var copyText = host.getCopyText();
if (copyText) {
text.value = copyText;
text.select();
if (e.keyCode == 88)
host.onCut();
}
}
});
}
else {
event.addListener(text, "copy", onCopy);
event.addListener(text, "cut", onCut);
} }
event.addListener(text, "compositionstart", onCompositionStart); event.addListener(text, "compositionstart", onCompositionStart);
@ -256,11 +289,10 @@ var TextInput = function(parentNode, host) {
event.addListener(text, "focus", function() { event.addListener(text, "focus", function() {
host.onFocus(); host.onFocus();
reset(); resetSelection();
}); });
this.focus = function() { this.focus = function() {
reset();
text.focus(); text.focus();
}; };
@ -286,11 +318,6 @@ var TextInput = function(parentNode, host) {
(useragent.isIE ? "background:rgba(0, 0, 0, 0.03); opacity:0.1;" : "") + //"background:rgba(250, 0, 0, 0.3); opacity:1;" + (useragent.isIE ? "background:rgba(0, 0, 0, 0.03); opacity:0.1;" : "") + //"background:rgba(250, 0, 0, 0.3); opacity:1;" +
"left:" + (e.clientX - 2) + "px; top:" + (e.clientY - 2) + "px;"; "left:" + (e.clientX - 2) + "px; top:" + (e.clientY - 2) + "px;";
if (host.selection.isEmpty())
text.value = "";
else
reset(true);
if (e.type != "mousedown") if (e.type != "mousedown")
return; return;
@ -311,7 +338,6 @@ var TextInput = function(parentNode, host) {
text.style.cssText = tempStyle; text.style.cssText = tempStyle;
tempStyle = ''; tempStyle = '';
} }
sendText();
if (host.renderer.$keepTextAreaAtCursor == null) { if (host.renderer.$keepTextAreaAtCursor == null) {
host.renderer.$keepTextAreaAtCursor = true; host.renderer.$keepTextAreaAtCursor = true;
host.renderer.$moveTextAreaToCursor(); host.renderer.$moveTextAreaToCursor();
@ -324,8 +350,16 @@ var TextInput = function(parentNode, host) {
if (!useragent.isGecko) if (!useragent.isGecko)
event.addListener(text, "contextmenu", function(e) { event.addListener(text, "contextmenu", function(e) {
host.textInput.onContextMenu(e); host.textInput.onContextMenu(e);
onContextMenuClose() onContextMenuClose();
}); });
host.addEventListener('changeSelection', function(){
if (host.selection.isEmpty() != isSelectionEmpty) {
isSelectionEmpty = !isSelectionEmpty;
resetSelection();
}
});
}; };
exports.TextInput = TextInput; exports.TextInput = TextInput;