This patch was autogenerated by my decomponents.py
It covers almost every file with the extension js, jsm, html, py,
xhtml, or xul.
It removes blank lines after removed lines, when the removed lines are
preceded by either blank lines or the start of a new block. The "start
of a new block" is defined fairly hackily: either the line starts with
//, ends with */, ends with {, <![CDATA[, """ or '''. The first two
cover comments, the third one covers JS, the fourth covers JS embedded
in XUL, and the final two cover JS embedded in Python. This also
applies if the removed line was the first line of the file.
It covers the pattern matching cases like "var {classes: Cc,
interfaces: Ci, utils: Cu, results: Cr} = Components;". It'll remove
the entire thing if they are all either Ci, Cr, Cc or Cu, or it will
remove the appropriate ones and leave the residue behind. If there's
only one behind, then it will turn it into a normal, non-pattern
matching variable definition. (For instance, "const { classes: Cc,
Constructor: CC, interfaces: Ci, utils: Cu } = Components" becomes
"const CC = Components.Constructor".)
MozReview-Commit-ID: DeSHcClQ7cG
182 lines
7.0 KiB
JavaScript
182 lines
7.0 KiB
JavaScript
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set sts=2 sw=2 et tw=80: */
|
|
"use strict";
|
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
ChromeUtils.import("resource://testing-common/httpd.js");
|
|
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
|
|
const server = new HttpServer();
|
|
server.registerDirectory("/", do_get_cwd());
|
|
server.start(-1);
|
|
const ROOT = `http://localhost:${server.identity.primaryPort}`;
|
|
const BASE = `${ROOT}/`;
|
|
const HEADLESS_URL = `${BASE}/headless.html`;
|
|
const HEADLESS_BUTTON_URL = `${BASE}/headless_button.html`;
|
|
registerCleanupFunction(() => { server.stop(() => {})});
|
|
|
|
// Refrences to the progress listeners to keep them from being gc'ed
|
|
// before they are called.
|
|
const progressListeners = new Map();
|
|
|
|
function loadContentWindow(webNavigation, uri) {
|
|
return new Promise((resolve, reject) => {
|
|
webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
|
|
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIDocShell);
|
|
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIWebProgress);
|
|
let progressListener = {
|
|
onLocationChange: function (progress, request, location, flags) {
|
|
// Ignore inner-frame events
|
|
if (progress != webProgress) {
|
|
return;
|
|
}
|
|
// Ignore events that don't change the document
|
|
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
|
|
return;
|
|
}
|
|
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIDocShell);
|
|
let contentWindow = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIDOMWindow);
|
|
webProgress.removeProgressListener(progressListener);
|
|
progressListeners.delete(progressListener);
|
|
contentWindow.addEventListener("load", (event) => {
|
|
resolve(contentWindow);
|
|
}, { once: true });
|
|
},
|
|
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
|
|
"nsISupportsWeakReference"])
|
|
};
|
|
progressListeners.set(progressListener, progressListener);
|
|
webProgress.addProgressListener(progressListener,
|
|
Ci.nsIWebProgress.NOTIFY_LOCATION);
|
|
});
|
|
}
|
|
|
|
add_task(async function test_snapshot() {
|
|
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
|
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
|
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_URL);
|
|
const contentWidth = 400;
|
|
const contentHeight = 300;
|
|
// Verify dimensions.
|
|
contentWindow.resizeTo(contentWidth, contentHeight);
|
|
equal(contentWindow.innerWidth, contentWidth);
|
|
equal(contentWindow.innerHeight, contentHeight);
|
|
|
|
// Snapshot the test page.
|
|
let canvas = contentWindow.document.createElementNS('http://www.w3.org/1999/xhtml', 'html:canvas');
|
|
let context = canvas.getContext('2d');
|
|
let width = contentWindow.innerWidth;
|
|
let height = contentWindow.innerHeight;
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
context.drawWindow(
|
|
contentWindow,
|
|
0,
|
|
0,
|
|
width,
|
|
height,
|
|
'rgb(255, 255, 255)'
|
|
);
|
|
let imageData = context.getImageData(0, 0, width, height).data;
|
|
ok(imageData[0] === 0 && imageData[1] === 255 && imageData[2] === 0 && imageData[3] === 255, "Page is green.");
|
|
|
|
// Search for a blue pixel (a quick and dirty check to see if the blue text is
|
|
// on the page)
|
|
let found = false;
|
|
for (let i = 0; i < imageData.length; i += 4) {
|
|
if (imageData[i + 2] === 255) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
ok(found, "Found blue text on page.");
|
|
|
|
webNavigation.close();
|
|
});
|
|
|
|
add_task(function* test_snapshot_widget_layers() {
|
|
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
|
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
|
let contentWindow = yield loadContentWindow(webNavigation, HEADLESS_URL);
|
|
const contentWidth = 1;
|
|
const contentHeight = 2;
|
|
// Verify dimensions.
|
|
contentWindow.resizeTo(contentWidth, contentHeight);
|
|
equal(contentWindow.innerWidth, contentWidth);
|
|
equal(contentWindow.innerHeight, contentHeight);
|
|
|
|
// Snapshot the test page.
|
|
let canvas = contentWindow.document.createElementNS('http://www.w3.org/1999/xhtml', 'html:canvas');
|
|
let context = canvas.getContext('2d');
|
|
let width = contentWindow.innerWidth;
|
|
let height = contentWindow.innerHeight;
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
context.drawWindow(
|
|
contentWindow,
|
|
0,
|
|
0,
|
|
width,
|
|
height,
|
|
'rgb(255, 255, 255)',
|
|
context.DRAWWINDOW_DRAW_CARET | context.DRAWWINDOW_DRAW_VIEW | context.DRAWWINDOW_USE_WIDGET_LAYERS
|
|
);
|
|
ok(true, "Snapshot with widget layers didn't crash.");
|
|
|
|
webNavigation.close();
|
|
});
|
|
|
|
// Ensure keydown events are triggered on the windowless browser.
|
|
add_task(async function test_keydown() {
|
|
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
|
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
|
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_URL);
|
|
|
|
let keydown = new Promise((resolve) => {
|
|
contentWindow.addEventListener("keydown", () => {
|
|
resolve();
|
|
}, { once: true });
|
|
})
|
|
|
|
let tip = Cc["@mozilla.org/text-input-processor;1"]
|
|
.createInstance(Ci.nsITextInputProcessor);
|
|
let begun = tip.beginInputTransactionForTests(contentWindow);
|
|
ok(begun, "nsITextInputProcessor.beginInputTransactionForTests() should succeed");
|
|
tip.keydown(new contentWindow.KeyboardEvent("", {key: "a", code: "KeyA", keyCode: contentWindow.KeyboardEvent.DOM_VK_A}));
|
|
|
|
await keydown;
|
|
ok(true, "Send keydown didn't crash");
|
|
|
|
webNavigation.close();
|
|
});
|
|
|
|
// Test dragging the mouse on a button to ensure the creation of the drag
|
|
// service doesn't crash in headless.
|
|
add_task(async function test_mouse_drag() {
|
|
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
|
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
|
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_BUTTON_URL);
|
|
contentWindow.resizeTo(400, 400);
|
|
|
|
let target = contentWindow.document.getElementById('btn');
|
|
let rect = target.getBoundingClientRect();
|
|
let left = rect.left;
|
|
let top = rect.top;
|
|
|
|
let utils = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIDOMWindowUtils);
|
|
utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
|
|
utils.sendMouseEvent("mousemove", left, top, 0, 1, 0, false, 0, 0);
|
|
// Wait for a turn of the event loop since the synthetic mouse event
|
|
// that creates the drag service is processed during the refresh driver.
|
|
await new Promise((r) => {executeSoon(r)});
|
|
utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
|
|
|
|
ok(true, "Send mouse event didn't crash");
|
|
|
|
webNavigation.close();
|
|
});
|