summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/chrome/window_browser_drop.xhtml
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/tests/chrome/window_browser_drop.xhtml')
-rw-r--r--toolkit/content/tests/chrome/window_browser_drop.xhtml247
1 files changed, 247 insertions, 0 deletions
diff --git a/toolkit/content/tests/chrome/window_browser_drop.xhtml b/toolkit/content/tests/chrome/window_browser_drop.xhtml
new file mode 100644
index 0000000000..5bd69ad77b
--- /dev/null
+++ b/toolkit/content/tests/chrome/window_browser_drop.xhtml
@@ -0,0 +1,247 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Browser Drop Tests"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+ <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+
+<script>
+<![CDATA[
+
+const { ContentTask } = ChromeUtils.import("resource://testing-common/ContentTask.jsm");
+
+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}, async function({data, shouldExpectStateChange}) {
+ if (!content.document.documentElement) {
+ // Wait until the testing document gets loaded.
+ await new Promise(resolve => {
+ let onload = function() {
+ content.window.removeEventListener("load", onload);
+ resolve();
+ };
+ content.window.addEventListener("load", onload);
+ });
+ }
+
+ let dataTransfer = new content.DataTransfer();
+ 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 links = [];
+ try {
+ 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);
+ console.error(ex);
+ }
+ }
+
+ return links;
+ });
+}
+
+async 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) {
+ ok(false, `droppedLinkHandler called for ${JSON.stringify(links)} which we didn't expect.`);
+ }
+ lastLinks = links;
+ resolve(links);
+ };
+ });
+
+ function dropOnBrowserSync() {
+ let dropEl = onbody ? browser.contentDocument.body : browser;
+ synthesizeDrop(dropEl, dropEl, data, null, dropEl.ownerGlobal);
+ }
+ let links;
+ if (browser.isRemoteBrowser) {
+ let remoteLinks = await dropOnRemoteBrowserAsync(browser, data, expectedLinks.length);
+ 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) {
+ // There is no way to check if nothing happens asynchronously.
+ return;
+ }
+
+ links = await lastLinksPromise;
+ } else {
+ dropOnBrowserSync();
+ links = lastLinks;
+ }
+
+ 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");
+ }
+};
+
+async function dropLinksOnBrowser(browser, type) {
+ // Dropping single text/plain item with single link should open single
+ // page.
+ await 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.
+ await 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.
+ await 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.
+ await 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.
+ await 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.
+ await 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);
+
+ await 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 single item with multiple types should open single page.
+ await 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:
+ await expectLink(browser,
+ [],
+ [ [ { type: "text/plain",
+ data: "javascript:'bad'" } ] ],
+ "text/plain javascript url drop on browser " + type);
+ await expectLink(browser,
+ [],
+ [ [ { type: "text/plain",
+ data: "jAvascript:'also bad'" } ] ],
+ "text/plain mixed-case javascript url drop on browser " + type);
+ await 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,
+ // defaulting to a source of file:///
+ await expectLink(browser,
+ [],
+ [ [ { type: "text/x-moz-url",
+ data: "chrome://browser/content/browser.xhtml" } ] ],
+ "text/x-moz-url chrome url drop on browser " + type);
+
+ if (browser.type == "content") {
+ await SpecialPowers.spawn(browser, [], function() {
+ content.window.stopMode = true;
+ });
+
+ // stopPropagation should not prevent the browser link handling from occuring
+ await 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);
+
+ await SpecialPowers.spawn(browser, [], function() {
+ content.window.cancelMode = true;
+ });
+
+ // Canceling the event, however, should prevent the link from being handled.
+ await expectLink(browser,
+ [],
+ [ [ { type: "text/uri-list", data: "http://www.mozilla.org/" } ] ],
+ "text/x-moz-url drop on browser with cancelled drop event", true);
+ }
+}
+
+function info(msg) { window.arguments[0].SimpleTest.info(msg); }
+function is(l, r, n) { window.arguments[0].SimpleTest.is(l,r,n); }
+function ok(v, n) { window.arguments[0].SimpleTest.ok(v,n); }
+
+]]>
+</script>
+
+<html:style>
+ /* FIXME: This is just preserving behavior from before bug 1656081.
+ * Without this there's one subtest that fails, but the browser
+ * elements were zero-sized before so... */
+ browser {
+ min-width: 0;
+ min-height: 0;
+ }
+</html:style>
+
+<browser id="chromechild" src="about:blank"/>
+<browser id="contentchild" type="content" style="width: 100px; height: 100px"
+ src="data:text/html,&lt;html draggable='true'&gt;&lt;body draggable='true' style='width: 100px; height: 100px;' ondragover='event.preventDefault()' ondrop='if (window.stopMode) event.stopPropagation(); if (window.cancelMode) event.preventDefault();'&gt;&lt;/body&gt;&lt;/html&gt;"/>
+<browser id="remote-contentchild" type="content" remote="true" style="width: 100px; height: 100px"
+ src="data:text/html,&lt;html draggable='true'&gt;&lt;body draggable='true' style='width: 100px; height: 100px;' ondragover='event.preventDefault()' ondrop='if (window.stopMode) event.stopPropagation(); if (window.cancelMode) event.preventDefault();'&gt;&lt;/body&gt;&lt;/html&gt;"/>
+</window>