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 INPUT_TEXT = "Text for select all in an <input>";
const TEXTAREA_TEXT = "Text for select all in a <textarea>";
const PASTE_TEXT = "Text for testing paste";
const READONLY_INPUT_TEXT = "readOnly text";
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
@ -28,6 +29,7 @@ function startTests() {
then(testReadonlyInput).
then(testCloseSelection).
then(testStartSelectionFail).
then(testPaste).
then(testAttachCaret).
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.
@ -373,6 +413,10 @@ function getSelectionHandler() {
this._selectionHandler;
}
function getTextValue(aElement) {
return aElement.value || aElement.textContent;
}
function ok(one, msg) {
return Messaging.sendRequestForResult({
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.
@ -424,9 +476,9 @@ function is(one, two, msg) {
nunc vel, fringilla turpis. Nulla lacinia, leo ut egestas hendrerit, risus
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>

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

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