Bug 923514 - add plaintext paste (paste without formatting) item to page context menu for richtext / contenteditable inputs, r=bgrins,fluent-reviewers,flod
Differential Revision: https://phabricator.services.mozilla.com/D153457
This commit is contained in:
@@ -1097,6 +1097,8 @@ class ContextMenuChild extends JSWindowActorChild {
|
||||
context.onNumeric = (editFlags & lazy.SpellCheckHelper.NUMERIC) !== 0;
|
||||
context.onEditable = (editFlags & lazy.SpellCheckHelper.EDITABLE) !== 0;
|
||||
context.onPassword = (editFlags & lazy.SpellCheckHelper.PASSWORD) !== 0;
|
||||
context.isDesignMode =
|
||||
(editFlags & lazy.SpellCheckHelper.CONTENTEDITABLE) !== 0;
|
||||
context.passwordRevealed =
|
||||
context.onPassword && context.target.revealPassword;
|
||||
context.onSpellcheckable =
|
||||
|
||||
@@ -296,6 +296,9 @@
|
||||
<menuitem id="context-paste"
|
||||
data-l10n-id="text-action-paste"
|
||||
command="cmd_paste"/>
|
||||
<menuitem id="context-paste-no-formatting"
|
||||
data-l10n-id="text-action-paste-no-formatting"
|
||||
command="cmd_pasteNoFormatting"/>
|
||||
<menuitem id="context-delete"
|
||||
data-l10n-id="text-action-delete"
|
||||
command="cmd_delete"/>
|
||||
|
||||
@@ -934,6 +934,7 @@ class nsContextMenu {
|
||||
this.showItem("context-cut", this.onTextInput);
|
||||
this.showItem("context-copy", this.isContentSelected || this.onTextInput);
|
||||
this.showItem("context-paste", this.onTextInput);
|
||||
this.showItem("context-paste-no-formatting", this.isDesignMode);
|
||||
this.showItem("context-delete", this.onTextInput);
|
||||
this.showItem(
|
||||
"context-selectall",
|
||||
|
||||
@@ -18,6 +18,7 @@ https_first_disabled = true
|
||||
skip-if =
|
||||
os == 'win' && bits == 64 # Bug 1719856
|
||||
os == 'linux' && socketprocess_networking
|
||||
[browser_contextmenu_contenteditable.js]
|
||||
[browser_contextmenu_inspect.js]
|
||||
skip-if = os == 'linux' && socketprocess_networking
|
||||
[browser_contextmenu_keyword.js]
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let contextMenu;
|
||||
|
||||
const example_base =
|
||||
"http://example.com/browser/browser/base/content/test/contextMenu/";
|
||||
const chrome_base =
|
||||
"chrome://mochitests/content/browser/browser/base/content/test/contextMenu/";
|
||||
|
||||
/* import-globals-from contextmenu_common.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
chrome_base + "contextmenu_common.js",
|
||||
this
|
||||
);
|
||||
|
||||
async function openMenuAndPaste(browser, useFormatting) {
|
||||
const kElementToUse = "test-contenteditable-spellcheck-false";
|
||||
let oldText = await SpecialPowers.spawn(browser, [kElementToUse], elemID => {
|
||||
return content.document.getElementById(elemID).textContent;
|
||||
});
|
||||
|
||||
// Open context menu and paste
|
||||
await test_contextmenu(
|
||||
"#" + kElementToUse,
|
||||
[
|
||||
"context-undo",
|
||||
null, // whether we can undo changes mid-test.
|
||||
"context-redo",
|
||||
false,
|
||||
"---",
|
||||
null,
|
||||
"context-cut",
|
||||
false,
|
||||
"context-copy",
|
||||
false,
|
||||
"context-paste",
|
||||
true,
|
||||
"context-paste-no-formatting",
|
||||
true,
|
||||
"context-delete",
|
||||
false,
|
||||
"context-selectall",
|
||||
true,
|
||||
],
|
||||
{
|
||||
keepMenuOpen: true,
|
||||
}
|
||||
);
|
||||
let popupHidden = BrowserTestUtils.waitForPopupEvent(contextMenu, "hidden");
|
||||
let menuID = "context-paste" + (useFormatting ? "" : "-no-formatting");
|
||||
contextMenu.activateItem(document.getElementById(menuID));
|
||||
await popupHidden;
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[kElementToUse, oldText, useFormatting],
|
||||
(elemID, textToReset, expectStrong) => {
|
||||
let node = content.document.getElementById(elemID);
|
||||
Assert.stringContains(
|
||||
node.textContent,
|
||||
"Bold text",
|
||||
"Text should have been pasted"
|
||||
);
|
||||
if (expectStrong) {
|
||||
isnot(
|
||||
node.querySelector("strong"),
|
||||
null,
|
||||
"Should be markup in the text."
|
||||
);
|
||||
} else {
|
||||
is(
|
||||
node.querySelector("strong"),
|
||||
null,
|
||||
"Should be no markup in the text."
|
||||
);
|
||||
}
|
||||
node.textContent = textToReset;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
add_task(async function test_contenteditable() {
|
||||
// Put some HTML on the clipboard:
|
||||
const xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
||||
Ci.nsITransferable
|
||||
);
|
||||
xferable.init(null);
|
||||
xferable.addDataFlavor("text/html");
|
||||
xferable.setTransferData(
|
||||
"text/html",
|
||||
PlacesUtils.toISupportsString("<strong>Bold text</strong>")
|
||||
);
|
||||
xferable.addDataFlavor("text/unicode");
|
||||
xferable.setTransferData(
|
||||
"text/unicode",
|
||||
PlacesUtils.toISupportsString("Bold text")
|
||||
);
|
||||
Services.clipboard.setData(
|
||||
xferable,
|
||||
null,
|
||||
Services.clipboard.kGlobalClipboard
|
||||
);
|
||||
|
||||
let url = example_base + "subtst_contextmenu.html";
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser,
|
||||
url,
|
||||
},
|
||||
async function(browser) {
|
||||
await openMenuAndPaste(browser, false);
|
||||
await openMenuAndPaste(browser, true);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -15,11 +15,10 @@ function goUpdateGlobalEditMenuItems(force) {
|
||||
return;
|
||||
}
|
||||
|
||||
goUpdateCommand("cmd_undo");
|
||||
goUpdateCommand("cmd_redo");
|
||||
goUpdateUndoEditMenuItems();
|
||||
goUpdateCommand("cmd_cut");
|
||||
goUpdateCommand("cmd_copy");
|
||||
goUpdateCommand("cmd_paste");
|
||||
goUpdatePasteMenuItems();
|
||||
goUpdateCommand("cmd_selectAll");
|
||||
goUpdateCommand("cmd_delete");
|
||||
goUpdateCommand("cmd_switchTextDirection");
|
||||
@@ -34,6 +33,7 @@ function goUpdateUndoEditMenuItems() {
|
||||
// update menu items that depend on clipboard contents
|
||||
function goUpdatePasteMenuItems() {
|
||||
goUpdateCommand("cmd_paste");
|
||||
goUpdateCommand("cmd_pasteNoFormatting");
|
||||
}
|
||||
|
||||
// Inject the commandset here instead of relying on preprocessor to share this across documents.
|
||||
@@ -52,6 +52,7 @@ window.addEventListener(
|
||||
<command id="cmd_cut" internal="true" />
|
||||
<command id="cmd_copy" internal="true" />
|
||||
<command id="cmd_paste" internal="true" />
|
||||
<command id="cmd_pasteNoFormatting" internal="true" />
|
||||
<command id="cmd_delete" />
|
||||
<command id="cmd_selectAll" internal="true" />
|
||||
<command id="cmd_switchTextDirection" />
|
||||
|
||||
@@ -34,6 +34,10 @@ text-action-paste =
|
||||
.label = Paste
|
||||
.accesskey = P
|
||||
|
||||
text-action-paste-no-formatting =
|
||||
.label = Paste Without Formatting
|
||||
.accesskey = m
|
||||
|
||||
text-action-paste-shortcut =
|
||||
.key = V
|
||||
|
||||
|
||||
Reference in New Issue
Block a user