mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1058712, e10s, support for copy image command, r=ehsan,mconley
This commit is contained in:
parent
124eaea6e3
commit
3b7fec7dde
@ -123,6 +123,13 @@ let handleContentContextMenu = function (event) {
|
||||
InlineSpellCheckerContent.initContextMenu(event, editFlags, this);
|
||||
}
|
||||
|
||||
// Set the event target first as the copy image command needs it to
|
||||
// determine what was context-clicked on. Then, update the state of the
|
||||
// commands on the context menu.
|
||||
docShell.contentViewer.QueryInterface(Ci.nsIContentViewerEdit)
|
||||
.setCommandNode(event.target);
|
||||
event.target.ownerDocument.defaultView.updateCommands("contentcontextmenu");
|
||||
|
||||
let customMenuItems = PageMenuChild.build(event.target);
|
||||
let principal = doc.nodePrincipal;
|
||||
sendSyncMessage("contextmenu",
|
||||
|
@ -628,7 +628,9 @@ nsContextMenu.prototype = {
|
||||
this.inSyntheticDoc = ownerDoc.mozSyntheticDocument;
|
||||
// First, do checks for nodes that never have children.
|
||||
if (this.target.nodeType == Node.ELEMENT_NODE) {
|
||||
// See if the user clicked on an image.
|
||||
// See if the user clicked on an image. This check mirrors
|
||||
// nsDocumentViewer::GetInImage. Make sure to update both if this is
|
||||
// changed.
|
||||
if (this.target instanceof Ci.nsIImageLoadingContent &&
|
||||
this.target.currentURI) {
|
||||
this.onImage = true;
|
||||
|
@ -1,7 +1,9 @@
|
||||
// This test is used to check copy and paste in editable areas to ensure that non-text
|
||||
// types (html and images) are copied to and pasted from the clipboard properly.
|
||||
|
||||
let testPage = "<div id='main' contenteditable='true'>Test <b>Bold</b> After Text</div>";
|
||||
let testPage = "<body style='margin: 0'><img id='img' tabindex='1' src='http://example.org/browser/browser/base/content/test/general/moz.png'>" +
|
||||
" <div id='main' contenteditable='true'>Test <b>Bold</b> After Text</div>" +
|
||||
"</body>";
|
||||
|
||||
add_task(function*() {
|
||||
let tab = gBrowser.addTab();
|
||||
@ -12,7 +14,12 @@ add_task(function*() {
|
||||
yield promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
|
||||
yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
|
||||
|
||||
let results = yield ContentTask.spawn(browser, {}, function* () {
|
||||
const modifier = (content.navigator.platform.indexOf("Mac") >= 0) ?
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_META :
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_CONTROL;
|
||||
|
||||
let results = yield ContentTask.spawn(browser, { modifier: modifier },
|
||||
function* (arg) {
|
||||
var doc = content.document;
|
||||
var main = doc.getElementById("main");
|
||||
main.focus();
|
||||
@ -20,10 +27,7 @@ add_task(function*() {
|
||||
const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
|
||||
const modifier = (content.navigator.platform.indexOf("Mac") >= 0) ?
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_META :
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_CONTROL;
|
||||
|
||||
const modifier = arg.modifier;
|
||||
function sendKey(key)
|
||||
{
|
||||
if (utils.sendKeyEvent("keydown", key, 0, modifier)) {
|
||||
@ -46,7 +50,7 @@ add_task(function*() {
|
||||
selection.modify("extend", "right", "word");
|
||||
selection.modify("extend", "right", "word");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
yield new Promise((resolve, reject) => {
|
||||
addEventListener("copy", function copyEvent(event) {
|
||||
removeEventListener("copy", copyEvent, true);
|
||||
// The data is empty as the selection is copied during the event default phase.
|
||||
@ -59,7 +63,7 @@ add_task(function*() {
|
||||
|
||||
selection.modify("move", "right", "line");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
yield new Promise((resolve, reject) => {
|
||||
addEventListener("paste", function copyEvent(event) {
|
||||
removeEventListener("paste", copyEvent, true);
|
||||
let clipboardData = event.clipboardData;
|
||||
@ -80,7 +84,7 @@ add_task(function*() {
|
||||
selection.modify("extend", "left", "word");
|
||||
selection.modify("extend", "left", "character");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
yield new Promise((resolve, reject) => {
|
||||
addEventListener("cut", function copyEvent(event) {
|
||||
removeEventListener("cut", copyEvent, true);
|
||||
event.clipboardData.setData("text/plain", "Some text");
|
||||
@ -94,7 +98,7 @@ add_task(function*() {
|
||||
|
||||
selection.modify("move", "left", "line");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
yield new Promise((resolve, reject) => {
|
||||
addEventListener("paste", function copyEvent(event) {
|
||||
removeEventListener("paste", copyEvent, true);
|
||||
let clipboardData = event.clipboardData;
|
||||
@ -110,6 +114,7 @@ add_task(function*() {
|
||||
});
|
||||
|
||||
is(main.innerHTML, "<i>Italic</i> Test <b>Bold</b> After<b></b>", "Copy and paste html 2");
|
||||
|
||||
return results;
|
||||
});
|
||||
|
||||
@ -118,6 +123,61 @@ add_task(function*() {
|
||||
ok(results[t].startsWith("PASSED"), results[t]);
|
||||
}
|
||||
|
||||
// Next, check that the Copy Image command works.
|
||||
|
||||
// The context menu needs to be opened to properly initialize for the copy
|
||||
// image command to run.
|
||||
let contextMenu = document.getElementById("contentAreaContextMenu");
|
||||
let contextMenuShown = promisePopupShown(contextMenu);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("#img", { type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
|
||||
yield contextMenuShown;
|
||||
|
||||
document.getElementById("context-copyimage-contents").doCommand();
|
||||
|
||||
contextMenu.hidePopup();
|
||||
yield promisePopupHidden(contextMenu);
|
||||
|
||||
// Focus the content again
|
||||
yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
|
||||
|
||||
let expectedContent = yield ContentTask.spawn(browser, { modifier: modifier },
|
||||
function* (arg) {
|
||||
var doc = content.document;
|
||||
var main = doc.getElementById("main");
|
||||
main.focus();
|
||||
|
||||
yield new Promise((resolve, reject) => {
|
||||
addEventListener("paste", function copyEvent(event) {
|
||||
removeEventListener("paste", copyEvent, true);
|
||||
let clipboardData = event.clipboardData;
|
||||
|
||||
// DataTransfer doesn't support the image types yet, so only text/html
|
||||
// will be present.
|
||||
if (clipboardData.getData("text/html") !=
|
||||
'<img id="img" tabindex="1" src="http://example.org/browser/browser/base/content/test/general/moz.png">') {
|
||||
reject();
|
||||
}
|
||||
resolve();
|
||||
}, true)
|
||||
|
||||
const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
|
||||
const modifier = arg.modifier;
|
||||
if (utils.sendKeyEvent("keydown", "v", 0, modifier)) {
|
||||
utils.sendKeyEvent("keypress", "v", "v".charCodeAt(0), modifier);
|
||||
}
|
||||
utils.sendKeyEvent("keyup", "v", 0, modifier);
|
||||
});
|
||||
|
||||
// Return the new content which should now include an image.
|
||||
return main.innerHTML;
|
||||
});
|
||||
|
||||
is(expectedContent, '<i>Italic</i> <img id="img" tabindex="1" ' +
|
||||
'src="http://example.org/browser/browser/base/content/test/general/moz.png">' +
|
||||
'Test <b>Bold</b> After<b></b>', "Paste after copy image");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
|
@ -6,7 +6,9 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(AF13EA3A-D488-4308-B843-526E055AB943)]
|
||||
interface nsIDOMNode;
|
||||
|
||||
[scriptable, uuid(35BE2D7E-F29B-48EC-BF7E-80A30A724DE3)]
|
||||
interface nsIContentViewerEdit : nsISupports
|
||||
{
|
||||
void clearSelection();
|
||||
@ -27,4 +29,8 @@ interface nsIContentViewerEdit : nsISupports
|
||||
|
||||
AString getContents(in string aMimeType, in boolean aSelectionOnly);
|
||||
readonly attribute boolean canGetContents;
|
||||
|
||||
// Set the node that will be the subject of the editing commands above.
|
||||
// Usually this will be the node that was context-clicked.
|
||||
void setCommandNode(in nsIDOMNode aNode);
|
||||
};
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIDOMHTMLFrameSetElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIXULDocument.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
@ -2707,6 +2708,20 @@ NS_IMETHODIMP nsDocumentViewer::GetCanGetContents(bool *aCanGetContents)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetCommandNode(nsIDOMNode* aNode)
|
||||
{
|
||||
nsIDocument* document = GetDocument();
|
||||
NS_ENSURE_STATE(document);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(document->GetWindow());
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
|
||||
NS_ENSURE_STATE(root);
|
||||
|
||||
root->SetPopupNode(aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================================
|
||||
* nsIContentViewerFile
|
||||
@ -3529,8 +3544,16 @@ NS_IMETHODIMP nsDocumentViewer::GetInImage(bool* aInImage)
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
// if we made it here, we're in an image
|
||||
*aInImage = true;
|
||||
// Make sure there is a URI assigned. This allows <input type="image"> to
|
||||
// be an image but rejects other <input> types. This matches what
|
||||
// nsContextMenu.js does.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
node->GetCurrentURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
// if we made it here, we're in an image
|
||||
*aInImage = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user