Bug 783846 - Part 1 - Allow paste within contentEditable elements. r=wesj

This commit is contained in:
Mike Taylor 2015-02-03 22:04:00 +01:00
Родитель 1455986744
Коммит b180e7973f
2 изменённых файлов: 60 добавлений и 7 удалений

Просмотреть файл

@ -9,6 +9,7 @@
const DIV_POINT_TEXT = "Under"; const DIV_POINT_TEXT = "Under";
const INPUT_TEXT = "Text for select all in an <input>"; const INPUT_TEXT = "Text for select all in an <input>";
const TEXTAREA_TEXT = "Text for select all in a <textarea>"; const TEXTAREA_TEXT = "Text for select all in a <textarea>";
const PASTE_TEXT = "Text for testing paste";
const READONLY_INPUT_TEXT = "readOnly text"; const READONLY_INPUT_TEXT = "readOnly text";
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
@ -28,6 +29,7 @@ function startTests() {
then(testReadonlyInput). then(testReadonlyInput).
then(testCloseSelection). then(testCloseSelection).
then(testStartSelectionFail). then(testStartSelectionFail).
then(testPaste).
then(testAttachCaret). then(testAttachCaret).
then(testAttachCaretFail). then(testAttachCaretFail).
@ -348,6 +350,44 @@ function testAttachCaretFail() {
} }
/*
* Tests related to pasting text inside editable elements:
* * input
* * textarea
* * contentEditable elements
*/
function testPaste() {
var sh = getSelectionHandler();
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
clipboard.copyString(PASTE_TEXT, document);
// Add a contentEditable element to the document.
var div = document.createElement("div");
div.contentEditable = true;
div.dataset.editable = true;
document.body.appendChild(div);
var elements = document.querySelectorAll("div, input, textarea");
var promises = [];
for (var i = 0; i < elements.length; i++) {
sh.startSelection(elements[i]);
sh.actions.PASTE.action(elements[i]);
if (elements[i].dataset.editable) {
promises.push(is(getTextValue(elements[i]), PASTE_TEXT, "Pasted correctly"));
promises.push(ok(sh.isElementEditableText(elements[i]), "Element is editable"));
} else {
promises.push(isnot(getTextValue(elements[i]), PASTE_TEXT, "Paste failed correctly"));
promises.push(ok(!sh.isElementEditableText(elements[i]), "Element is not editable"));
}
}
document.body.removeChild(div);
div = null;
return Promise.all(promises);
}
/* ================================================================================= /* =================================================================================
* *
* After finish of all selection tests, wrap up and go home. * After finish of all selection tests, wrap up and go home.
@ -373,6 +413,10 @@ function getSelectionHandler() {
this._selectionHandler; this._selectionHandler;
} }
function getTextValue(aElement) {
return aElement.value || aElement.textContent;
}
function ok(one, msg) { function ok(one, msg) {
return Messaging.sendRequestForResult({ return Messaging.sendRequestForResult({
type: "Robocop:testSelectionHandler", type: "Robocop:testSelectionHandler",
@ -389,6 +433,14 @@ function is(one, two, msg) {
}); });
} }
function isnot(one, two, msg) {
return Messaging.sendRequestForResult({
type: "Robocop:testSelectionHandler",
result: one !== two,
msg: msg + " : " + one + " !== " + two
});
}
/* ================================================================================= /* =================================================================================
* *
* Page definition for all tests. * Page definition for all tests.
@ -424,9 +476,9 @@ function is(one, two, msg) {
nunc vel, fringilla turpis. Nulla lacinia, leo ut egestas hendrerit, risus nunc vel, fringilla turpis. Nulla lacinia, leo ut egestas hendrerit, risus
ligula interdum enim, vel varius libero sem ut ligula.</div><br> ligula interdum enim, vel varius libero sem ut ligula.</div><br>
<input id="inputNode" type="text"><br> <input data-editable="true" id="inputNode" type="text"><br>
<textarea id="textareaNode"></textarea><br> <textarea data-editable="true" id="textareaNode"></textarea><br>
<input id="readOnlyTextInput" type="text" readonly><br> <input id="readOnlyTextInput" type="text" readonly><br>

Просмотреть файл

@ -671,10 +671,10 @@ var SelectionHandler = {
id: "paste_action", id: "paste_action",
icon: "drawable://ab_paste", icon: "drawable://ab_paste",
action: function(aElement) { action: function(aElement) {
if (aElement && (aElement instanceof Ci.nsIDOMNSEditableElement)) { if (aElement) {
let target = aElement.QueryInterface(Ci.nsIDOMNSEditableElement); let editor = SelectionHandler._getEditor();
target.editor.paste(Ci.nsIClipboard.kGlobalClipboard); aElement.focus();
target.focus(); editor.paste(Ci.nsIClipboard.kGlobalClipboard);
SelectionHandler._closeSelection(); SelectionHandler._closeSelection();
UITelemetry.addEvent("action.1", "actionbar", null, "paste"); UITelemetry.addEvent("action.1", "actionbar", null, "paste");
} }
@ -850,7 +850,8 @@ var SelectionHandler = {
isElementEditableText: function (aElement) { isElementEditableText: function (aElement) {
return (((aElement instanceof HTMLInputElement && aElement.mozIsTextField(false)) || return (((aElement instanceof HTMLInputElement && aElement.mozIsTextField(false)) ||
(aElement instanceof HTMLTextAreaElement)) && !aElement.readOnly); (aElement instanceof HTMLTextAreaElement)) && !aElement.readOnly) ||
aElement.contentEditable == "true";
}, },
_isNonTextInputElement: function(aElement) { _isNonTextInputElement: function(aElement) {