зеркало из https://github.com/mozilla/gecko-dev.git
Bug 92737 - Part 3: Open multiple tabs when multiple items are dropped on remote content area. r=enndeakin
This commit is contained in:
Родитель
9867f060f7
Коммит
e933275fe8
|
@ -5654,9 +5654,14 @@ function handleDroppedLink(event, urlOrLinks, name)
|
|||
|
||||
let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid");
|
||||
|
||||
let inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
|
||||
if (event.shiftKey)
|
||||
inBackground = !inBackground;
|
||||
// event is null if links are dropped in content process.
|
||||
// inBackground should be false, as it's loading into current browser.
|
||||
let inBackground = false;
|
||||
if (event) {
|
||||
let inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
|
||||
if (event.shiftKey)
|
||||
inBackground = !inBackground;
|
||||
}
|
||||
|
||||
Task.spawn(function*() {
|
||||
let urls = [];
|
||||
|
@ -5677,9 +5682,13 @@ function handleDroppedLink(event, urlOrLinks, name)
|
|||
}
|
||||
});
|
||||
|
||||
// Keep the event from being handled by the dragDrop listeners
|
||||
// built-in to gecko if they happen to be above us.
|
||||
event.preventDefault();
|
||||
// If links are dropped in content process, event.preventDefault() should be
|
||||
// called in content process.
|
||||
if (event) {
|
||||
// Keep the event from being handled by the dragDrop listeners
|
||||
// built-in to gecko if they happen to be above us.
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function BrowserSetForcedCharacterSet(aCharset)
|
||||
|
|
|
@ -23,4 +23,3 @@ interface nsIRemoteBrowser : nsISupports
|
|||
in unsigned long disabledLength,
|
||||
[array, size_is(disabledLength)] in string disabledCommands);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
|
||||
#include "domstubs.idl"
|
||||
#include "nsIDroppedLinkHandler.idl"
|
||||
|
||||
interface nsIContentFrameMessageManager;
|
||||
interface nsIWebBrowserChrome3;
|
||||
|
||||
|
@ -28,6 +30,9 @@ interface nsITabChild : nsISupports
|
|||
[noscript] void remoteSizeShellTo(in int32_t width, in int32_t height,
|
||||
in int32_t shellItemWidth, in int32_t shellItemHeight);
|
||||
|
||||
[noscript] void remoteDropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in nsIDroppedLinkItem links);
|
||||
|
||||
readonly attribute uint64_t tabId;
|
||||
};
|
||||
|
||||
|
|
|
@ -186,6 +186,14 @@ parent:
|
|||
async SizeShellTo(uint32_t aFlag, int32_t aWidth, int32_t aHeight,
|
||||
int32_t aShellItemWidth, int32_t aShellItemHeight);
|
||||
|
||||
/**
|
||||
* Called by the child to inform the parent that links are dropped into
|
||||
* content area.
|
||||
*
|
||||
* aLinks A flat array of url, name, and type for each link
|
||||
*/
|
||||
async DropLinks(nsString[] aLinks);
|
||||
|
||||
async Event(RemoteDOMEvent aEvent);
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
|
|
|
@ -952,6 +952,37 @@ TabChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
|
|||
return sent ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
|
||||
{
|
||||
nsTArray<nsString> linksArray;
|
||||
nsresult rv = NS_OK;
|
||||
for (uint32_t i = 0; i < aLinksCount; i++) {
|
||||
nsString tmp;
|
||||
rv = aLinks[i]->GetUrl(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
linksArray.AppendElement(tmp);
|
||||
|
||||
rv = aLinks[i]->GetName(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
linksArray.AppendElement(tmp);
|
||||
|
||||
rv = aLinks[i]->GetType(tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
linksArray.AppendElement(tmp);
|
||||
}
|
||||
|
||||
bool sent = SendDropLinks(linksArray);
|
||||
|
||||
return sent ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::SizeBrowserTo(int32_t aWidth, int32_t aHeight)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsFocusManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIBrowser.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
|
@ -697,6 +698,21 @@ TabParent::RecvSizeShellTo(const uint32_t& aFlags, const int32_t& aWidth, const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
|
||||
{
|
||||
nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
|
||||
if (browser) {
|
||||
UniquePtr<const char16_t*[]> links;
|
||||
links = MakeUnique<const char16_t*[]>(aLinks.Length());
|
||||
for (uint32_t i = 0; i < aLinks.Length(); i++) {
|
||||
links[i] = aLinks[i].get();
|
||||
}
|
||||
browser->DropLinks(aLinks.Length(), links.get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
|
||||
{
|
||||
|
|
|
@ -170,6 +170,8 @@ public:
|
|||
const int32_t& aShellItemWidth,
|
||||
const int32_t& aShellItemHeight) override;
|
||||
|
||||
virtual bool RecvDropLinks(nsTArray<nsString>&& aLinks) override;
|
||||
|
||||
virtual bool RecvEvent(const RemoteDOMEvent& aEvent) override;
|
||||
|
||||
virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& aEvent) override;
|
||||
|
|
|
@ -14,4 +14,14 @@ interface nsIBrowser : nsISupports
|
|||
* for any new tab parents.
|
||||
*/
|
||||
readonly attribute nsIDOMElement relatedBrowser;
|
||||
|
||||
/*
|
||||
* Called by the child to inform the parent that links are dropped into
|
||||
* content area.
|
||||
*
|
||||
* @param linksCount length of links
|
||||
* @param links a flat array of url, name, and type for each link
|
||||
*/
|
||||
void dropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in wstring links);
|
||||
};
|
||||
|
|
|
@ -1062,11 +1062,34 @@ nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
|
|||
} else if (eventType.EqualsLiteral("drop")) {
|
||||
nsIWebNavigation* webnav = static_cast<nsIWebNavigation*>(mWebBrowser);
|
||||
|
||||
nsAutoString link, name;
|
||||
uint32_t linksCount;
|
||||
nsIDroppedLinkItem** links;
|
||||
if (webnav &&
|
||||
NS_SUCCEEDED(handler->DropLink(dragEvent, name, true, link))) {
|
||||
if (!link.IsEmpty()) {
|
||||
webnav->LoadURI(link.get(), 0, nullptr, nullptr, nullptr);
|
||||
NS_SUCCEEDED(handler->DropLinks(dragEvent, true, &linksCount, &links))) {
|
||||
if (linksCount >= 1) {
|
||||
nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
|
||||
if (webBrowserChrome) {
|
||||
nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(webBrowserChrome);
|
||||
if (tabChild) {
|
||||
nsresult rv = tabChild->RemoteDropLinks(linksCount, links);
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_RELEASE(links[i]);
|
||||
}
|
||||
free(links);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
nsAutoString url;
|
||||
if (NS_SUCCEEDED(links[0]->GetUrl(url))) {
|
||||
if (!url.IsEmpty()) {
|
||||
webnav->LoadURI(url.get(), 0, nullptr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_RELEASE(links[i]);
|
||||
}
|
||||
free(links);
|
||||
}
|
||||
} else {
|
||||
aEvent->StopPropagation();
|
||||
|
|
|
@ -14,123 +14,204 @@
|
|||
|
||||
Components.utils.import("resource://testing-common/ContentTask.jsm");
|
||||
|
||||
function doDropAndStopLoad(browser, data, shouldExpectStateChange) {
|
||||
function dropOnRemoteBrowserAsync(browser, data, shouldExpectStateChange) {
|
||||
ContentTask.setTestScope(window); // Need this so is/isnot/ok are available inside the contenttask
|
||||
return ContentTask.spawn(browser, {data, shouldExpectStateChange}, function*({data, shouldExpectStateChange}) {
|
||||
let { interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let nameReturned = "";
|
||||
let uri = "";
|
||||
let gotLoad = false;
|
||||
function stopContent(uriLoaded) {
|
||||
content.stop();
|
||||
gotLoad = true;
|
||||
uri = uriLoaded;
|
||||
if (!content.document.documentElement) {
|
||||
// Wait until the testing document gets loaded.
|
||||
yield new Promise(resolve => {
|
||||
let onload = function() {
|
||||
content.window.removeEventListener("load", onload);
|
||||
resolve();
|
||||
};
|
||||
content.window.addEventListener("load", onload);
|
||||
});
|
||||
}
|
||||
|
||||
let wp = docShell.QueryInterface(Ci.nsIWebProgress);
|
||||
let progressListener = {
|
||||
onStateChange: function (webProgress, req, flags, status) {
|
||||
info("waitForDocLoadAndStopIt: onStateChange " + flags.toString(16) + ": " + req.name + "\n");
|
||||
|
||||
if (webProgress.isTopLevel &&
|
||||
flags & Ci.nsIWebProgressListener.STATE_START) {
|
||||
wp.removeProgressListener(progressListener);
|
||||
|
||||
let chan = req.QueryInterface(Ci.nsIChannel);
|
||||
info(`waitForDocLoadAndStopIt: Document start: ${chan.URI.spec}\n`);
|
||||
|
||||
stopContent(chan.originalURI.spec);
|
||||
}
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI(["nsISupportsWeakReference"])
|
||||
};
|
||||
wp.addProgressListener(progressListener, wp.NOTIFY_STATE_WINDOW);
|
||||
|
||||
let dataTransfer = new content.DataTransfer("dragstart", false);
|
||||
dataTransfer.mozSetDataAt(data.type, data.data, 0);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let types = data[i];
|
||||
for (let j = 0; j < types.length; j++) {
|
||||
dataTransfer.mozSetDataAt(types[j].type, types[j].data, i);
|
||||
}
|
||||
}
|
||||
let event = content.document.createEvent("DragEvent");
|
||||
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
content.document.body.dispatchEvent(event);
|
||||
let nameGetter = {};
|
||||
|
||||
let links = [];
|
||||
try {
|
||||
Services.droppedLinkHandler.dropLink(event, nameGetter, true);
|
||||
nameReturned = nameGetter.value;
|
||||
links = Services.droppedLinkHandler.dropLinks(event, true);
|
||||
} catch (ex) {
|
||||
if (shouldExpectStateChange) {
|
||||
ok(false, "Should not have gotten an exception from the dropped link handler, but got: " + ex);
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
is(shouldExpectStateChange, gotLoad, "Should have gotten a load only if we expected it.");
|
||||
if (!gotLoad) {
|
||||
wp.removeProgressListener(progressListener);
|
||||
}
|
||||
return [uri, nameReturned];
|
||||
|
||||
return links;
|
||||
});
|
||||
}
|
||||
|
||||
function expectLink(browser, expectedLink, expectedName, data, testid, onbody=false) {
|
||||
let lastLink = "";
|
||||
let lastLinkName = "";
|
||||
function dropOnBrowserSync() {
|
||||
browser.droppedLinkHandler = function(event, link, linkname) {
|
||||
info(`droppedLinkHandler called, received link ${link} and linkname ${linkname}`);
|
||||
if (!expectedLink && !expectedName) {
|
||||
ok(false, "droppedLinkHandler called for URI " + link + " which we didn't expect.");
|
||||
function* expectLink(browser, expectedLinks, data, testid, onbody=false) {
|
||||
let lastLinks = [];
|
||||
let lastLinksPromise = new Promise(resolve => {
|
||||
browser.droppedLinkHandler = function(event, links) {
|
||||
info(`droppedLinkHandler called, received links ${JSON.stringify(links)}`);
|
||||
if (expectedLinks.length == 0) {
|
||||
ok(false, `droppedLinkHandler called for ${JSON.stringify(links)} which we didn't expect.`);
|
||||
}
|
||||
lastLink = link;
|
||||
lastLinkName = linkname;
|
||||
lastLinks = links;
|
||||
resolve(links);
|
||||
};
|
||||
});
|
||||
|
||||
function dropOnBrowserSync() {
|
||||
let dropEl = onbody ? browser.contentDocument.body : browser;
|
||||
synthesizeDrop(dropEl, dropEl, data, "", dropEl.ownerDocument.defaultView);
|
||||
return Promise.resolve([lastLink, lastLinkName]);
|
||||
}
|
||||
let dropInfoReceived;
|
||||
let links;
|
||||
if (browser.isRemoteBrowser) {
|
||||
dropInfoReceived = doDropAndStopLoad(browser, data[0][0], !!expectedLink);
|
||||
let remoteLinks = yield dropOnRemoteBrowserAsync(browser, data, expectedLinks.length != 0);
|
||||
is(remoteLinks.length, expectedLinks.length, testid + " remote links length");
|
||||
for (let i = 0, length = remoteLinks.length; i < length; i++) {
|
||||
is(remoteLinks[i].url, expectedLinks[i].url, testid + "[" + i + "] remote link");
|
||||
is(remoteLinks[i].name, expectedLinks[i].name, testid + "[" + i + "] remote name");
|
||||
}
|
||||
|
||||
if (expectedLinks.length == 0) {
|
||||
// There is no way to check if nothing happens asynchronously.
|
||||
return;
|
||||
}
|
||||
|
||||
links = yield lastLinksPromise;
|
||||
} else {
|
||||
dropInfoReceived = dropOnBrowserSync();
|
||||
dropOnBrowserSync();
|
||||
links = lastLinks;
|
||||
}
|
||||
return dropInfoReceived.then(([uri, linkname]) => {
|
||||
is(uri, expectedLink, testid + " link");
|
||||
is(linkname, expectedName, testid + " name");
|
||||
});
|
||||
}
|
||||
|
||||
is(links.length, expectedLinks.length, testid + " links length");
|
||||
for (let i = 0, length = links.length; i < length; i++) {
|
||||
is(links[i].url, expectedLinks[i].url, testid + "[" + i + "] link");
|
||||
is(links[i].name, expectedLinks[i].name, testid + "[" + i + "] name");
|
||||
}
|
||||
};
|
||||
|
||||
function* dropLinksOnBrowser(browser, type) {
|
||||
yield expectLink(browser, "http://www.mozilla.org/", "http://www.mozilla.org/",
|
||||
[ [ { type: "text/plain", data: "http://www.mozilla.org/" } ] ],
|
||||
"text/plain drop on browser " + type);
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/link", data: "http://www.mozilla.org/" } ] ],
|
||||
"text/link drop on browser " + type);
|
||||
yield expectLink(browser, "http://www.example.com/", "http://www.example.com/",
|
||||
[ [ { type: "text/uri-list", data: "http://www.example.com/\nhttp://www.mozilla.org" } ] ],
|
||||
"text/uri-list drop on browser " + type);
|
||||
yield expectLink(browser, "http://www.example.com/", "Example.com",
|
||||
[ [ { type: "text/x-moz-url", data: "http://www.example.com/\nExample.com" } ] ],
|
||||
"text/x-moz-url drop on browser " + type);
|
||||
// Dropping single text/plain item with single link should open single
|
||||
// page.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.mozilla.org/",
|
||||
name: "http://www.mozilla.org/" } ],
|
||||
[ [ { type: "text/plain",
|
||||
data: "http://www.mozilla.org/" } ] ],
|
||||
"text/plain drop on browser " + type);
|
||||
|
||||
// Dropping single text/plain item with multiple links should open
|
||||
// multiple pages.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.mozilla.org/",
|
||||
name: "http://www.mozilla.org/" },
|
||||
{ url: "http://www.example.com/",
|
||||
name: "http://www.example.com/" } ],
|
||||
[ [ { type: "text/plain",
|
||||
data: "http://www.mozilla.org/\nhttp://www.example.com/" } ] ],
|
||||
"text/plain with 2 URLs drop on browser " + type);
|
||||
|
||||
// Dropping sinlge unsupported type item should not open anything.
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/link",
|
||||
data: "http://www.mozilla.org/" } ] ],
|
||||
"text/link drop on browser " + type);
|
||||
|
||||
// Dropping single text/uri-list item with single link should open single
|
||||
// page.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.example.com/",
|
||||
name: "http://www.example.com/" } ],
|
||||
[ [ { type: "text/uri-list",
|
||||
data: "http://www.example.com/" } ] ],
|
||||
"text/uri-list drop on browser " + type);
|
||||
|
||||
// Dropping single text/uri-list item with multiple links should open
|
||||
// multiple pages.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.example.com/",
|
||||
name: "http://www.example.com/" },
|
||||
{ url: "http://www.mozilla.org/",
|
||||
name: "http://www.mozilla.org/" }],
|
||||
[ [ { type: "text/uri-list",
|
||||
data: "http://www.example.com/\nhttp://www.mozilla.org/" } ] ],
|
||||
"text/uri-list with 2 URLs drop on browser " + type);
|
||||
|
||||
// Name in text/x-moz-url should be handled.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.example.com/",
|
||||
name: "Example.com" } ],
|
||||
[ [ { type: "text/x-moz-url",
|
||||
data: "http://www.example.com/\nExample.com" } ] ],
|
||||
"text/x-moz-url drop on browser " + type);
|
||||
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.mozilla.org/",
|
||||
name: "Mozilla.org" },
|
||||
{ url: "http://www.example.com/",
|
||||
name: "Example.com" } ],
|
||||
[ [ { type: "text/x-moz-url",
|
||||
data: "http://www.mozilla.org/\nMozilla.org\nhttp://www.example.com/\nExample.com" } ] ],
|
||||
"text/x-moz-url with 2 URLs drop on browser " + type);
|
||||
|
||||
// Dropping multiple items should open multiple pages.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.example.com/",
|
||||
name: "Example.com" },
|
||||
{ url: "http://www.mozilla.org/",
|
||||
name: "http://www.mozilla.org/" }],
|
||||
[ [ { type: "text/x-moz-url",
|
||||
data: "http://www.example.com/\nExample.com" } ],
|
||||
[ { type: "text/plain",
|
||||
data: "http://www.mozilla.org/" } ] ],
|
||||
"text/x-moz-url and text/plain drop on browser " + type);
|
||||
|
||||
// Dropping single item with multiple types should open single page.
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.example.org/",
|
||||
name: "Example.com" } ],
|
||||
[ [ { type: "text/plain",
|
||||
data: "http://www.mozilla.org/" },
|
||||
{ type: "text/x-moz-url",
|
||||
data: "http://www.example.org/\nExample.com" } ] ],
|
||||
"text/plain and text/x-moz-url drop on browser " + type);
|
||||
|
||||
// Dropping javascript or data: URLs should fail:
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/plain", data: "javascript:'bad'" } ] ],
|
||||
"text/plain javascript url drop on browser " + type);
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/plain", data: "jAvascript:'also bad'" } ] ],
|
||||
"text/plain mixed-case javascript url drop on browser " + type);
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/plain", data: "data:text/html,bad" } ] ],
|
||||
"text/plain data url drop on browser " + type);
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/plain",
|
||||
data: "javascript:'bad'" } ] ],
|
||||
"text/plain javascript url drop on browser " + type);
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/plain",
|
||||
data: "jAvascript:'also bad'" } ] ],
|
||||
"text/plain mixed-case javascript url drop on browser " + type);
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/plain",
|
||||
data: "data:text/html,bad" } ] ],
|
||||
"text/plain data url drop on browser " + type);
|
||||
|
||||
// dropping a chrome url should fail as we don't have a source node set,
|
||||
// Dropping a chrome url should fail as we don't have a source node set,
|
||||
// defaulting to a source of file:///
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/x-moz-url", data: "chrome://browser/content/browser.xul" } ] ],
|
||||
"text/x-moz-url chrome url drop on browser " + type);
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/x-moz-url",
|
||||
data: "chrome://browser/content/browser.xul" } ] ],
|
||||
"text/x-moz-url chrome url drop on browser " + type);
|
||||
|
||||
if (browser.type == "content") {
|
||||
yield ContentTask.spawn(browser, null, function() {
|
||||
|
@ -138,18 +219,22 @@ function* dropLinksOnBrowser(browser, type) {
|
|||
});
|
||||
|
||||
// stopPropagation should not prevent the browser link handling from occuring
|
||||
yield expectLink(browser, "http://www.mozilla.org/", "http://www.mozilla.org/",
|
||||
[ [ { type: "text/uri-list", data: "http://www.mozilla.org/" } ] ],
|
||||
"text/x-moz-url drop on browser with stopPropagation drop event", true);
|
||||
yield* expectLink(browser,
|
||||
[ { url: "http://www.mozilla.org/",
|
||||
name: "http://www.mozilla.org/" } ],
|
||||
[ [ { type: "text/uri-list",
|
||||
data: "http://www.mozilla.org/" } ] ],
|
||||
"text/x-moz-url drop on browser with stopPropagation drop event", true);
|
||||
|
||||
yield ContentTask.spawn(browser, null, function() {
|
||||
content.window.cancelMode = true;
|
||||
});
|
||||
|
||||
// canceling the event, however, should prevent the link from being handled
|
||||
yield expectLink(browser, "", "",
|
||||
[ [ { type: "text/uri-list", data: "http://www.mozilla.org/" } ] ],
|
||||
"text/x-moz-url drop on browser with cancelled drop event", true);
|
||||
// Canceling the event, however, should prevent the link from being handled.
|
||||
yield* expectLink(browser,
|
||||
[],
|
||||
[ [ { type: "text/uri-list", data: "http://www.mozilla.org/" } ] ],
|
||||
"text/x-moz-url drop on browser with cancelled drop event", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1336,6 +1336,26 @@
|
|||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="dropLinks">
|
||||
<parameter name="aLinksCount"/>
|
||||
<parameter name="aLinks"/>
|
||||
<body><![CDATA[
|
||||
if (!this.droppedLinkHandler) {
|
||||
return false;
|
||||
}
|
||||
let links = [];
|
||||
for (let i = 0; i < aLinksCount; i += 3) {
|
||||
links.push({
|
||||
url: aLinks[i],
|
||||
name: aLinks[i + 1],
|
||||
type: aLinks[i + 2],
|
||||
});
|
||||
}
|
||||
this.droppedLinkHandler(null, links);
|
||||
return true;
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
|
Загрузка…
Ссылка в новой задаче