forked from mirrors/gecko-dev
Bug 1561435 - Format layout/, a=automatic-formatting
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35927 --HG-- extra : source : b9cc96337c05dbb9a9f811c63dcc5fd63588d652
This commit is contained in:
parent
baef0fa817
commit
6a261b9e77
29 changed files with 9192 additions and 4513 deletions
|
|
@ -45,7 +45,6 @@ module.exports = {
|
||||||
"overrides": [{
|
"overrides": [{
|
||||||
"files": [
|
"files": [
|
||||||
"devtools/**",
|
"devtools/**",
|
||||||
"layout/**",
|
|
||||||
"media/**",
|
"media/**",
|
||||||
"memory/**",
|
"memory/**",
|
||||||
"mfbt/**",
|
"mfbt/**",
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
|
||||||
toolkit/components/telemetry/healthreport-prefs.js
|
toolkit/components/telemetry/healthreport-prefs.js
|
||||||
|
|
||||||
# Ignore all top-level directories for now.
|
# Ignore all top-level directories for now.
|
||||||
layout/**
|
|
||||||
media/**
|
media/**
|
||||||
memory/**
|
memory/**
|
||||||
mfbt/**
|
mfbt/**
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@
|
||||||
|
|
||||||
add_task(async function test() {
|
add_task(async function test() {
|
||||||
// Open the test tab
|
// Open the test tab
|
||||||
let testTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:addons");
|
let testTab = await BrowserTestUtils.openNewForegroundTab(
|
||||||
|
gBrowser,
|
||||||
|
"about:addons"
|
||||||
|
);
|
||||||
|
|
||||||
// insert button into test page content
|
// insert button into test page content
|
||||||
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
|
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
|
||||||
|
|
@ -24,7 +27,11 @@ add_task(async function test() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// open a second tab and select it
|
// open a second tab and select it
|
||||||
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true);
|
let tab2 = await BrowserTestUtils.openNewForegroundTab(
|
||||||
|
gBrowser,
|
||||||
|
"about:blank",
|
||||||
|
true
|
||||||
|
);
|
||||||
gBrowser.selectedTab = tab2;
|
gBrowser.selectedTab = tab2;
|
||||||
|
|
||||||
// Select the testTab then perform mouse events on inserted button
|
// Select the testTab then perform mouse events on inserted button
|
||||||
|
|
@ -32,9 +39,27 @@ add_task(async function test() {
|
||||||
let browser = gBrowser.selectedBrowser;
|
let browser = gBrowser.selectedBrowser;
|
||||||
EventUtils.disableNonTestMouseEvents(true);
|
EventUtils.disableNonTestMouseEvents(true);
|
||||||
try {
|
try {
|
||||||
await BrowserTestUtils.synthesizeMouse("#test-button", 1, 1, { type: "mouseover" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
await BrowserTestUtils.synthesizeMouse("#test-button", 2, 6, { type: "mousemove" }, browser);
|
"#test-button",
|
||||||
await BrowserTestUtils.synthesizeMouse("#test-button", 2, 4, { type: "mousemove" }, browser);
|
1,
|
||||||
|
1,
|
||||||
|
{ type: "mouseover" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#test-button",
|
||||||
|
2,
|
||||||
|
6,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#test-button",
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
EventUtils.disableNonTestMouseEvents(false);
|
EventUtils.disableNonTestMouseEvents(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
function pageScript() {
|
function pageScript() {
|
||||||
window.addEventListener("beforeunload", function (event) {
|
window.addEventListener(
|
||||||
var str = "Some text that causes the beforeunload dialog to be shown";
|
"beforeunload",
|
||||||
event.returnValue = str;
|
function(event) {
|
||||||
return str;
|
var str = "Some text that causes the beforeunload dialog to be shown";
|
||||||
}, true);
|
event.returnValue = str;
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
|
SpecialPowers.pushPrefEnv({
|
||||||
|
set: [["dom.require_user_interaction_for_beforeunload", false]],
|
||||||
|
});
|
||||||
|
|
||||||
const PAGE_URL =
|
const PAGE_URL =
|
||||||
"data:text/html," + encodeURIComponent("<script>(" + pageScript.toSource() + ")();</script>");
|
"data:text/html," +
|
||||||
|
encodeURIComponent("<script>(" + pageScript.toSource() + ")();</script>");
|
||||||
|
|
||||||
add_task(async function enableDialogs() {
|
add_task(async function enableDialogs() {
|
||||||
// The onbeforeunload dialog should appear.
|
// The onbeforeunload dialog should appear.
|
||||||
|
|
@ -34,22 +41,27 @@ add_task(async function disableDialogs() {
|
||||||
|
|
||||||
async function openPage(enableDialogs) {
|
async function openPage(enableDialogs) {
|
||||||
// Open about:blank in a new tab.
|
// Open about:blank in a new tab.
|
||||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, async function(browser) {
|
await BrowserTestUtils.withNewTab(
|
||||||
// Load the content script in the frame.
|
{ gBrowser, url: "about:blank" },
|
||||||
let methodName = enableDialogs ? "enableDialogs" : "disableDialogs";
|
async function(browser) {
|
||||||
await ContentTask.spawn(browser, methodName, async function(name) {
|
// Load the content script in the frame.
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
let methodName = enableDialogs ? "enableDialogs" : "disableDialogs";
|
||||||
Services.obs.addObserver(doc => {
|
await ContentTask.spawn(browser, methodName, async function(name) {
|
||||||
if (content && doc == content.document) {
|
const { Services } = ChromeUtils.import(
|
||||||
content.windowUtils[name]();
|
"resource://gre/modules/Services.jsm"
|
||||||
}
|
);
|
||||||
}, "document-element-inserted");
|
Services.obs.addObserver(doc => {
|
||||||
});
|
if (content && doc == content.document) {
|
||||||
// Load the page.
|
content.windowUtils[name]();
|
||||||
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
}
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
}, "document-element-inserted");
|
||||||
// And then navigate away.
|
});
|
||||||
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
// Load the page.
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
||||||
});
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
|
// And then navigate away.
|
||||||
|
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
function pageScript() {
|
function pageScript() {
|
||||||
window.addEventListener("beforeunload", function (event) {
|
window.addEventListener(
|
||||||
var str = "Some text that causes the beforeunload dialog to be shown";
|
"beforeunload",
|
||||||
event.returnValue = str;
|
function(event) {
|
||||||
return str;
|
var str = "Some text that causes the beforeunload dialog to be shown";
|
||||||
}, true);
|
event.returnValue = str;
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", true]]});
|
SpecialPowers.pushPrefEnv({
|
||||||
|
set: [["dom.require_user_interaction_for_beforeunload", true]],
|
||||||
|
});
|
||||||
|
|
||||||
const PAGE_URL =
|
const PAGE_URL =
|
||||||
"data:text/html," + encodeURIComponent("<script>(" + pageScript.toSource() + ")();</script>");
|
"data:text/html," +
|
||||||
|
encodeURIComponent("<script>(" + pageScript.toSource() + ")();</script>");
|
||||||
|
|
||||||
add_task(async function doClick() {
|
add_task(async function doClick() {
|
||||||
// The onbeforeunload dialog should appear.
|
// The onbeforeunload dialog should appear.
|
||||||
|
|
@ -34,20 +41,27 @@ add_task(async function noClick() {
|
||||||
|
|
||||||
async function openPage(shouldClick) {
|
async function openPage(shouldClick) {
|
||||||
// Open about:blank in a new tab.
|
// Open about:blank in a new tab.
|
||||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, async function(browser) {
|
await BrowserTestUtils.withNewTab(
|
||||||
// Load the page.
|
{ gBrowser, url: "about:blank" },
|
||||||
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
async function(browser) {
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
// Load the page.
|
||||||
|
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
|
|
||||||
if (shouldClick) {
|
if (shouldClick) {
|
||||||
await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser);
|
await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser);
|
||||||
|
}
|
||||||
|
let hasInteractedWith = await ContentTask.spawn(browser, "", function() {
|
||||||
|
return content.document.userHasInteracted;
|
||||||
|
});
|
||||||
|
is(
|
||||||
|
shouldClick,
|
||||||
|
hasInteractedWith,
|
||||||
|
"Click should update document interactivity state"
|
||||||
|
);
|
||||||
|
// And then navigate away.
|
||||||
|
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
}
|
}
|
||||||
let hasInteractedWith = await ContentTask.spawn(browser, "", function() {
|
);
|
||||||
return content.document.userHasInteracted;
|
|
||||||
});
|
|
||||||
is(shouldClick, hasInteractedWith, "Click should update document interactivity state");
|
|
||||||
// And then navigate away.
|
|
||||||
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,34 @@
|
||||||
function pageScript() {
|
function pageScript() {
|
||||||
window.addEventListener("beforeunload", function (event) {
|
window.addEventListener(
|
||||||
var str = "Some text that causes the beforeunload dialog to be shown";
|
"beforeunload",
|
||||||
event.returnValue = str;
|
function(event) {
|
||||||
return str;
|
var str = "Some text that causes the beforeunload dialog to be shown";
|
||||||
}, true);
|
event.returnValue = str;
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", true],
|
SpecialPowers.pushPrefEnv({
|
||||||
["security.allow_eval_with_system_principal", true]]});
|
set: [
|
||||||
|
["dom.require_user_interaction_for_beforeunload", true],
|
||||||
|
["security.allow_eval_with_system_principal", true],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
const FRAME_URL =
|
const FRAME_URL =
|
||||||
"data:text/html," + encodeURIComponent("<body>Just a frame</body>");
|
"data:text/html," + encodeURIComponent("<body>Just a frame</body>");
|
||||||
|
|
||||||
const PAGE_URL =
|
const PAGE_URL =
|
||||||
"data:text/html," + encodeURIComponent("<iframe src='" + FRAME_URL + "'></iframe><script>(" + pageScript.toSource() + ")();</script>");
|
"data:text/html," +
|
||||||
|
encodeURIComponent(
|
||||||
|
"<iframe src='" +
|
||||||
|
FRAME_URL +
|
||||||
|
"'></iframe><script>(" +
|
||||||
|
pageScript.toSource() +
|
||||||
|
")();</script>"
|
||||||
|
);
|
||||||
|
|
||||||
add_task(async function doClick() {
|
add_task(async function doClick() {
|
||||||
// The onbeforeunload dialog should appear.
|
// The onbeforeunload dialog should appear.
|
||||||
|
|
@ -38,23 +53,43 @@ add_task(async function noClick() {
|
||||||
|
|
||||||
async function openPage(shouldClick) {
|
async function openPage(shouldClick) {
|
||||||
// Open about:blank in a new tab.
|
// Open about:blank in a new tab.
|
||||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, async function(browser) {
|
await BrowserTestUtils.withNewTab(
|
||||||
// Load the page.
|
{ gBrowser, url: "about:blank" },
|
||||||
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
async function(browser) {
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
// Load the page.
|
||||||
|
await BrowserTestUtils.loadURI(browser, PAGE_URL);
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
|
|
||||||
if (shouldClick) {
|
if (shouldClick) {
|
||||||
await BrowserTestUtils.synthesizeMouse(function() {
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
return content.frames[0].document.body;
|
function() {
|
||||||
}, 2, 2, {}, browser);
|
return content.frames[0].document.body;
|
||||||
|
},
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
{},
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let hasInteractedWith = await ContentTask.spawn(browser, "", function() {
|
||||||
|
return [
|
||||||
|
content.document.userHasInteracted,
|
||||||
|
content.frames[0].document.userHasInteracted,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
is(
|
||||||
|
shouldClick,
|
||||||
|
hasInteractedWith[0],
|
||||||
|
"Click should update parent interactivity state"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
shouldClick,
|
||||||
|
hasInteractedWith[1],
|
||||||
|
"Click should update frame interactivity state"
|
||||||
|
);
|
||||||
|
// And then navigate away.
|
||||||
|
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
||||||
|
await BrowserTestUtils.browserLoaded(browser);
|
||||||
}
|
}
|
||||||
let hasInteractedWith = await ContentTask.spawn(browser, "", function() {
|
);
|
||||||
return [content.document.userHasInteracted, content.frames[0].document.userHasInteracted];
|
|
||||||
});
|
|
||||||
is(shouldClick, hasInteractedWith[0], "Click should update parent interactivity state");
|
|
||||||
is(shouldClick, hasInteractedWith[1], "Click should update frame interactivity state");
|
|
||||||
// And then navigate away.
|
|
||||||
await BrowserTestUtils.loadURI(browser, "http://example.com/");
|
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,24 @@
|
||||||
// -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
|
// -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||||
// vim: set ts=2 sw=2 et tw=78:
|
// vim: set ts=2 sw=2 et tw=78:
|
||||||
function clearSelection(w)
|
function clearSelection(w) {
|
||||||
{
|
|
||||||
var sel = (w ? w : window).getSelection();
|
var sel = (w ? w : window).getSelection();
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNode(e, index) {
|
function getNode(e, index) {
|
||||||
if (!(typeof index==='number')) return index;
|
if (!(typeof index === "number")) {
|
||||||
if (index >= 0) return e.childNodes[index];
|
return index;
|
||||||
while (++index != 0) e = e.parentNode;
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
return e.childNodes[index];
|
||||||
|
}
|
||||||
|
while (++index != 0) {
|
||||||
|
e = e.parentNode;
|
||||||
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragSelectPointsWithData()
|
function dragSelectPointsWithData() {
|
||||||
{
|
|
||||||
var event = arguments[0];
|
var event = arguments[0];
|
||||||
var e = arguments[1];
|
var e = arguments[1];
|
||||||
var x1 = arguments[2];
|
var x1 = arguments[2];
|
||||||
|
|
@ -22,111 +26,111 @@ function dragSelectPointsWithData()
|
||||||
var x2 = arguments[4];
|
var x2 = arguments[4];
|
||||||
var y2 = arguments[5];
|
var y2 = arguments[5];
|
||||||
dir = x2 > x1 ? 1 : -1;
|
dir = x2 > x1 ? 1 : -1;
|
||||||
event['type'] = "mousedown";
|
event["type"] = "mousedown";
|
||||||
synthesizeMouse(e, x1, y1, event);
|
synthesizeMouse(e, x1, y1, event);
|
||||||
event['type'] = "mousemove";
|
event["type"] = "mousemove";
|
||||||
synthesizeMouse(e, x1 + dir, y1, event);
|
synthesizeMouse(e, x1 + dir, y1, event);
|
||||||
for (var i = 6; i < arguments.length; ++i)
|
for (var i = 6; i < arguments.length; ++i) {
|
||||||
synthesizeMouse(e, arguments[i], y1, event);
|
synthesizeMouse(e, arguments[i], y1, event);
|
||||||
|
}
|
||||||
synthesizeMouse(e, x2 - dir, y2, event);
|
synthesizeMouse(e, x2 - dir, y2, event);
|
||||||
event['type'] = "mouseup";
|
event["type"] = "mouseup";
|
||||||
synthesizeMouse(e, x2, y2, event);
|
synthesizeMouse(e, x2, y2, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragSelectPoints()
|
function dragSelectPoints() {
|
||||||
{
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
dragSelectPointsWithData.apply(this, [{}].concat(args));
|
dragSelectPointsWithData.apply(this, [{}].concat(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragSelect()
|
function dragSelect() {
|
||||||
{
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
var e = args.shift();
|
var e = args.shift();
|
||||||
var x1 = args.shift();
|
var x1 = args.shift();
|
||||||
var x2 = args.shift();
|
var x2 = args.shift();
|
||||||
dragSelectPointsWithData.apply(this, [{},e,x1,5,x2,5].concat(args));
|
dragSelectPointsWithData.apply(this, [{}, e, x1, 5, x2, 5].concat(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
function accelDragSelect()
|
function accelDragSelect() {
|
||||||
{
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
var e = args.shift();
|
var e = args.shift();
|
||||||
var x1 = args.shift();
|
var x1 = args.shift();
|
||||||
var x2 = args.shift();
|
var x2 = args.shift();
|
||||||
var y = args.length != 0 ? args.shift() : 5;
|
var y = args.length != 0 ? args.shift() : 5;
|
||||||
dragSelectPointsWithData.apply(this, [{accelKey: true},e,x1,y,x2,y].concat(args));
|
dragSelectPointsWithData.apply(
|
||||||
|
this,
|
||||||
|
[{ accelKey: true }, e, x1, y, x2, y].concat(args)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftClick(e, x, y)
|
function shiftClick(e, x, y) {
|
||||||
{
|
function pos(p) {
|
||||||
function pos(p) { return (typeof p === "undefined") ? 5 : p }
|
return typeof p === "undefined" ? 5 : p;
|
||||||
|
}
|
||||||
synthesizeMouse(e, pos(x), pos(y), { shiftKey: true });
|
synthesizeMouse(e, pos(x), pos(y), { shiftKey: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyRepeat(key,data,repeat)
|
function keyRepeat(key, data, repeat) {
|
||||||
{
|
while (repeat-- > 0) {
|
||||||
while (repeat-- > 0)
|
|
||||||
synthesizeKey(key, data);
|
synthesizeKey(key, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyRight(data)
|
function keyRight(data) {
|
||||||
{
|
|
||||||
var repeat = arguments.length > 1 ? arguments[1] : 1;
|
var repeat = arguments.length > 1 ? arguments[1] : 1;
|
||||||
keyRepeat("VK_RIGHT", data, repeat);
|
keyRepeat("VK_RIGHT", data, repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyLeft(data)
|
function keyLeft(data) {
|
||||||
{
|
|
||||||
var repeat = arguments.length > 1 ? arguments[1] : 1;
|
var repeat = arguments.length > 1 ? arguments[1] : 1;
|
||||||
keyRepeat("VK_LEFT", data, repeat);
|
keyRepeat("VK_LEFT", data, repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftAccelClick(e, x, y)
|
function shiftAccelClick(e, x, y) {
|
||||||
{
|
function pos(p) {
|
||||||
function pos(p) { return (typeof p === "undefined") ? 5 : p }
|
return typeof p === "undefined" ? 5 : p;
|
||||||
|
}
|
||||||
synthesizeMouse(e, pos(x), pos(y), { shiftKey: true, accelKey: true });
|
synthesizeMouse(e, pos(x), pos(y), { shiftKey: true, accelKey: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function accelClick(e, x, y)
|
function accelClick(e, x, y) {
|
||||||
{
|
function pos(p) {
|
||||||
function pos(p) { return (typeof p === "undefined") ? 5 : p }
|
return typeof p === "undefined" ? 5 : p;
|
||||||
|
}
|
||||||
synthesizeMouse(e, pos(x), pos(y), { accelKey: true });
|
synthesizeMouse(e, pos(x), pos(y), { accelKey: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChildRanges(arr, e)
|
function addChildRanges(arr, e) {
|
||||||
{
|
|
||||||
var sel = window.getSelection();
|
var sel = window.getSelection();
|
||||||
for (i = 0; i < arr.length; ++i) {
|
for (i = 0; i < arr.length; ++i) {
|
||||||
var data = arr[i];
|
var data = arr[i];
|
||||||
var r = new Range()
|
var r = new Range();
|
||||||
r.setStart(getNode(e, data[0]), data[1]);
|
r.setStart(getNode(e, data[0]), data[1]);
|
||||||
r.setEnd(getNode(e, data[2]), data[3]);
|
r.setEnd(getNode(e, data[2]), data[3]);
|
||||||
sel.addRange(r);
|
sel.addRange(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkText(text, e)
|
function checkText(text, e) {
|
||||||
{
|
|
||||||
var sel = window.getSelection();
|
var sel = window.getSelection();
|
||||||
is(sel.toString(), text, e.id + ": selected text")
|
is(sel.toString(), text, e.id + ": selected text");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRangeText(text, index)
|
function checkRangeText(text, index) {
|
||||||
{
|
|
||||||
var r = window.getSelection().getRangeAt(index);
|
var r = window.getSelection().getRangeAt(index);
|
||||||
is(r.toString(), text, e.id + ": range["+index+"].toString()")
|
is(r.toString(), text, e.id + ": range[" + index + "].toString()");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRangeCount(n, e)
|
function checkRangeCount(n, e) {
|
||||||
{
|
|
||||||
var sel = window.getSelection();
|
var sel = window.getSelection();
|
||||||
is(sel.rangeCount, n, e.id + ": Selection range count");
|
is(sel.rangeCount, n, e.id + ": Selection range count");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRangePoints(i, expected, e) {
|
function checkRangePoints(i, expected, e) {
|
||||||
var sel = window.getSelection();
|
var sel = window.getSelection();
|
||||||
if (i >= sel.rangeCount) return;
|
if (i >= sel.rangeCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var r = sel.getRangeAt(i);
|
var r = sel.getRangeAt(i);
|
||||||
is(r.startContainer, expected[0], e.id + ": range.startContainer");
|
is(r.startContainer, expected[0], e.id + ": range.startContainer");
|
||||||
is(r.startOffset, expected[1], e.id + ": range.startOffset");
|
is(r.startOffset, expected[1], e.id + ": range.startOffset");
|
||||||
|
|
@ -136,16 +140,25 @@ function checkRangePoints(i, expected, e) {
|
||||||
|
|
||||||
function checkRange(i, expected, e) {
|
function checkRange(i, expected, e) {
|
||||||
var sel = window.getSelection();
|
var sel = window.getSelection();
|
||||||
if (i >= sel.rangeCount) return;
|
if (i >= sel.rangeCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var r = sel.getRangeAt(i);
|
var r = sel.getRangeAt(i);
|
||||||
is(r.startContainer, getNode(e, expected[0]), e.id + ": range["+i+"].startContainer");
|
is(
|
||||||
is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset");
|
r.startContainer,
|
||||||
is(r.endContainer, getNode(e, expected[2]), e.id + ": range["+i+"].endContainer");
|
getNode(e, expected[0]),
|
||||||
is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset");
|
e.id + ": range[" + i + "].startContainer"
|
||||||
|
);
|
||||||
|
is(r.startOffset, expected[1], e.id + ": range[" + i + "].startOffset");
|
||||||
|
is(
|
||||||
|
r.endContainer,
|
||||||
|
getNode(e, expected[2]),
|
||||||
|
e.id + ": range[" + i + "].endContainer"
|
||||||
|
);
|
||||||
|
is(r.endOffset, expected[3], e.id + ": range[" + i + "].endOffset");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRanges(arr, e)
|
function checkRanges(arr, e) {
|
||||||
{
|
|
||||||
checkRangeCount(arr.length, e);
|
checkRangeCount(arr.length, e);
|
||||||
for (i = 0; i < arr.length; ++i) {
|
for (i = 0; i < arr.length; ++i) {
|
||||||
var expected = arr[i];
|
var expected = arr[i];
|
||||||
|
|
|
||||||
|
|
@ -1,163 +1,191 @@
|
||||||
var checkClipRegion, checkClipRegionForFrame, checkClipRegionNoBounds;
|
var checkClipRegion, checkClipRegionForFrame, checkClipRegionNoBounds;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var windowFrameX, windowFrameY;
|
var windowFrameX, windowFrameY;
|
||||||
|
|
||||||
// Import test API
|
// Import test API
|
||||||
var is = window.opener.is;
|
var is = window.opener.is;
|
||||||
var ok = window.opener.ok;
|
var ok = window.opener.ok;
|
||||||
var todo = window.opener.todo;
|
var todo = window.opener.todo;
|
||||||
var finish = window.opener.SimpleTest.finish;
|
var finish = window.opener.SimpleTest.finish;
|
||||||
window.onerror = function (event) { window.opener.onerror(event); window.close(); };
|
window.onerror = function(event) {
|
||||||
|
window.opener.onerror(event);
|
||||||
|
window.close();
|
||||||
|
};
|
||||||
|
|
||||||
function dumpRect(r) {
|
function dumpRect(r) {
|
||||||
return "{" + r.join(",") + "}";
|
return "{" + r.join(",") + "}";
|
||||||
}
|
|
||||||
|
|
||||||
function dumpRegion(rects) {
|
|
||||||
var s = [];
|
|
||||||
for (var i = 0; i < rects.length; ++i) {
|
|
||||||
var r = rects[i];
|
|
||||||
s.push(dumpRect(r));
|
|
||||||
}
|
}
|
||||||
return s.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateSpan(coords) {
|
function dumpRegion(rects) {
|
||||||
coords.sort(function(a,b) { return a - b; });
|
var s = [];
|
||||||
var result = [coords[0]];
|
for (var i = 0; i < rects.length; ++i) {
|
||||||
for (var i = 1; i < coords.length; ++i) {
|
var r = rects[i];
|
||||||
if (coords[i] != coords[i - 1]) {
|
s.push(dumpRect(r));
|
||||||
result.push(coords[i]);
|
|
||||||
}
|
}
|
||||||
|
return s.join(", ");
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function containsRect(r1, r2) {
|
function generateSpan(coords) {
|
||||||
return r1[0] <= r2[0] && r1[2] >= r2[2] &&
|
coords.sort(function(a, b) {
|
||||||
r1[1] <= r2[1] && r1[3] >= r2[3];
|
return a - b;
|
||||||
}
|
});
|
||||||
|
var result = [coords[0]];
|
||||||
|
for (var i = 1; i < coords.length; ++i) {
|
||||||
|
if (coords[i] != coords[i - 1]) {
|
||||||
|
result.push(coords[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function subtractRect(r1, r2, rlist) {
|
function containsRect(r1, r2) {
|
||||||
var spanX = generateSpan([r1[0], r1[2], r2[0], r2[2]]);
|
return r1[0] <= r2[0] && r1[2] >= r2[2] && r1[1] <= r2[1] && r1[3] >= r2[3];
|
||||||
var spanY = generateSpan([r1[1], r1[3], r2[1], r2[3]]);
|
}
|
||||||
for (var i = 1; i < spanX.length; ++i) {
|
|
||||||
for (var j = 1; j < spanY.length; ++j) {
|
function subtractRect(r1, r2, rlist) {
|
||||||
var subrect = [spanX[i - 1], spanY[j - 1], spanX[i], spanY[j]];
|
var spanX = generateSpan([r1[0], r1[2], r2[0], r2[2]]);
|
||||||
if (containsRect(r1, subrect) && !containsRect(r2, subrect)) {
|
var spanY = generateSpan([r1[1], r1[3], r2[1], r2[3]]);
|
||||||
rlist.push(subrect);
|
for (var i = 1; i < spanX.length; ++i) {
|
||||||
|
for (var j = 1; j < spanY.length; ++j) {
|
||||||
|
var subrect = [spanX[i - 1], spanY[j - 1], spanX[i], spanY[j]];
|
||||||
|
if (containsRect(r1, subrect) && !containsRect(r2, subrect)) {
|
||||||
|
rlist.push(subrect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function regionContainsRect(rs, r) {
|
function regionContainsRect(rs, r) {
|
||||||
var rectList = [r];
|
var rectList = [r];
|
||||||
for (var i = 0; i < rs.length; ++i) {
|
for (var i = 0; i < rs.length; ++i) {
|
||||||
var newList = [];
|
var newList = [];
|
||||||
for (var j = 0; j < rectList.length; ++j) {
|
for (var j = 0; j < rectList.length; ++j) {
|
||||||
subtractRect(rectList[j], rs[i], newList);
|
subtractRect(rectList[j], rs[i], newList);
|
||||||
|
}
|
||||||
|
if (newList.length == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
rectList = newList;
|
||||||
}
|
}
|
||||||
if (newList.length == 0)
|
return false;
|
||||||
return true;
|
|
||||||
rectList = newList;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function regionContains(r1s, r2s) {
|
|
||||||
for (var i = 0; i < r2s.length; ++i) {
|
|
||||||
if (!regionContainsRect(r1s, r2s[i]))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function equalRegions(r1s, r2s) {
|
|
||||||
return regionContains(r1s, r2s) && regionContains(r2s, r1s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks that a plugin's clip region equals the specified rectangle list.
|
|
||||||
// The rectangles are given relative to the plugin's top-left. They are in
|
|
||||||
// [left, top, right, bottom] format.
|
|
||||||
function checkClipRegionWithDoc(doc, offsetX, offsetY, id, rects, checkBounds) {
|
|
||||||
var p = doc.getElementById(id);
|
|
||||||
var bounds = p.getBoundingClientRect();
|
|
||||||
var pX = p.getEdge(0);
|
|
||||||
var pY = p.getEdge(1);
|
|
||||||
|
|
||||||
if (checkBounds) {
|
|
||||||
var pWidth = p.getEdge(2) - pX;
|
|
||||||
var pHeight = p.getEdge(3) - pY;
|
|
||||||
|
|
||||||
is(pX, windowFrameX + bounds.left + offsetX, id + " plugin X");
|
|
||||||
is(pY, windowFrameY + bounds.top + offsetY, id + " plugin Y");
|
|
||||||
is(pWidth, bounds.width, id + " plugin width");
|
|
||||||
is(pHeight, bounds.height, id + " plugin height");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check clip region. 'rects' is relative to the plugin's top-left.
|
function regionContains(r1s, r2s) {
|
||||||
var clipRects = [];
|
for (var i = 0; i < r2s.length; ++i) {
|
||||||
var n = p.getClipRegionRectCount();
|
if (!regionContainsRect(r1s, r2s[i])) {
|
||||||
for (var i = 0; i < n; ++i) {
|
return false;
|
||||||
// Convert the clip rect to be relative to the plugin's top-left.
|
}
|
||||||
clipRects[i] = [
|
}
|
||||||
p.getClipRegionRectEdge(i, 0) - pX,
|
return true;
|
||||||
p.getClipRegionRectEdge(i, 1) - pY,
|
|
||||||
p.getClipRegionRectEdge(i, 2) - pX,
|
|
||||||
p.getClipRegionRectEdge(i, 3) - pY
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(equalRegions(clipRects, rects), "Matching regions for '" + id +
|
function equalRegions(r1s, r2s) {
|
||||||
"': expected " + dumpRegion(rects) + ", got " + dumpRegion(clipRects));
|
return regionContains(r1s, r2s) && regionContains(r2s, r1s);
|
||||||
}
|
|
||||||
|
|
||||||
checkClipRegion = function(id, rects) {
|
|
||||||
checkClipRegionWithDoc(document, 0, 0, id, rects, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkClipRegionForFrame = function(fid, id, rects) {
|
|
||||||
var f = document.getElementById(fid);
|
|
||||||
var bounds = f.getBoundingClientRect();
|
|
||||||
checkClipRegionWithDoc(f.contentDocument, bounds.left, bounds.top, id, rects, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkClipRegionNoBounds = function(id, rects) {
|
|
||||||
checkClipRegionWithDoc(document, 0, 0, id, rects, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loaded() {
|
|
||||||
var h1 = document.getElementById("h1");
|
|
||||||
var h2 = document.getElementById("h2");
|
|
||||||
var hwidth = h2.screenX - h1.screenX;
|
|
||||||
if (hwidth != 100) {
|
|
||||||
// Maybe it's a DPI issue
|
|
||||||
todo(false, "Unexpected DPI?");
|
|
||||||
finish();
|
|
||||||
window.close();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!document.getElementById("p1").identifierToStringTest) {
|
// Checks that a plugin's clip region equals the specified rectangle list.
|
||||||
todo(false, "Test plugin not available");
|
// The rectangles are given relative to the plugin's top-left. They are in
|
||||||
finish();
|
// [left, top, right, bottom] format.
|
||||||
window.close();
|
function checkClipRegionWithDoc(
|
||||||
return;
|
doc,
|
||||||
|
offsetX,
|
||||||
|
offsetY,
|
||||||
|
id,
|
||||||
|
rects,
|
||||||
|
checkBounds
|
||||||
|
) {
|
||||||
|
var p = doc.getElementById(id);
|
||||||
|
var bounds = p.getBoundingClientRect();
|
||||||
|
var pX = p.getEdge(0);
|
||||||
|
var pY = p.getEdge(1);
|
||||||
|
|
||||||
|
if (checkBounds) {
|
||||||
|
var pWidth = p.getEdge(2) - pX;
|
||||||
|
var pHeight = p.getEdge(3) - pY;
|
||||||
|
|
||||||
|
is(pX, windowFrameX + bounds.left + offsetX, id + " plugin X");
|
||||||
|
is(pY, windowFrameY + bounds.top + offsetY, id + " plugin Y");
|
||||||
|
is(pWidth, bounds.width, id + " plugin width");
|
||||||
|
is(pHeight, bounds.height, id + " plugin height");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check clip region. 'rects' is relative to the plugin's top-left.
|
||||||
|
var clipRects = [];
|
||||||
|
var n = p.getClipRegionRectCount();
|
||||||
|
for (var i = 0; i < n; ++i) {
|
||||||
|
// Convert the clip rect to be relative to the plugin's top-left.
|
||||||
|
clipRects[i] = [
|
||||||
|
p.getClipRegionRectEdge(i, 0) - pX,
|
||||||
|
p.getClipRegionRectEdge(i, 1) - pY,
|
||||||
|
p.getClipRegionRectEdge(i, 2) - pX,
|
||||||
|
p.getClipRegionRectEdge(i, 3) - pY,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(
|
||||||
|
equalRegions(clipRects, rects),
|
||||||
|
"Matching regions for '" +
|
||||||
|
id +
|
||||||
|
"': expected " +
|
||||||
|
dumpRegion(rects) +
|
||||||
|
", got " +
|
||||||
|
dumpRegion(clipRects)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bounds = h1.getBoundingClientRect();
|
checkClipRegion = function(id, rects) {
|
||||||
windowFrameX = h1.screenX - bounds.left - window.screenX;
|
checkClipRegionWithDoc(document, 0, 0, id, rects, true);
|
||||||
windowFrameY = h1.screenY - bounds.top - window.screenY;
|
};
|
||||||
|
|
||||||
// Run actual test code
|
checkClipRegionForFrame = function(fid, id, rects) {
|
||||||
runTests();
|
var f = document.getElementById(fid);
|
||||||
}
|
var bounds = f.getBoundingClientRect();
|
||||||
|
checkClipRegionWithDoc(
|
||||||
|
f.contentDocument,
|
||||||
|
bounds.left,
|
||||||
|
bounds.top,
|
||||||
|
id,
|
||||||
|
rects,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Need to run 'loaded' after painting is unsuppressed, or we'll set clip
|
checkClipRegionNoBounds = function(id, rects) {
|
||||||
// regions to empty. The timeout must be non-zero on X11 so that
|
checkClipRegionWithDoc(document, 0, 0, id, rects, false);
|
||||||
// gtk_container_idle_sizer runs after the GtkSocket gets the plug_window.
|
};
|
||||||
window.addEventListener("load",
|
|
||||||
function () { setTimeout(loaded, 1000); });
|
function loaded() {
|
||||||
|
var h1 = document.getElementById("h1");
|
||||||
|
var h2 = document.getElementById("h2");
|
||||||
|
var hwidth = h2.screenX - h1.screenX;
|
||||||
|
if (hwidth != 100) {
|
||||||
|
// Maybe it's a DPI issue
|
||||||
|
todo(false, "Unexpected DPI?");
|
||||||
|
finish();
|
||||||
|
window.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!document.getElementById("p1").identifierToStringTest) {
|
||||||
|
todo(false, "Test plugin not available");
|
||||||
|
finish();
|
||||||
|
window.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bounds = h1.getBoundingClientRect();
|
||||||
|
windowFrameX = h1.screenX - bounds.left - window.screenX;
|
||||||
|
windowFrameY = h1.screenY - bounds.top - window.screenY;
|
||||||
|
|
||||||
|
// Run actual test code
|
||||||
|
runTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to run 'loaded' after painting is unsuppressed, or we'll set clip
|
||||||
|
// regions to empty. The timeout must be non-zero on X11 so that
|
||||||
|
// gtk_container_idle_sizer runs after the GtkSocket gets the plug_window.
|
||||||
|
window.addEventListener("load", function() {
|
||||||
|
setTimeout(loaded, 1000);
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -25,7 +25,7 @@ function advance_clock(milliseconds) {
|
||||||
if (gElem) {
|
if (gElem) {
|
||||||
ok(false, "test author forgot to call done_div/done_elem");
|
ok(false, "test author forgot to call done_div/done_elem");
|
||||||
}
|
}
|
||||||
if (typeof(style) != "string") {
|
if (typeof style != "string") {
|
||||||
ok(false, "test author forgot to pass argument");
|
ok(false, "test author forgot to pass argument");
|
||||||
}
|
}
|
||||||
if (!document.getElementById("display")) {
|
if (!document.getElementById("display")) {
|
||||||
|
|
@ -35,7 +35,7 @@ function advance_clock(milliseconds) {
|
||||||
gElem.setAttribute("style", style);
|
gElem.setAttribute("style", style);
|
||||||
gElem.classList.add("target");
|
gElem.classList.add("target");
|
||||||
document.getElementById("display").appendChild(gElem);
|
document.getElementById("display").appendChild(gElem);
|
||||||
return [ gElem, getComputedStyle(gElem, "") ];
|
return [gElem, getComputedStyle(gElem, "")];
|
||||||
}
|
}
|
||||||
|
|
||||||
function listen() {
|
function listen() {
|
||||||
|
|
@ -55,22 +55,41 @@ function advance_clock(milliseconds) {
|
||||||
// This function checks that the list of eventsExpected matches
|
// This function checks that the list of eventsExpected matches
|
||||||
// the received events -- but it only checks the properties that
|
// the received events -- but it only checks the properties that
|
||||||
// are present on eventsExpected.
|
// are present on eventsExpected.
|
||||||
is(gEventsReceived.length, eventsExpected.length,
|
is(
|
||||||
"number of events received for " + desc);
|
gEventsReceived.length,
|
||||||
for (var i = 0,
|
eventsExpected.length,
|
||||||
i_end = Math.min(eventsExpected.length, gEventsReceived.length);
|
"number of events received for " + desc
|
||||||
i != i_end; ++i) {
|
);
|
||||||
|
for (
|
||||||
|
var i = 0,
|
||||||
|
i_end = Math.min(eventsExpected.length, gEventsReceived.length);
|
||||||
|
i != i_end;
|
||||||
|
++i
|
||||||
|
) {
|
||||||
var exp = eventsExpected[i];
|
var exp = eventsExpected[i];
|
||||||
var rec = gEventsReceived[i];
|
var rec = gEventsReceived[i];
|
||||||
for (var prop in exp) {
|
for (var prop in exp) {
|
||||||
if (prop == "elapsedTime") {
|
if (prop == "elapsedTime") {
|
||||||
// Allow floating point error.
|
// Allow floating point error.
|
||||||
ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002,
|
ok(
|
||||||
"events[" + i + "]." + prop + " for " + desc +
|
Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002,
|
||||||
" received=" + rec.elapsedTime + " expected=" + exp.elapsedTime);
|
"events[" +
|
||||||
|
i +
|
||||||
|
"]." +
|
||||||
|
prop +
|
||||||
|
" for " +
|
||||||
|
desc +
|
||||||
|
" received=" +
|
||||||
|
rec.elapsedTime +
|
||||||
|
" expected=" +
|
||||||
|
exp.elapsedTime
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
is(rec[prop], exp[prop],
|
is(
|
||||||
"events[" + i + "]." + prop + " for " + desc);
|
rec[prop],
|
||||||
|
exp[prop],
|
||||||
|
"events[" + i + "]." + prop + " for " + desc
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,8 +101,11 @@ function advance_clock(milliseconds) {
|
||||||
|
|
||||||
function done_element() {
|
function done_element() {
|
||||||
if (!gElem) {
|
if (!gElem) {
|
||||||
ok(false, "test author called done_element/done_div without matching"
|
ok(
|
||||||
+ " call to new_element/new_div");
|
false,
|
||||||
|
"test author called done_element/done_div without matching" +
|
||||||
|
" call to new_element/new_div"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
gElem.remove();
|
gElem.remove();
|
||||||
gElem = null;
|
gElem = null;
|
||||||
|
|
@ -92,85 +114,90 @@ function advance_clock(milliseconds) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[ new_div
|
[new_div, new_element, listen, check_events, done_element].forEach(function(
|
||||||
, new_element
|
fn
|
||||||
, listen
|
) {
|
||||||
, check_events
|
|
||||||
, done_element ]
|
|
||||||
.forEach(function(fn) {
|
|
||||||
window[fn.name] = fn;
|
window[fn.name] = fn;
|
||||||
});
|
});
|
||||||
window.done_div = done_element;
|
window.done_div = done_element;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function px_to_num(str)
|
function px_to_num(str) {
|
||||||
{
|
return Number(String(str).match(/^([\d.]+)px$/)[1]);
|
||||||
return Number(String(str).match(/^([\d.]+)px$/)[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function bezier(x1, y1, x2, y2) {
|
function bezier(x1, y1, x2, y2) {
|
||||||
// Cubic bezier with control points (0, 0), (x1, y1), (x2, y2), and (1, 1).
|
// Cubic bezier with control points (0, 0), (x1, y1), (x2, y2), and (1, 1).
|
||||||
function x_for_t(t) {
|
function x_for_t(t) {
|
||||||
var omt = 1-t;
|
var omt = 1 - t;
|
||||||
return 3 * omt * omt * t * x1 + 3 * omt * t * t * x2 + t * t * t;
|
return 3 * omt * omt * t * x1 + 3 * omt * t * t * x2 + t * t * t;
|
||||||
|
}
|
||||||
|
function y_for_t(t) {
|
||||||
|
var omt = 1 - t;
|
||||||
|
return 3 * omt * omt * t * y1 + 3 * omt * t * t * y2 + t * t * t;
|
||||||
|
}
|
||||||
|
function t_for_x(x) {
|
||||||
|
// Binary subdivision.
|
||||||
|
var mint = 0,
|
||||||
|
maxt = 1;
|
||||||
|
for (var i = 0; i < 30; ++i) {
|
||||||
|
var guesst = (mint + maxt) / 2;
|
||||||
|
var guessx = x_for_t(guesst);
|
||||||
|
if (x < guessx) {
|
||||||
|
maxt = guesst;
|
||||||
|
} else {
|
||||||
|
mint = guesst;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function y_for_t(t) {
|
return (mint + maxt) / 2;
|
||||||
var omt = 1-t;
|
}
|
||||||
return 3 * omt * omt * t * y1 + 3 * omt * t * t * y2 + t * t * t;
|
return function bezier_closure(x) {
|
||||||
|
if (x == 0) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
function t_for_x(x) {
|
if (x == 1) {
|
||||||
// Binary subdivision.
|
return 1;
|
||||||
var mint = 0, maxt = 1;
|
|
||||||
for (var i = 0; i < 30; ++i) {
|
|
||||||
var guesst = (mint + maxt) / 2;
|
|
||||||
var guessx = x_for_t(guesst);
|
|
||||||
if (x < guessx)
|
|
||||||
maxt = guesst;
|
|
||||||
else
|
|
||||||
mint = guesst;
|
|
||||||
}
|
|
||||||
return (mint + maxt) / 2;
|
|
||||||
}
|
|
||||||
return function bezier_closure(x) {
|
|
||||||
if (x == 0) return 0;
|
|
||||||
if (x == 1) return 1;
|
|
||||||
return y_for_t(t_for_x(x));
|
|
||||||
}
|
}
|
||||||
|
return y_for_t(t_for_x(x));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function step_end(nsteps) {
|
function step_end(nsteps) {
|
||||||
return function step_end_closure(x) {
|
return function step_end_closure(x) {
|
||||||
return Math.floor(x * nsteps) / nsteps;
|
return Math.floor(x * nsteps) / nsteps;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function step_start(nsteps) {
|
function step_start(nsteps) {
|
||||||
var stepend = step_end(nsteps);
|
var stepend = step_end(nsteps);
|
||||||
return function step_start_closure(x) {
|
return function step_start_closure(x) {
|
||||||
return 1.0 - stepend(1.0 - x);
|
return 1.0 - stepend(1.0 - x);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var gTF = {
|
var gTF = {
|
||||||
"ease": bezier(0.25, 0.1, 0.25, 1),
|
ease: bezier(0.25, 0.1, 0.25, 1),
|
||||||
"linear": function(x) { return x; },
|
linear: function(x) {
|
||||||
"ease_in": bezier(0.42, 0, 1, 1),
|
return x;
|
||||||
"ease_out": bezier(0, 0, 0.58, 1),
|
},
|
||||||
"ease_in_out": bezier(0.42, 0, 0.58, 1),
|
ease_in: bezier(0.42, 0, 1, 1),
|
||||||
"step_start": step_start(1),
|
ease_out: bezier(0, 0, 0.58, 1),
|
||||||
"step_end": step_end(1),
|
ease_in_out: bezier(0.42, 0, 0.58, 1),
|
||||||
|
step_start: step_start(1),
|
||||||
|
step_end: step_end(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
function is_approx(float1, float2, error, desc) {
|
function is_approx(float1, float2, error, desc) {
|
||||||
ok(Math.abs(float1 - float2) < error,
|
ok(
|
||||||
desc + ": " + float1 + " and " + float2 + " should be within " + error);
|
Math.abs(float1 - float2) < error,
|
||||||
|
desc + ": " + float1 + " and " + float2 + " should be within " + error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findKeyframesRule(name) {
|
function findKeyframesRule(name) {
|
||||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||||
var match = [].find.call(document.styleSheets[i].cssRules, function(rule) {
|
var match = [].find.call(document.styleSheets[i].cssRules, function(rule) {
|
||||||
return rule.type == CSSRule.KEYFRAMES_RULE &&
|
return rule.type == CSSRule.KEYFRAMES_RULE && rule.name == name;
|
||||||
rule.name == name;
|
|
||||||
});
|
});
|
||||||
if (match) {
|
if (match) {
|
||||||
return match;
|
return match;
|
||||||
|
|
@ -197,42 +224,49 @@ function findKeyframesRule(name) {
|
||||||
// explicitly.
|
// explicitly.
|
||||||
function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
const OMTAPrefKey = "layers.offmainthreadcomposition.async-animations";
|
const OMTAPrefKey = "layers.offmainthreadcomposition.async-animations";
|
||||||
var utils = SpecialPowers.DOMWindowUtils;
|
var utils = SpecialPowers.DOMWindowUtils;
|
||||||
if (!specialPowersForPrefs) {
|
if (!specialPowersForPrefs) {
|
||||||
specialPowersForPrefs = SpecialPowers;
|
specialPowersForPrefs = SpecialPowers;
|
||||||
}
|
}
|
||||||
var expectOMTA = utils.layerManagerRemote &&
|
var expectOMTA =
|
||||||
// ^ Off-main thread animation cannot be used if off-main
|
utils.layerManagerRemote &&
|
||||||
// thread composition (OMTC) is not available
|
// ^ Off-main thread animation cannot be used if off-main
|
||||||
specialPowersForPrefs.getBoolPref(OMTAPrefKey);
|
// thread composition (OMTC) is not available
|
||||||
|
specialPowersForPrefs.getBoolPref(OMTAPrefKey);
|
||||||
|
|
||||||
isOMTAWorking().then(function(isWorking) {
|
isOMTAWorking()
|
||||||
if (expectOMTA) {
|
.then(function(isWorking) {
|
||||||
if (isWorking) {
|
if (expectOMTA) {
|
||||||
aTestFunction();
|
if (isWorking) {
|
||||||
|
aTestFunction();
|
||||||
|
} else {
|
||||||
|
// We only call this when we know it will fail as otherwise in the
|
||||||
|
// regular success case we will end up inflating the "passed tests"
|
||||||
|
// count by 1
|
||||||
|
ok(isWorking, "OMTA should work");
|
||||||
|
aOnSkip();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// We only call this when we know it will fail as otherwise in the
|
todo(
|
||||||
// regular success case we will end up inflating the "passed tests"
|
isWorking,
|
||||||
// count by 1
|
"OMTA should ideally work, though we don't expect it to work on " +
|
||||||
ok(isWorking, "OMTA should work");
|
"this platform/configuration"
|
||||||
|
);
|
||||||
aOnSkip();
|
aOnSkip();
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
todo(isWorking,
|
.catch(function(err) {
|
||||||
"OMTA should ideally work, though we don't expect it to work on " +
|
ok(false, err);
|
||||||
"this platform/configuration");
|
|
||||||
aOnSkip();
|
aOnSkip();
|
||||||
}
|
});
|
||||||
}).catch(function(err) {
|
|
||||||
ok(false, err);
|
|
||||||
aOnSkip();
|
|
||||||
});
|
|
||||||
|
|
||||||
function isOMTAWorking() {
|
function isOMTAWorking() {
|
||||||
// Create keyframes rule
|
// Create keyframes rule
|
||||||
const animationName = "a6ce3091ed85"; // Random name to avoid clashes
|
const animationName = "a6ce3091ed85"; // Random name to avoid clashes
|
||||||
var ruleText = "@keyframes " + animationName +
|
var ruleText =
|
||||||
" { from { opacity: 0.5 } to { opacity: 0.5 } }";
|
"@keyframes " +
|
||||||
|
animationName +
|
||||||
|
" { from { opacity: 0.5 } to { opacity: 0.5 } }";
|
||||||
var style = document.createElement("style");
|
var style = document.createElement("style");
|
||||||
style.appendChild(document.createTextNode(ruleText));
|
style.appendChild(document.createTextNode(ruleText));
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
|
|
@ -242,7 +276,7 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
|
|
||||||
// Give the target geometry so it is eligible for layerization
|
// Give the target geometry so it is eligible for layerization
|
||||||
div.style.width = "100px";
|
div.style.width = "100px";
|
||||||
div.style.height = "100px";
|
div.style.height = "100px";
|
||||||
div.style.backgroundColor = "white";
|
div.style.backgroundColor = "white";
|
||||||
|
|
||||||
|
|
@ -264,15 +298,18 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
// notifications.
|
// notifications.
|
||||||
utils.advanceTimeAndRefresh(0);
|
utils.advanceTimeAndRefresh(0);
|
||||||
return waitForPaintsFlushed();
|
return waitForPaintsFlushed();
|
||||||
}).then(function() {
|
})
|
||||||
|
.then(function() {
|
||||||
div.style.animation = animationName + " 10s";
|
div.style.animation = animationName + " 10s";
|
||||||
|
|
||||||
return waitForPaintsFlushed();
|
return waitForPaintsFlushed();
|
||||||
}).then(function() {
|
})
|
||||||
|
.then(function() {
|
||||||
var opacity = utils.getOMTAStyle(div, "opacity");
|
var opacity = utils.getOMTAStyle(div, "opacity");
|
||||||
cleanUp();
|
cleanUp();
|
||||||
return Promise.resolve(opacity == 0.5);
|
return Promise.resolve(opacity == 0.5);
|
||||||
}).catch(function(err) {
|
})
|
||||||
|
.catch(function(err) {
|
||||||
cleanUp();
|
cleanUp();
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
});
|
});
|
||||||
|
|
@ -290,7 +327,7 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
|
|
||||||
function loadPaintListener() {
|
function loadPaintListener() {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
if (typeof(window.waitForAllPaints) !== "function") {
|
if (typeof window.waitForAllPaints !== "function") {
|
||||||
var script = document.createElement("script");
|
var script = document.createElement("script");
|
||||||
script.onload = resolve;
|
script.onload = resolve;
|
||||||
script.onerror = function() {
|
script.onerror = function() {
|
||||||
|
|
@ -329,10 +366,10 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
// runAsyncAnimTest returns a Promise that is resolved when the
|
// runAsyncAnimTest returns a Promise that is resolved when the
|
||||||
// test is finished so we can chain them together
|
// test is finished so we can chain them together
|
||||||
return tests.reduce(function(sequence, test) {
|
return tests.reduce(function(sequence, test) {
|
||||||
return sequence.then(function() {
|
return sequence.then(function() {
|
||||||
return runAsyncAnimTest(test, aOnAbort);
|
return runAsyncAnimTest(test, aOnAbort);
|
||||||
});
|
});
|
||||||
}, Promise.resolve() /* the start of the sequence */);
|
}, Promise.resolve() /* the start of the sequence */);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Takes a generator function that represents a test case. Each point in the
|
// Takes a generator function that represents a test case. Each point in the
|
||||||
|
|
@ -359,8 +396,9 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
if (next.done) {
|
if (next.done) {
|
||||||
return Promise.resolve(next.value);
|
return Promise.resolve(next.value);
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(next.value)
|
return Promise.resolve(next.value).then(step, function(err) {
|
||||||
.then(step, function(err) { throw err; });
|
throw err;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,15 +411,17 @@ function runOMTATest(aTestFunction, aOnSkip, specialPowersForPrefs) {
|
||||||
generator = promise;
|
generator = promise;
|
||||||
promise = step();
|
promise = step();
|
||||||
}
|
}
|
||||||
return promise.catch(function(err) {
|
return promise
|
||||||
ok(false, err.message);
|
.catch(function(err) {
|
||||||
if (typeof aOnAbort == "function") {
|
ok(false, err.message);
|
||||||
aOnAbort();
|
if (typeof aOnAbort == "function") {
|
||||||
}
|
aOnAbort();
|
||||||
}).then(function() {
|
}
|
||||||
// Restore clock
|
})
|
||||||
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
.then(function() {
|
||||||
});
|
// Restore clock
|
||||||
|
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
@ -395,36 +435,70 @@ const RunningOn = {
|
||||||
MainThread: 0,
|
MainThread: 0,
|
||||||
Compositor: 1,
|
Compositor: 1,
|
||||||
Either: 2,
|
Either: 2,
|
||||||
TodoMainThread: 3
|
TodoMainThread: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ExpectComparisonTo = {
|
const ExpectComparisonTo = {
|
||||||
Pass: 1,
|
Pass: 1,
|
||||||
Fail: 2
|
Fail: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
window.omta_todo_is = function(elem, property, expected, runningOn, desc,
|
window.omta_todo_is = function(
|
||||||
pseudo) {
|
elem,
|
||||||
return omta_is_approx(elem, property, expected, 0, runningOn, desc,
|
property,
|
||||||
ExpectComparisonTo.Fail, pseudo);
|
expected,
|
||||||
|
runningOn,
|
||||||
|
desc,
|
||||||
|
pseudo
|
||||||
|
) {
|
||||||
|
return omta_is_approx(
|
||||||
|
elem,
|
||||||
|
property,
|
||||||
|
expected,
|
||||||
|
0,
|
||||||
|
runningOn,
|
||||||
|
desc,
|
||||||
|
ExpectComparisonTo.Fail,
|
||||||
|
pseudo
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.omta_is = function(elem, property, expected, runningOn, desc,
|
window.omta_is = function(elem, property, expected, runningOn, desc, pseudo) {
|
||||||
pseudo) {
|
return omta_is_approx(
|
||||||
return omta_is_approx(elem, property, expected, 0, runningOn, desc,
|
elem,
|
||||||
ExpectComparisonTo.Pass, pseudo);
|
property,
|
||||||
|
expected,
|
||||||
|
0,
|
||||||
|
runningOn,
|
||||||
|
desc,
|
||||||
|
ExpectComparisonTo.Pass,
|
||||||
|
pseudo
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Many callers of this method will pass 'undefined' for
|
// Many callers of this method will pass 'undefined' for
|
||||||
// expectedComparisonResult.
|
// expectedComparisonResult.
|
||||||
window.omta_is_approx = function(elem, property, expected, tolerance,
|
window.omta_is_approx = function(
|
||||||
runningOn, desc, expectedComparisonResult,
|
elem,
|
||||||
pseudo) {
|
property,
|
||||||
|
expected,
|
||||||
|
tolerance,
|
||||||
|
runningOn,
|
||||||
|
desc,
|
||||||
|
expectedComparisonResult,
|
||||||
|
pseudo
|
||||||
|
) {
|
||||||
// Check input
|
// Check input
|
||||||
// FIXME: Auto generate this array.
|
// FIXME: Auto generate this array.
|
||||||
const omtaProperties = [ "transform", "translate", "rotate", "scale",
|
const omtaProperties = [
|
||||||
"opacity", "background-color" ];
|
"transform",
|
||||||
|
"translate",
|
||||||
|
"rotate",
|
||||||
|
"scale",
|
||||||
|
"opacity",
|
||||||
|
"background-color",
|
||||||
|
];
|
||||||
if (!omtaProperties.includes(property)) {
|
if (!omtaProperties.includes(property)) {
|
||||||
ok(false, property + " is not an OMTA property");
|
ok(false, property + " is not an OMTA property");
|
||||||
return;
|
return;
|
||||||
|
|
@ -443,11 +517,15 @@ const ExpectComparisonTo = {
|
||||||
break;
|
break;
|
||||||
case "opacity":
|
case "opacity":
|
||||||
normalize = parseFloat;
|
normalize = parseFloat;
|
||||||
compare = function(a, b, error) { return Math.abs(a - b) <= error; };
|
compare = function(a, b, error) {
|
||||||
|
return Math.abs(a - b) <= error;
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
normalize = value => value;
|
normalize = value => value;
|
||||||
compare = function(a, b, error) { return a == b; };
|
compare = function(a, b, error) {
|
||||||
|
return a == b;
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,15 +538,23 @@ const ExpectComparisonTo = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get actual values
|
// Get actual values
|
||||||
var compositorStr =
|
var compositorStr = SpecialPowers.DOMWindowUtils.getOMTAStyle(
|
||||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(elem, property, pseudo);
|
elem,
|
||||||
|
property,
|
||||||
|
pseudo
|
||||||
|
);
|
||||||
var computedStr = window.getComputedStyle(elem, pseudo)[property];
|
var computedStr = window.getComputedStyle(elem, pseudo)[property];
|
||||||
|
|
||||||
// Prepare expected value
|
// Prepare expected value
|
||||||
var expectedValue = normalize(expected);
|
var expectedValue = normalize(expected);
|
||||||
if (expectedValue === null) {
|
if (expectedValue === null) {
|
||||||
ok(false, desc + ": test author should provide a valid 'expected' value" +
|
ok(
|
||||||
" - got " + expected.toString());
|
false,
|
||||||
|
desc +
|
||||||
|
": test author should provide a valid 'expected' value" +
|
||||||
|
" - got " +
|
||||||
|
expected.toString()
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -476,9 +562,8 @@ const ExpectComparisonTo = {
|
||||||
var actualStr;
|
var actualStr;
|
||||||
switch (runningOn) {
|
switch (runningOn) {
|
||||||
case RunningOn.Either:
|
case RunningOn.Either:
|
||||||
runningOn = compositorStr !== "" ?
|
runningOn =
|
||||||
RunningOn.Compositor :
|
compositorStr !== "" ? RunningOn.Compositor : RunningOn.MainThread;
|
||||||
RunningOn.MainThread;
|
|
||||||
actualStr = compositorStr !== "" ? compositorStr : computedStr;
|
actualStr = compositorStr !== "" ? compositorStr : computedStr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -491,8 +576,10 @@ const ExpectComparisonTo = {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RunningOn.TodoMainThread:
|
case RunningOn.TodoMainThread:
|
||||||
todo(compositorStr === "",
|
todo(
|
||||||
desc + ": should NOT be animating on compositor");
|
compositorStr === "",
|
||||||
|
desc + ": should NOT be animating on compositor"
|
||||||
|
);
|
||||||
actualStr = compositorStr === "" ? computedStr : compositorStr;
|
actualStr = compositorStr === "" ? computedStr : compositorStr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -505,9 +592,8 @@ const ExpectComparisonTo = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var okOrTodo = expectedComparisonResult == ExpectComparisonTo.Fail ?
|
var okOrTodo =
|
||||||
todo :
|
expectedComparisonResult == ExpectComparisonTo.Fail ? todo : ok;
|
||||||
ok;
|
|
||||||
|
|
||||||
// Compare animated value with expected
|
// Compare animated value with expected
|
||||||
var actualValue = normalize(actualStr);
|
var actualValue = normalize(actualStr);
|
||||||
|
|
@ -515,9 +601,14 @@ const ExpectComparisonTo = {
|
||||||
ok(false, desc + ": should return a valid result - got " + actualStr);
|
ok(false, desc + ": should return a valid result - got " + actualStr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
okOrTodo(compare(expectedValue, actualValue, tolerance),
|
okOrTodo(
|
||||||
desc + " - got " + actualStr + ", expected " +
|
compare(expectedValue, actualValue, tolerance),
|
||||||
normalizedToString(expectedValue));
|
desc +
|
||||||
|
" - got " +
|
||||||
|
actualStr +
|
||||||
|
", expected " +
|
||||||
|
normalizedToString(expectedValue)
|
||||||
|
);
|
||||||
|
|
||||||
// For transform-like properties, if we have multiple transform-like
|
// For transform-like properties, if we have multiple transform-like
|
||||||
// properties, the OMTA value and getComputedStyle() must be different,
|
// properties, the OMTA value and getComputedStyle() must be different,
|
||||||
|
|
@ -532,7 +623,7 @@ const ExpectComparisonTo = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof expected.computed !== 'undefined') {
|
if (typeof expected.computed !== "undefined") {
|
||||||
// For some tests we specify a separate computed value for comparing
|
// For some tests we specify a separate computed value for comparing
|
||||||
// with getComputedStyle.
|
// with getComputedStyle.
|
||||||
//
|
//
|
||||||
|
|
@ -547,21 +638,33 @@ const ExpectComparisonTo = {
|
||||||
// result of getComputedStyle since it will help to alert us if some
|
// result of getComputedStyle since it will help to alert us if some
|
||||||
// discrepancy arises between the way we calculate values on the main
|
// discrepancy arises between the way we calculate values on the main
|
||||||
// thread and compositor.
|
// thread and compositor.
|
||||||
okOrTodo(computedStr == expected.computed,
|
okOrTodo(
|
||||||
desc + ": Computed style should be equal to " +
|
computedStr == expected.computed,
|
||||||
expected.computed);
|
desc + ": Computed style should be equal to " + expected.computed
|
||||||
|
);
|
||||||
} else if (actualStr === compositorStr) {
|
} else if (actualStr === compositorStr) {
|
||||||
// For compositor animations do an additional check that they match
|
// For compositor animations do an additional check that they match
|
||||||
// the value calculated on the main thread
|
// the value calculated on the main thread
|
||||||
var computedValue = normalize(computedStr);
|
var computedValue = normalize(computedStr);
|
||||||
if (computedValue === null) {
|
if (computedValue === null) {
|
||||||
ok(false, desc + ": test framework should parse computed style" +
|
ok(
|
||||||
" - got " + computedStr);
|
false,
|
||||||
|
desc +
|
||||||
|
": test framework should parse computed style" +
|
||||||
|
" - got " +
|
||||||
|
computedStr
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
okOrTodo(compare(computedValue, actualValue, 0.0),
|
okOrTodo(
|
||||||
desc + ": OMTA style and computed style should be equal" +
|
compare(computedValue, actualValue, 0.0),
|
||||||
" - OMTA " + actualStr + ", computed " + computedStr);
|
desc +
|
||||||
|
": OMTA style and computed style should be equal" +
|
||||||
|
" - OMTA " +
|
||||||
|
actualStr +
|
||||||
|
", computed " +
|
||||||
|
computedStr
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -570,8 +673,9 @@ const ExpectComparisonTo = {
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
for (var j = 0; j < 4; j++) {
|
for (var j = 0; j < 4; j++) {
|
||||||
var diff = Math.abs(a[i][j] - b[i][j]);
|
var diff = Math.abs(a[i][j] - b[i][j]);
|
||||||
if (diff > tolerance || isNaN(diff))
|
if (diff > tolerance || isNaN(diff)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -585,11 +689,11 @@ const ExpectComparisonTo = {
|
||||||
// [ 1, 0, 0, ... ]
|
// [ 1, 0, 0, ... ]
|
||||||
// { a: 1, ty: 23 } etc.
|
// { a: 1, ty: 23 } etc.
|
||||||
window.convertTo3dMatrix = function(matrixLike) {
|
window.convertTo3dMatrix = function(matrixLike) {
|
||||||
if (typeof(matrixLike) == "string") {
|
if (typeof matrixLike == "string") {
|
||||||
return convertStringTo3dMatrix(matrixLike);
|
return convertStringTo3dMatrix(matrixLike);
|
||||||
} else if (Array.isArray(matrixLike)) {
|
} else if (Array.isArray(matrixLike)) {
|
||||||
return convertArrayTo3dMatrix(matrixLike);
|
return convertArrayTo3dMatrix(matrixLike);
|
||||||
} else if (typeof(matrixLike) == "object") {
|
} else if (typeof matrixLike == "object") {
|
||||||
return convertObjectTo3dMatrix(matrixLike);
|
return convertObjectTo3dMatrix(matrixLike);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -605,19 +709,22 @@ const ExpectComparisonTo = {
|
||||||
// Converts strings of the format "matrix(...)" and "matrix3d(...)" to a 3d
|
// Converts strings of the format "matrix(...)" and "matrix3d(...)" to a 3d
|
||||||
// matrix
|
// matrix
|
||||||
function convertStringTo3dMatrix(str) {
|
function convertStringTo3dMatrix(str) {
|
||||||
if (str == "none")
|
if (str == "none") {
|
||||||
return convertArrayTo3dMatrix([1, 0, 0, 1, 0, 0]);
|
return convertArrayTo3dMatrix([1, 0, 0, 1, 0, 0]);
|
||||||
|
}
|
||||||
var result = str.match("^matrix(3d)?\\(");
|
var result = str.match("^matrix(3d)?\\(");
|
||||||
if (result === null)
|
if (result === null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return convertArrayTo3dMatrix(
|
return convertArrayTo3dMatrix(
|
||||||
str.substring(result[0].length, str.length-1)
|
str
|
||||||
.split(",")
|
.substring(result[0].length, str.length - 1)
|
||||||
.map(function(component) {
|
.split(",")
|
||||||
return Number(component);
|
.map(function(component) {
|
||||||
})
|
return Number(component);
|
||||||
);
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes an array of numbers of length 6 (2d matrix) or 16 (3d matrix)
|
// Takes an array of numbers of length 6 (2d matrix) or 16 (3d matrix)
|
||||||
|
|
@ -625,16 +732,20 @@ const ExpectComparisonTo = {
|
||||||
// matrix represented as an array of arrays
|
// matrix represented as an array of arrays
|
||||||
function convertArrayTo3dMatrix(array) {
|
function convertArrayTo3dMatrix(array) {
|
||||||
if (array.length == 6) {
|
if (array.length == 6) {
|
||||||
return convertObjectTo3dMatrix(
|
return convertObjectTo3dMatrix({
|
||||||
{ a: array[0], b: array[1],
|
a: array[0],
|
||||||
c: array[2], d: array[3],
|
b: array[1],
|
||||||
e: array[4], f: array[5] } );
|
c: array[2],
|
||||||
|
d: array[3],
|
||||||
|
e: array[4],
|
||||||
|
f: array[5],
|
||||||
|
});
|
||||||
} else if (array.length == 16) {
|
} else if (array.length == 16) {
|
||||||
return [
|
return [
|
||||||
array.slice(0, 4),
|
array.slice(0, 4),
|
||||||
array.slice(4, 8),
|
array.slice(4, 8),
|
||||||
array.slice(8, 12),
|
array.slice(8, 12),
|
||||||
array.slice(12, 16)
|
array.slice(12, 16),
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -643,7 +754,7 @@ const ExpectComparisonTo = {
|
||||||
|
|
||||||
// Return the first defined value in args.
|
// Return the first defined value in args.
|
||||||
function defined(...args) {
|
function defined(...args) {
|
||||||
return args.find(arg => typeof arg !== 'undefined');
|
return args.find(arg => typeof arg !== "undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes an object of the form { a: 1.1, e: 23 } and builds up a 3d matrix
|
// Takes an object of the form { a: 1.1, e: 23 } and builds up a 3d matrix
|
||||||
|
|
@ -654,46 +765,64 @@ const ExpectComparisonTo = {
|
||||||
defined(obj.a, obj.sx, obj.m11, 1),
|
defined(obj.a, obj.sx, obj.m11, 1),
|
||||||
obj.b || obj.m12 || 0,
|
obj.b || obj.m12 || 0,
|
||||||
obj.m13 || 0,
|
obj.m13 || 0,
|
||||||
obj.m14 || 0
|
obj.m14 || 0,
|
||||||
], [
|
],
|
||||||
|
[
|
||||||
obj.c || obj.m21 || 0,
|
obj.c || obj.m21 || 0,
|
||||||
defined(obj.d, obj.sy, obj.m22, 1),
|
defined(obj.d, obj.sy, obj.m22, 1),
|
||||||
obj.m23 || 0,
|
obj.m23 || 0,
|
||||||
obj.m24 || 0
|
obj.m24 || 0,
|
||||||
], [
|
],
|
||||||
obj.m31 || 0,
|
[obj.m31 || 0, obj.m32 || 0, defined(obj.sz, obj.m33, 1), obj.m34 || 0],
|
||||||
obj.m32 || 0,
|
[
|
||||||
defined(obj.sz, obj.m33, 1),
|
|
||||||
obj.m34 || 0
|
|
||||||
], [
|
|
||||||
obj.e || obj.tx || obj.m41 || 0,
|
obj.e || obj.tx || obj.m41 || 0,
|
||||||
obj.f || obj.ty || obj.m42 || 0,
|
obj.f || obj.ty || obj.m42 || 0,
|
||||||
obj.tz || obj.m43 || 0,
|
obj.tz || obj.m43 || 0,
|
||||||
defined(obj.m44, 1),
|
defined(obj.m44, 1),
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function convert3dMatrixToString(matrix) {
|
function convert3dMatrixToString(matrix) {
|
||||||
if (is2d(matrix)) {
|
if (is2d(matrix)) {
|
||||||
return "matrix(" +
|
return (
|
||||||
[ matrix[0][0], matrix[0][1],
|
"matrix(" +
|
||||||
matrix[1][0], matrix[1][1],
|
[
|
||||||
matrix[3][0], matrix[3][1] ].join(", ") + ")";
|
matrix[0][0],
|
||||||
|
matrix[0][1],
|
||||||
|
matrix[1][0],
|
||||||
|
matrix[1][1],
|
||||||
|
matrix[3][0],
|
||||||
|
matrix[3][1],
|
||||||
|
].join(", ") +
|
||||||
|
")"
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return "matrix3d(" +
|
return (
|
||||||
matrix.reduce(function(outer, inner) {
|
"matrix3d(" +
|
||||||
return outer.concat(inner);
|
matrix
|
||||||
}).join(", ") + ")";
|
.reduce(function(outer, inner) {
|
||||||
|
return outer.concat(inner);
|
||||||
|
})
|
||||||
|
.join(", ") +
|
||||||
|
")"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function is2d(matrix) {
|
function is2d(matrix) {
|
||||||
return matrix[0][2] === 0 && matrix[0][3] === 0 &&
|
return (
|
||||||
matrix[1][2] === 0 && matrix[1][3] === 0 &&
|
matrix[0][2] === 0 &&
|
||||||
matrix[2][0] === 0 && matrix[2][1] === 0 &&
|
matrix[0][3] === 0 &&
|
||||||
matrix[2][2] === 1 && matrix[2][3] === 0 &&
|
matrix[1][2] === 0 &&
|
||||||
matrix[3][2] === 0 && matrix[3][3] === 1;
|
matrix[1][3] === 0 &&
|
||||||
|
matrix[2][0] === 0 &&
|
||||||
|
matrix[2][1] === 0 &&
|
||||||
|
matrix[2][2] === 1 &&
|
||||||
|
matrix[2][3] === 0 &&
|
||||||
|
matrix[3][2] === 0 &&
|
||||||
|
matrix[3][3] === 1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDeterminant(matrix) {
|
function getDeterminant(matrix) {
|
||||||
|
|
@ -701,30 +830,32 @@ const ExpectComparisonTo = {
|
||||||
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
|
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0]
|
return (
|
||||||
- matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0]
|
matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] -
|
||||||
- matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0]
|
matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] -
|
||||||
+ matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0]
|
matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] +
|
||||||
+ matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0]
|
matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
|
||||||
- matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0]
|
matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] -
|
||||||
- matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1]
|
matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
|
||||||
+ matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1]
|
matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] +
|
||||||
+ matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1]
|
matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
|
||||||
- matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1]
|
matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] -
|
||||||
- matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1]
|
matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
|
||||||
+ matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1]
|
matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] +
|
||||||
+ matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2]
|
matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
|
||||||
- matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2]
|
matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] -
|
||||||
- matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2]
|
matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
|
||||||
+ matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2]
|
matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] +
|
||||||
+ matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2]
|
matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
|
||||||
- matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2]
|
matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] -
|
||||||
- matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3]
|
matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
|
||||||
+ matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3]
|
matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] +
|
||||||
+ matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3]
|
matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
|
||||||
- matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3]
|
matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] -
|
||||||
- matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3]
|
matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
|
||||||
+ matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
|
matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] +
|
||||||
|
matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
@ -750,9 +881,13 @@ function waitForPaintsFlushed() {
|
||||||
|
|
||||||
function waitForVisitedLinkColoring(visitedLink, waitProperty, waitValue) {
|
function waitForVisitedLinkColoring(visitedLink, waitProperty, waitValue) {
|
||||||
function checkLink(resolve) {
|
function checkLink(resolve) {
|
||||||
if (SpecialPowers.DOMWindowUtils
|
if (
|
||||||
.getVisitedDependentComputedStyle(visitedLink, "", waitProperty) ==
|
SpecialPowers.DOMWindowUtils.getVisitedDependentComputedStyle(
|
||||||
waitValue) {
|
visitedLink,
|
||||||
|
"",
|
||||||
|
waitProperty
|
||||||
|
) == waitValue
|
||||||
|
) {
|
||||||
// Our link has been styled as visited. Resolve.
|
// Our link has been styled as visited. Resolve.
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
let uri = getRootDirectory(gTestPath) + "bug453896_iframe.html";
|
let uri = getRootDirectory(gTestPath) + "bug453896_iframe.html";
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({
|
await BrowserTestUtils.withNewTab(
|
||||||
gBrowser,
|
{
|
||||||
url: uri
|
gBrowser,
|
||||||
}, function(browser) {
|
url: uri,
|
||||||
return ContentTask.spawn(browser, null, async function() {
|
},
|
||||||
var fake_window = { ok: ok };
|
function(browser) {
|
||||||
content.wrappedJSObject.run(fake_window);
|
return ContentTask.spawn(browser, null, async function() {
|
||||||
});
|
var fake_window = { ok: ok };
|
||||||
});
|
content.wrappedJSObject.run(fake_window);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,40 @@ add_task(async function() {
|
||||||
let uri = "http://example.com/browser/layout/style/test/sourcemap_css.html";
|
let uri = "http://example.com/browser/layout/style/test/sourcemap_css.html";
|
||||||
info(`URI is ${uri}`);
|
info(`URI is ${uri}`);
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({
|
await BrowserTestUtils.withNewTab(
|
||||||
gBrowser,
|
{
|
||||||
url: uri
|
gBrowser,
|
||||||
}, async function(browser) {
|
url: uri,
|
||||||
await ContentTask.spawn(browser, null, function* () {
|
},
|
||||||
let seenSheets = 0;
|
async function(browser) {
|
||||||
|
await ContentTask.spawn(browser, null, function*() {
|
||||||
|
let seenSheets = 0;
|
||||||
|
|
||||||
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
||||||
let sheet = content.document.styleSheets[i];
|
let sheet = content.document.styleSheets[i];
|
||||||
|
|
||||||
info(`Checking ${sheet.href}`);
|
info(`Checking ${sheet.href}`);
|
||||||
if (/mapped\.css/.test(sheet.href)) {
|
if (/mapped\.css/.test(sheet.href)) {
|
||||||
is(sheet.sourceMapURL, "mapped.css.map", "X-SourceMap header took effect");
|
is(
|
||||||
seenSheets |= 1;
|
sheet.sourceMapURL,
|
||||||
} else if (/mapped2\.css/.test(sheet.href)) {
|
"mapped.css.map",
|
||||||
is(sheet.sourceMapURL, "mapped2.css.map", "SourceMap header took effect");
|
"X-SourceMap header took effect"
|
||||||
seenSheets |= 2;
|
);
|
||||||
} else {
|
seenSheets |= 1;
|
||||||
ok(false, "sheet does not have source map URL");
|
} else if (/mapped2\.css/.test(sheet.href)) {
|
||||||
|
is(
|
||||||
|
sheet.sourceMapURL,
|
||||||
|
"mapped2.css.map",
|
||||||
|
"SourceMap header took effect"
|
||||||
|
);
|
||||||
|
seenSheets |= 2;
|
||||||
|
} else {
|
||||||
|
ok(false, "sheet does not have source map URL");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
is(seenSheets, 3, "seen all source-mapped sheets");
|
is(seenSheets, 3, "seen all source-mapped sheets");
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,24 +17,33 @@ add_task(async function() {
|
||||||
|
|
||||||
let page = "<!DOCTYPE HTML>\n<html>\n<head>\n";
|
let page = "<!DOCTYPE HTML>\n<html>\n<head>\n";
|
||||||
for (let i = 0; i < test_cases.length; ++i) {
|
for (let i = 0; i < test_cases.length; ++i) {
|
||||||
page += `<style type="text/css"> #x${i} { color: red; }${test_cases[i][0]}</style>\n`;
|
page += `<style type="text/css"> #x${i} { color: red; }${
|
||||||
|
test_cases[i][0]
|
||||||
|
}</style>\n`;
|
||||||
}
|
}
|
||||||
page += "</head><body>some text</body></html>";
|
page += "</head><body>some text</body></html>";
|
||||||
|
|
||||||
let uri = "data:text/html;base64," + btoa(page);
|
let uri = "data:text/html;base64," + btoa(page);
|
||||||
info(`URI is ${uri}`);
|
info(`URI is ${uri}`);
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({
|
await BrowserTestUtils.withNewTab(
|
||||||
gBrowser,
|
{
|
||||||
url: uri
|
gBrowser,
|
||||||
}, async function(browser) {
|
url: uri,
|
||||||
await ContentTask.spawn(browser, test_cases, function* (tests) {
|
},
|
||||||
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
async function(browser) {
|
||||||
let sheet = content.document.styleSheets[i];
|
await ContentTask.spawn(browser, test_cases, function*(tests) {
|
||||||
|
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
||||||
|
let sheet = content.document.styleSheets[i];
|
||||||
|
|
||||||
info(`Checking sheet #${i}`);
|
info(`Checking sheet #${i}`);
|
||||||
is(sheet.sourceMapURL, tests[i][1], `correct source map for sheet ${i}`);
|
is(
|
||||||
}
|
sheet.sourceMapURL,
|
||||||
});
|
tests[i][1],
|
||||||
});
|
`correct source map for sheet ${i}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,24 +17,29 @@ add_task(async function() {
|
||||||
|
|
||||||
let page = "<!DOCTYPE HTML>\n<html>\n<head>\n";
|
let page = "<!DOCTYPE HTML>\n<html>\n<head>\n";
|
||||||
for (let i = 0; i < test_cases.length; ++i) {
|
for (let i = 0; i < test_cases.length; ++i) {
|
||||||
page += `<style type="text/css"> #x${i} { color: red; }${test_cases[i][0]}</style>\n`;
|
page += `<style type="text/css"> #x${i} { color: red; }${
|
||||||
|
test_cases[i][0]
|
||||||
|
}</style>\n`;
|
||||||
}
|
}
|
||||||
page += "</head><body>some text</body></html>";
|
page += "</head><body>some text</body></html>";
|
||||||
|
|
||||||
let uri = "data:text/html;base64," + btoa(page);
|
let uri = "data:text/html;base64," + btoa(page);
|
||||||
info(`URI is ${uri}`);
|
info(`URI is ${uri}`);
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({
|
await BrowserTestUtils.withNewTab(
|
||||||
gBrowser,
|
{
|
||||||
url: uri
|
gBrowser,
|
||||||
}, async function(browser) {
|
url: uri,
|
||||||
await ContentTask.spawn(browser, test_cases, function* (tests) {
|
},
|
||||||
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
async function(browser) {
|
||||||
let sheet = content.document.styleSheets[i];
|
await ContentTask.spawn(browser, test_cases, function*(tests) {
|
||||||
|
for (let i = 0; i < content.document.styleSheets.length; ++i) {
|
||||||
|
let sheet = content.document.styleSheets[i];
|
||||||
|
|
||||||
info(`Checking sheet #${i}`);
|
info(`Checking sheet #${i}`);
|
||||||
is(sheet.sourceURL, tests[i][1], `correct source URL for sheet ${i}`);
|
is(sheet.sourceURL, tests[i][1], `correct source URL for sheet ${i}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,26 +16,38 @@ var expected_values = [
|
||||||
["color", null, 8],
|
["color", null, 8],
|
||||||
["color-index", null, 0],
|
["color-index", null, 0],
|
||||||
["aspect-ratio", null, window.innerWidth + "/" + window.innerHeight],
|
["aspect-ratio", null, window.innerWidth + "/" + window.innerHeight],
|
||||||
["device-aspect-ratio", screen.width + "/" + screen.height,
|
[
|
||||||
window.innerWidth + "/" + window.innerHeight],
|
"device-aspect-ratio",
|
||||||
|
screen.width + "/" + screen.height,
|
||||||
|
window.innerWidth + "/" + window.innerHeight,
|
||||||
|
],
|
||||||
["device-height", screen.height + "px", window.innerHeight + "px"],
|
["device-height", screen.height + "px", window.innerHeight + "px"],
|
||||||
["device-width", screen.width + "px", window.innerWidth + "px"],
|
["device-width", screen.width + "px", window.innerWidth + "px"],
|
||||||
["grid", null, 0],
|
["grid", null, 0],
|
||||||
["height", window.innerHeight + "px", window.innerHeight + "px"],
|
["height", window.innerHeight + "px", window.innerHeight + "px"],
|
||||||
["monochrome", null, 0],
|
["monochrome", null, 0],
|
||||||
// Square is defined as portrait:
|
// Square is defined as portrait:
|
||||||
["orientation", null,
|
[
|
||||||
window.innerWidth > window.innerHeight ?
|
"orientation",
|
||||||
"landscape" : "portrait"],
|
null,
|
||||||
|
window.innerWidth > window.innerHeight ? "landscape" : "portrait",
|
||||||
|
],
|
||||||
["resolution", null, "96dpi"],
|
["resolution", null, "96dpi"],
|
||||||
["resolution", [0.999 * window.devicePixelRatio + "dppx",
|
[
|
||||||
1.001 * window.devicePixelRatio + "dppx"], "1dppx"],
|
"resolution",
|
||||||
|
[
|
||||||
|
0.999 * window.devicePixelRatio + "dppx",
|
||||||
|
1.001 * window.devicePixelRatio + "dppx",
|
||||||
|
],
|
||||||
|
"1dppx",
|
||||||
|
],
|
||||||
["width", window.innerWidth + "px", window.innerWidth + "px"],
|
["width", window.innerWidth + "px", window.innerWidth + "px"],
|
||||||
["-moz-device-pixel-ratio", window.devicePixelRatio, 1],
|
["-moz-device-pixel-ratio", window.devicePixelRatio, 1],
|
||||||
["-moz-device-orientation", screen.width > screen.height ?
|
[
|
||||||
"landscape" : "portrait",
|
"-moz-device-orientation",
|
||||||
window.innerWidth > window.innerHeight ?
|
screen.width > screen.height ? "landscape" : "portrait",
|
||||||
"landscape" : "portrait"]
|
window.innerWidth > window.innerHeight ? "landscape" : "portrait",
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// These media queries return value 0 or 1 when the pref is off.
|
// These media queries return value 0 or 1 when the pref is off.
|
||||||
|
|
@ -43,7 +55,7 @@ var expected_values = [
|
||||||
var suppressed_toggles = [
|
var suppressed_toggles = [
|
||||||
"-moz-mac-graphite-theme",
|
"-moz-mac-graphite-theme",
|
||||||
// Not available on most OSs.
|
// Not available on most OSs.
|
||||||
// "-moz-maemo-classic",
|
// "-moz-maemo-classic",
|
||||||
"-moz-scrollbar-end-backward",
|
"-moz-scrollbar-end-backward",
|
||||||
"-moz-scrollbar-end-forward",
|
"-moz-scrollbar-end-forward",
|
||||||
"-moz-scrollbar-start-backward",
|
"-moz-scrollbar-start-backward",
|
||||||
|
|
@ -62,16 +74,10 @@ var suppressed_toggles = [
|
||||||
"-moz-gtk-csd-reversed-placement",
|
"-moz-gtk-csd-reversed-placement",
|
||||||
];
|
];
|
||||||
|
|
||||||
var toggles_enabled_in_content = [
|
var toggles_enabled_in_content = ["-moz-touch-enabled"];
|
||||||
"-moz-touch-enabled",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Possible values for '-moz-os-version'
|
// Possible values for '-moz-os-version'
|
||||||
var windows_versions = [
|
var windows_versions = ["windows-win7", "windows-win8", "windows-win10"];
|
||||||
"windows-win7",
|
|
||||||
"windows-win8",
|
|
||||||
"windows-win10",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Read the current OS.
|
// Read the current OS.
|
||||||
var OS = SpecialPowers.Services.appinfo.OS;
|
var OS = SpecialPowers.Services.appinfo.OS;
|
||||||
|
|
@ -84,18 +90,22 @@ if (OS === "WINNT") {
|
||||||
|
|
||||||
// __keyValMatches(key, val)__.
|
// __keyValMatches(key, val)__.
|
||||||
// Runs a media query and returns true if key matches to val.
|
// Runs a media query and returns true if key matches to val.
|
||||||
var keyValMatches = (key, val) => matchMedia("(" + key + ":" + val +")").matches;
|
var keyValMatches = (key, val) =>
|
||||||
|
matchMedia("(" + key + ":" + val + ")").matches;
|
||||||
|
|
||||||
// __testMatch(key, val)__.
|
// __testMatch(key, val)__.
|
||||||
// Attempts to run a media query match for the given key and value.
|
// Attempts to run a media query match for the given key and value.
|
||||||
// If value is an array of two elements [min max], then matches any
|
// If value is an array of two elements [min max], then matches any
|
||||||
// value in-between.
|
// value in-between.
|
||||||
var testMatch = function (key, val) {
|
var testMatch = function(key, val) {
|
||||||
if (val === null) {
|
if (val === null) {
|
||||||
return;
|
return;
|
||||||
} else if (Array.isArray(val)) {
|
} else if (Array.isArray(val)) {
|
||||||
ok(keyValMatches("min-" + key, val[0]) && keyValMatches("max-" + key, val[1]),
|
ok(
|
||||||
"Expected " + key + " between " + val[0] + " and " + val[1]);
|
keyValMatches("min-" + key, val[0]) &&
|
||||||
|
keyValMatches("max-" + key, val[1]),
|
||||||
|
"Expected " + key + " between " + val[0] + " and " + val[1]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
ok(keyValMatches(key, val), "Expected " + key + ":" + val);
|
ok(keyValMatches(key, val), "Expected " + key + ":" + val);
|
||||||
}
|
}
|
||||||
|
|
@ -103,26 +113,28 @@ var testMatch = function (key, val) {
|
||||||
|
|
||||||
// __testToggles(resisting)__.
|
// __testToggles(resisting)__.
|
||||||
// Test whether we are able to match the "toggle" media queries.
|
// Test whether we are able to match the "toggle" media queries.
|
||||||
var testToggles = function (resisting) {
|
var testToggles = function(resisting) {
|
||||||
suppressed_toggles.forEach(
|
suppressed_toggles.forEach(function(key) {
|
||||||
function (key) {
|
var exists = keyValMatches(key, 0) || keyValMatches(key, 1);
|
||||||
var exists = keyValMatches(key, 0) || keyValMatches(key, 1);
|
if (!toggles_enabled_in_content.includes(key) && !is_chrome_window) {
|
||||||
if (!toggles_enabled_in_content.includes(key) && !is_chrome_window) {
|
ok(!exists, key + " should not exist.");
|
||||||
ok(!exists, key + " should not exist.");
|
} else {
|
||||||
} else {
|
ok(exists, key + " should exist.");
|
||||||
ok(exists, key + " should exist.");
|
if (resisting) {
|
||||||
if (resisting) {
|
ok(
|
||||||
ok(keyValMatches(key, 0) && !keyValMatches(key, 1), "Should always match as false");
|
keyValMatches(key, 0) && !keyValMatches(key, 1),
|
||||||
}
|
"Should always match as false"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// __testWindowsSpecific__.
|
// __testWindowsSpecific__.
|
||||||
// Runs a media query on the queryName with the given possible matching values.
|
// Runs a media query on the queryName with the given possible matching values.
|
||||||
var testWindowsSpecific = function (resisting, queryName, possibleValues) {
|
var testWindowsSpecific = function(resisting, queryName, possibleValues) {
|
||||||
let foundValue = null;
|
let foundValue = null;
|
||||||
possibleValues.forEach(function (val) {
|
possibleValues.forEach(function(val) {
|
||||||
if (keyValMatches(queryName, val)) {
|
if (keyValMatches(queryName, val)) {
|
||||||
foundValue = val;
|
foundValue = val;
|
||||||
}
|
}
|
||||||
|
|
@ -130,8 +142,12 @@ var testWindowsSpecific = function (resisting, queryName, possibleValues) {
|
||||||
if (resisting || !is_chrome_window) {
|
if (resisting || !is_chrome_window) {
|
||||||
ok(!foundValue, queryName + " should have no match");
|
ok(!foundValue, queryName + " should have no match");
|
||||||
} else {
|
} else {
|
||||||
ok(foundValue, foundValue ? ("Match found: '" + queryName + ":" + foundValue + "'")
|
ok(
|
||||||
: "Should have a match for '" + queryName + "'");
|
foundValue,
|
||||||
|
foundValue
|
||||||
|
? "Match found: '" + queryName + ":" + foundValue + "'"
|
||||||
|
: "Should have a match for '" + queryName + "'"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -139,27 +155,25 @@ var testWindowsSpecific = function (resisting, queryName, possibleValues) {
|
||||||
// Create a series of div elements that look like:
|
// Create a series of div elements that look like:
|
||||||
// `<div class='spoof' id='resolution'>resolution</div>`,
|
// `<div class='spoof' id='resolution'>resolution</div>`,
|
||||||
// where each line corresponds to a different media query.
|
// where each line corresponds to a different media query.
|
||||||
var generateHtmlLines = function (resisting) {
|
var generateHtmlLines = function(resisting) {
|
||||||
let fragment = document.createDocumentFragment();
|
let fragment = document.createDocumentFragment();
|
||||||
expected_values.forEach(
|
expected_values.forEach(function([key, offVal, onVal]) {
|
||||||
function ([key, offVal, onVal]) {
|
let val = resisting ? onVal : offVal;
|
||||||
let val = resisting ? onVal : offVal;
|
if (val) {
|
||||||
if (val) {
|
|
||||||
let div = document.createElementNS(HTML_NS, "div");
|
|
||||||
div.setAttribute("class", "spoof");
|
|
||||||
div.setAttribute("id", key);
|
|
||||||
div.textContent = key;
|
|
||||||
fragment.appendChild(div);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
suppressed_toggles.forEach(
|
|
||||||
function (key) {
|
|
||||||
let div = document.createElementNS(HTML_NS, "div");
|
let div = document.createElementNS(HTML_NS, "div");
|
||||||
div.setAttribute("class", "suppress");
|
div.setAttribute("class", "spoof");
|
||||||
div.setAttribute("id", key);
|
div.setAttribute("id", key);
|
||||||
div.textContent = key;
|
div.textContent = key;
|
||||||
fragment.appendChild(div);
|
fragment.appendChild(div);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
suppressed_toggles.forEach(function(key) {
|
||||||
|
let div = document.createElementNS(HTML_NS, "div");
|
||||||
|
div.setAttribute("class", "suppress");
|
||||||
|
div.setAttribute("id", key);
|
||||||
|
div.textContent = key;
|
||||||
|
fragment.appendChild(div);
|
||||||
|
});
|
||||||
if (OS === "WINNT") {
|
if (OS === "WINNT") {
|
||||||
let div = document.createElementNS(HTML_NS, "div");
|
let div = document.createElementNS(HTML_NS, "div");
|
||||||
div.setAttribute("class", "windows");
|
div.setAttribute("class", "windows");
|
||||||
|
|
@ -173,23 +187,32 @@ var generateHtmlLines = function (resisting) {
|
||||||
// __cssLine__.
|
// __cssLine__.
|
||||||
// Creates a line of css that looks something like
|
// Creates a line of css that looks something like
|
||||||
// `@media (resolution: 1ppx) { .spoof#resolution { background-color: green; } }`.
|
// `@media (resolution: 1ppx) { .spoof#resolution { background-color: green; } }`.
|
||||||
var cssLine = function (query, clazz, id, color) {
|
var cssLine = function(query, clazz, id, color) {
|
||||||
return "@media " + query + " { ." + clazz + "#" + id +
|
return (
|
||||||
" { background-color: " + color + "; } }\n";
|
"@media " +
|
||||||
|
query +
|
||||||
|
" { ." +
|
||||||
|
clazz +
|
||||||
|
"#" +
|
||||||
|
id +
|
||||||
|
" { background-color: " +
|
||||||
|
color +
|
||||||
|
"; } }\n"
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// __constructQuery(key, val)__.
|
// __constructQuery(key, val)__.
|
||||||
// Creates a CSS media query from key and val. If key is an array of
|
// Creates a CSS media query from key and val. If key is an array of
|
||||||
// two elements, constructs a range query (using min- and max-).
|
// two elements, constructs a range query (using min- and max-).
|
||||||
var constructQuery = function (key, val) {
|
var constructQuery = function(key, val) {
|
||||||
return Array.isArray(val) ?
|
return Array.isArray(val)
|
||||||
"(min-" + key + ": " + val[0] + ") and (max-" + key + ": " + val[1] + ")" :
|
? "(min-" + key + ": " + val[0] + ") and (max-" + key + ": " + val[1] + ")"
|
||||||
"(" + key + ": " + val + ")";
|
: "(" + key + ": " + val + ")";
|
||||||
};
|
};
|
||||||
|
|
||||||
// __mediaQueryCSSLine(key, val, color)__.
|
// __mediaQueryCSSLine(key, val, color)__.
|
||||||
// Creates a line containing a CSS media query and a CSS expression.
|
// Creates a line containing a CSS media query and a CSS expression.
|
||||||
var mediaQueryCSSLine = function (key, val, color) {
|
var mediaQueryCSSLine = function(key, val, color) {
|
||||||
if (val === null) {
|
if (val === null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +222,7 @@ var mediaQueryCSSLine = function (key, val, color) {
|
||||||
// __suppressedMediaQueryCSSLine(key, color)__.
|
// __suppressedMediaQueryCSSLine(key, color)__.
|
||||||
// Creates a CSS line that matches the existence of a
|
// Creates a CSS line that matches the existence of a
|
||||||
// media query that is supposed to be suppressed.
|
// media query that is supposed to be suppressed.
|
||||||
var suppressedMediaQueryCSSLine = function (key, color, suppressed) {
|
var suppressedMediaQueryCSSLine = function(key, color, suppressed) {
|
||||||
let query = "(" + key + ": 0), (" + key + ": 1)";
|
let query = "(" + key + ": 0), (" + key + ": 1)";
|
||||||
return cssLine(query, "suppress", key, color);
|
return cssLine(query, "suppress", key, color);
|
||||||
};
|
};
|
||||||
|
|
@ -208,25 +231,32 @@ var suppressedMediaQueryCSSLine = function (key, color, suppressed) {
|
||||||
// Creates a series of lines of CSS, each of which corresponds to
|
// Creates a series of lines of CSS, each of which corresponds to
|
||||||
// a different media query. If the query produces a match to the
|
// a different media query. If the query produces a match to the
|
||||||
// expected value, then the element will be colored green.
|
// expected value, then the element will be colored green.
|
||||||
var generateCSSLines = function (resisting) {
|
var generateCSSLines = function(resisting) {
|
||||||
let lines = ".spoof { background-color: red;}\n";
|
let lines = ".spoof { background-color: red;}\n";
|
||||||
expected_values.forEach(
|
expected_values.forEach(function([key, offVal, onVal]) {
|
||||||
function ([key, offVal, onVal]) {
|
lines += mediaQueryCSSLine(key, resisting ? onVal : offVal, "green");
|
||||||
lines += mediaQueryCSSLine(key, resisting ? onVal : offVal, "green");
|
});
|
||||||
});
|
lines +=
|
||||||
lines += ".suppress { background-color: " + (resisting ? "green" : "red") + ";}\n";
|
".suppress { background-color: " + (resisting ? "green" : "red") + ";}\n";
|
||||||
suppressed_toggles.forEach(
|
suppressed_toggles.forEach(function(key) {
|
||||||
function (key) {
|
if (
|
||||||
if (!toggles_enabled_in_content.includes(key) && !resisting && !is_chrome_window) {
|
!toggles_enabled_in_content.includes(key) &&
|
||||||
lines += "#" + key + " { background-color: green; }\n";
|
!resisting &&
|
||||||
} else {
|
!is_chrome_window
|
||||||
lines += suppressedMediaQueryCSSLine(key, "green");
|
) {
|
||||||
}
|
lines += "#" + key + " { background-color: green; }\n";
|
||||||
});
|
} else {
|
||||||
|
lines += suppressedMediaQueryCSSLine(key, "green");
|
||||||
|
}
|
||||||
|
});
|
||||||
if (OS === "WINNT") {
|
if (OS === "WINNT") {
|
||||||
lines += ".windows { background-color: " + (resisting ? "green" : "red") + ";}\n";
|
lines +=
|
||||||
lines += windows_versions.map(val => "(-moz-os-version: " + val + ")").join(", ") +
|
".windows { background-color: " + (resisting ? "green" : "red") + ";}\n";
|
||||||
" { #-moz-os-version { background-color: " + (resisting ? "red" : "green") + ";} }\n";
|
lines +=
|
||||||
|
windows_versions.map(val => "(-moz-os-version: " + val + ")").join(", ") +
|
||||||
|
" { #-moz-os-version { background-color: " +
|
||||||
|
(resisting ? "red" : "green") +
|
||||||
|
";} }\n";
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
};
|
};
|
||||||
|
|
@ -239,7 +269,7 @@ var green = "rgb(0, 128, 0)";
|
||||||
// Creates a series of divs and CSS using media queries to set their
|
// Creates a series of divs and CSS using media queries to set their
|
||||||
// background color. If all media queries match as expected, then
|
// background color. If all media queries match as expected, then
|
||||||
// all divs should have a green background color.
|
// all divs should have a green background color.
|
||||||
var testCSS = function (resisting) {
|
var testCSS = function(resisting) {
|
||||||
document.getElementById("display").appendChild(generateHtmlLines(resisting));
|
document.getElementById("display").appendChild(generateHtmlLines(resisting));
|
||||||
document.getElementById("test-css").textContent = generateCSSLines(resisting);
|
document.getElementById("test-css").textContent = generateCSSLines(resisting);
|
||||||
let cssTestDivs = document.querySelectorAll(".spoof,.suppress");
|
let cssTestDivs = document.querySelectorAll(".spoof,.suppress");
|
||||||
|
|
@ -252,20 +282,26 @@ var testCSS = function (resisting) {
|
||||||
// __testOSXFontSmoothing(resisting)__.
|
// __testOSXFontSmoothing(resisting)__.
|
||||||
// When fingerprinting resistance is enabled, the `getComputedStyle`
|
// When fingerprinting resistance is enabled, the `getComputedStyle`
|
||||||
// should always return `undefined` for `MozOSXFontSmoothing`.
|
// should always return `undefined` for `MozOSXFontSmoothing`.
|
||||||
var testOSXFontSmoothing = function (resisting) {
|
var testOSXFontSmoothing = function(resisting) {
|
||||||
let div = document.createElementNS(HTML_NS, "div");
|
let div = document.createElementNS(HTML_NS, "div");
|
||||||
div.style.MozOsxFontSmoothing = "unset";
|
div.style.MozOsxFontSmoothing = "unset";
|
||||||
document.documentElement.appendChild(div);
|
document.documentElement.appendChild(div);
|
||||||
let readBack = window.getComputedStyle(div).MozOsxFontSmoothing;
|
let readBack = window.getComputedStyle(div).MozOsxFontSmoothing;
|
||||||
div.remove();
|
div.remove();
|
||||||
let smoothingPref = SpecialPowers.getBoolPref("layout.css.osx-font-smoothing.enabled", false);
|
let smoothingPref = SpecialPowers.getBoolPref(
|
||||||
is(readBack, resisting ? "" : (smoothingPref ? "auto" : ""),
|
"layout.css.osx-font-smoothing.enabled",
|
||||||
"-moz-osx-font-smoothing");
|
false
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
readBack,
|
||||||
|
resisting ? "" : smoothingPref ? "auto" : "",
|
||||||
|
"-moz-osx-font-smoothing"
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// __sleep(timeoutMs)__.
|
// __sleep(timeoutMs)__.
|
||||||
// Returns a promise that resolves after the given timeout.
|
// Returns a promise that resolves after the given timeout.
|
||||||
var sleep = function (timeoutMs) {
|
var sleep = function(timeoutMs) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
window.setTimeout(resolve);
|
window.setTimeout(resolve);
|
||||||
});
|
});
|
||||||
|
|
@ -282,7 +318,10 @@ var testMediaQueriesInPictureElements = async function(resisting) {
|
||||||
let query = constructQuery(key, expected);
|
let query = constructQuery(key, expected);
|
||||||
|
|
||||||
let source = document.createElementNS(HTML_NS, "source");
|
let source = document.createElementNS(HTML_NS, "source");
|
||||||
source.setAttribute("srcset", "/tests/layout/style/test/chrome/match.png");
|
source.setAttribute(
|
||||||
|
"srcset",
|
||||||
|
"/tests/layout/style/test/chrome/match.png"
|
||||||
|
);
|
||||||
source.setAttribute("media", query);
|
source.setAttribute("media", query);
|
||||||
|
|
||||||
let image = document.createElementNS(HTML_NS, "img");
|
let image = document.createElementNS(HTML_NS, "img");
|
||||||
|
|
@ -299,16 +338,19 @@ var testMediaQueriesInPictureElements = async function(resisting) {
|
||||||
var testImages = document.getElementsByClassName("testImage");
|
var testImages = document.getElementsByClassName("testImage");
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
for (let testImage of testImages) {
|
for (let testImage of testImages) {
|
||||||
ok(testImage.currentSrc.endsWith("/match.png"), "Media query '" + testImage.title + "' in picture should match.");
|
ok(
|
||||||
|
testImage.currentSrc.endsWith("/match.png"),
|
||||||
|
"Media query '" + testImage.title + "' in picture should match."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// __pushPref(key, value)__.
|
// __pushPref(key, value)__.
|
||||||
// Set a pref value asynchronously, returning a promise that resolves
|
// Set a pref value asynchronously, returning a promise that resolves
|
||||||
// when it succeeds.
|
// when it succeeds.
|
||||||
var pushPref = function (key, value) {
|
var pushPref = function(key, value) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
SpecialPowers.pushPrefEnv({"set": [[key, value]]}, resolve);
|
SpecialPowers.pushPrefEnv({ set: [[key, value]] }, resolve);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -318,10 +360,9 @@ var test = async function(isContent) {
|
||||||
for (prefValue of [false, true]) {
|
for (prefValue of [false, true]) {
|
||||||
await pushPref("privacy.resistFingerprinting", prefValue);
|
await pushPref("privacy.resistFingerprinting", prefValue);
|
||||||
let resisting = prefValue && isContent;
|
let resisting = prefValue && isContent;
|
||||||
expected_values.forEach(
|
expected_values.forEach(function([key, offVal, onVal]) {
|
||||||
function ([key, offVal, onVal]) {
|
testMatch(key, resisting ? onVal : offVal);
|
||||||
testMatch(key, resisting ? onVal : offVal);
|
});
|
||||||
});
|
|
||||||
testToggles(resisting);
|
testToggles(resisting);
|
||||||
if (OS === "WINNT") {
|
if (OS === "WINNT") {
|
||||||
testWindowsSpecific(resisting, "-moz-os-version", windows_versions);
|
testWindowsSpecific(resisting, "-moz-os-version", windows_versions);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1 @@
|
||||||
var gShorthandPropertiesLikeLonghand = [
|
var gShorthandPropertiesLikeLonghand = [{ name: "overflow", prop: "overflow" }];
|
||||||
{ name: "overflow", prop: "overflow"},
|
|
||||||
];
|
|
||||||
|
|
|
||||||
|
|
@ -11,67 +11,132 @@
|
||||||
// should be rejected.
|
// should be rejected.
|
||||||
|
|
||||||
var gCSSFontFaceDescriptors = {
|
var gCSSFontFaceDescriptors = {
|
||||||
"font-family": {
|
"font-family": {
|
||||||
domProp: "fontFamily",
|
domProp: "fontFamily",
|
||||||
values: [ "\"serif\"", "\"cursive\"", "seriff", "Times New Roman", "TimesRoman", "\"Times New Roman\"" ],
|
values: [
|
||||||
/* not clear that the generics are really invalid */
|
'"serif"',
|
||||||
invalid_values: [ "sans-serif", "Times New Roman, serif", "'Times New Roman', serif", "cursive", "fantasy", "Times )", "Times !", "Times ! foo", "Times ! important" ]
|
'"cursive"',
|
||||||
},
|
"seriff",
|
||||||
"font-stretch": {
|
"Times New Roman",
|
||||||
domProp: "fontStretch",
|
"TimesRoman",
|
||||||
values: [ "normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" ],
|
'"Times New Roman"',
|
||||||
invalid_values: [ "wider", "narrower", "normal ! important", "normal )" ]
|
],
|
||||||
},
|
/* not clear that the generics are really invalid */
|
||||||
"font-style": {
|
invalid_values: [
|
||||||
domProp: "fontStyle",
|
"sans-serif",
|
||||||
values: [ "normal", "italic", "oblique" ],
|
"Times New Roman, serif",
|
||||||
invalid_values: []
|
"'Times New Roman', serif",
|
||||||
},
|
"cursive",
|
||||||
"font-weight": {
|
"fantasy",
|
||||||
domProp: "fontWeight",
|
"Times )",
|
||||||
values: [
|
"Times !",
|
||||||
"normal", "400", "bold", "100", "200", "300", "500", "600",
|
"Times ! foo",
|
||||||
"700", "800", "900", "107", "399", "401", "699", "710",
|
"Times ! important",
|
||||||
"calc(1001)", "calc(100 + 1)", "calc(1)", "100.6", "99",
|
],
|
||||||
"700 900", "300.4 500.4", "calc(200.4) calc(400.4)",
|
},
|
||||||
],
|
"font-stretch": {
|
||||||
invalid_values: [ "bolder", "lighter", "1001", "0", "0 100", "100 1001" ]
|
domProp: "fontStretch",
|
||||||
},
|
values: [
|
||||||
"src": {
|
"normal",
|
||||||
domProp: null,
|
"ultra-condensed",
|
||||||
values: [
|
"extra-condensed",
|
||||||
"url(404.ttf)",
|
"condensed",
|
||||||
"url(\"404.eot\")",
|
"semi-condensed",
|
||||||
"url(\'404.otf\')",
|
"semi-expanded",
|
||||||
"url(404.ttf) format(\"truetype\")",
|
"expanded",
|
||||||
"url(404.ttf) format(\"truetype\", \"opentype\")",
|
"extra-expanded",
|
||||||
"url(404.ttf) format(\"truetype\", \"opentype\"), url(\'404.eot\')",
|
"ultra-expanded",
|
||||||
"local(Times New Roman)",
|
],
|
||||||
"local(\'Times New Roman\')",
|
invalid_values: ["wider", "narrower", "normal ! important", "normal )"],
|
||||||
"local(\"Times New Roman\")",
|
},
|
||||||
"local(\"serif\")",
|
"font-style": {
|
||||||
"url(404.ttf) format(\"truetype\", \"unknown\"), local(Times New Roman), url(\'404.eot\')",
|
domProp: "fontStyle",
|
||||||
],
|
values: ["normal", "italic", "oblique"],
|
||||||
invalid_values: [
|
invalid_values: [],
|
||||||
"url(404.ttf) format(truetype)",
|
},
|
||||||
"url(404.ttf) format(\"truetype\" \"opentype\")",
|
"font-weight": {
|
||||||
"url(404.ttf) format(\"truetype\",)",
|
domProp: "fontWeight",
|
||||||
"local(\"Times New\" Roman)",
|
values: [
|
||||||
"local(serif)", /* is this valid? */
|
"normal",
|
||||||
"url(404.ttf) )",
|
"400",
|
||||||
"url(404.ttf) ) foo",
|
"bold",
|
||||||
"url(404.ttf) ! important",
|
"100",
|
||||||
"url(404.ttf) ! hello",
|
"200",
|
||||||
]
|
"300",
|
||||||
},
|
"500",
|
||||||
"unicode-range": {
|
"600",
|
||||||
domProp: null,
|
"700",
|
||||||
values: [ "U+0-10FFFF", "U+3-7B3", "U+3??", "U+6A", "U+3????", "U+???", "U+302-302", "U+0-7,U+A-C", "U+3??, U+500-513 ,U+612 , U+4????", "U+1FFF,U+200-27F" ],
|
"800",
|
||||||
invalid_values: [ "U+1????-2????", "U+0-7,A-C", "U+100-17F,U+200-17F", "U+100-17F,200-27F", "U+6A!important", "U+6A)" ]
|
"900",
|
||||||
},
|
"107",
|
||||||
"font-display": {
|
"399",
|
||||||
domProp: null,
|
"401",
|
||||||
values: [ "auto", "block", "swap", "fallback", "optional" ],
|
"699",
|
||||||
invalid_values: [ "normal", "initial" ]
|
"710",
|
||||||
}
|
"calc(1001)",
|
||||||
}
|
"calc(100 + 1)",
|
||||||
|
"calc(1)",
|
||||||
|
"100.6",
|
||||||
|
"99",
|
||||||
|
"700 900",
|
||||||
|
"300.4 500.4",
|
||||||
|
"calc(200.4) calc(400.4)",
|
||||||
|
],
|
||||||
|
invalid_values: ["bolder", "lighter", "1001", "0", "0 100", "100 1001"],
|
||||||
|
},
|
||||||
|
src: {
|
||||||
|
domProp: null,
|
||||||
|
values: [
|
||||||
|
"url(404.ttf)",
|
||||||
|
'url("404.eot")',
|
||||||
|
"url('404.otf')",
|
||||||
|
'url(404.ttf) format("truetype")',
|
||||||
|
'url(404.ttf) format("truetype", "opentype")',
|
||||||
|
'url(404.ttf) format("truetype", "opentype"), url(\'404.eot\')',
|
||||||
|
"local(Times New Roman)",
|
||||||
|
"local('Times New Roman')",
|
||||||
|
'local("Times New Roman")',
|
||||||
|
'local("serif")',
|
||||||
|
'url(404.ttf) format("truetype", "unknown"), local(Times New Roman), url(\'404.eot\')',
|
||||||
|
],
|
||||||
|
invalid_values: [
|
||||||
|
"url(404.ttf) format(truetype)",
|
||||||
|
'url(404.ttf) format("truetype" "opentype")',
|
||||||
|
'url(404.ttf) format("truetype",)',
|
||||||
|
'local("Times New" Roman)',
|
||||||
|
"local(serif)" /* is this valid? */,
|
||||||
|
"url(404.ttf) )",
|
||||||
|
"url(404.ttf) ) foo",
|
||||||
|
"url(404.ttf) ! important",
|
||||||
|
"url(404.ttf) ! hello",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"unicode-range": {
|
||||||
|
domProp: null,
|
||||||
|
values: [
|
||||||
|
"U+0-10FFFF",
|
||||||
|
"U+3-7B3",
|
||||||
|
"U+3??",
|
||||||
|
"U+6A",
|
||||||
|
"U+3????",
|
||||||
|
"U+???",
|
||||||
|
"U+302-302",
|
||||||
|
"U+0-7,U+A-C",
|
||||||
|
"U+3??, U+500-513 ,U+612 , U+4????",
|
||||||
|
"U+1FFF,U+200-27F",
|
||||||
|
],
|
||||||
|
invalid_values: [
|
||||||
|
"U+1????-2????",
|
||||||
|
"U+0-7,A-C",
|
||||||
|
"U+100-17F,U+200-17F",
|
||||||
|
"U+100-17F,200-27F",
|
||||||
|
"U+6A!important",
|
||||||
|
"U+6A)",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"font-display": {
|
||||||
|
domProp: null,
|
||||||
|
values: ["auto", "block", "swap", "fallback", "optional"],
|
||||||
|
invalid_values: ["normal", "initial"],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,27 +1,25 @@
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
window.addEventListener("load", runTests);
|
window.addEventListener("load", runTests);
|
||||||
|
|
||||||
function runTests(event)
|
function runTests(event) {
|
||||||
{
|
if (event.target != document) {
|
||||||
if (event.target != document) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var elt = document.getElementById("content");
|
var elt = document.getElementById("content");
|
||||||
|
|
||||||
elt.setAttribute("style", "color: blue; background-color: fuchsia");
|
elt.setAttribute("style", "color: blue; background-color: fuchsia");
|
||||||
is(elt.style.color, "blue",
|
is(elt.style.color, "blue", "setting correct style attribute (color)");
|
||||||
"setting correct style attribute (color)");
|
is(
|
||||||
is(elt.style.backgroundColor, "fuchsia",
|
elt.style.backgroundColor,
|
||||||
"setting correct style attribute (color)");
|
"fuchsia",
|
||||||
|
"setting correct style attribute (color)"
|
||||||
|
);
|
||||||
|
|
||||||
elt.setAttribute("style", "{color: blue; background-color: fuchsia}");
|
elt.setAttribute("style", "{color: blue; background-color: fuchsia}");
|
||||||
is(elt.style.color, "",
|
is(elt.style.color, "", "setting braced style attribute (color)");
|
||||||
"setting braced style attribute (color)");
|
is(elt.style.backgroundColor, "", "setting braced style attribute (color)");
|
||||||
is(elt.style.backgroundColor, "",
|
|
||||||
"setting braced style attribute (color)");
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,15 @@ function test() {
|
||||||
|
|
||||||
const windowListener = {
|
const windowListener = {
|
||||||
onOpenWindow(win) {
|
onOpenWindow(win) {
|
||||||
info("Observed window open")
|
info("Observed window open");
|
||||||
|
|
||||||
const domWindow = win.docShell.domWindow;
|
const domWindow = win.docShell.domWindow;
|
||||||
waitForFocus(() => {
|
waitForFocus(() => {
|
||||||
is(domWindow.location,
|
is(
|
||||||
"chrome://layoutdebug/content/layoutdebug.xul",
|
domWindow.location,
|
||||||
"Window location is correct");
|
"chrome://layoutdebug/content/layoutdebug.xul",
|
||||||
|
"Window location is correct"
|
||||||
|
);
|
||||||
domWindow.close();
|
domWindow.close();
|
||||||
}, domWindow);
|
}, domWindow);
|
||||||
},
|
},
|
||||||
|
|
@ -26,7 +28,7 @@ function test() {
|
||||||
info("Observed window closed");
|
info("Observed window closed");
|
||||||
Services.wm.removeListener(this);
|
Services.wm.removeListener(this);
|
||||||
finish();
|
finish();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
Services.wm.addListener(windowListener);
|
Services.wm.addListener(windowListener);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
function run_test() {
|
function run_test() {
|
||||||
Assert.ok("@mozilla.org/layout-debug/layout-debuggingtools;1" in
|
Assert.ok("@mozilla.org/layout-debug/layout-debuggingtools;1" in Cc);
|
||||||
Cc);
|
Assert.ok(
|
||||||
Assert.ok("@mozilla.org/commandlinehandler/general-startup;1?type=layoutdebug" in
|
"@mozilla.org/commandlinehandler/general-startup;1?type=layoutdebug" in Cc
|
||||||
Cc);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,103 +6,100 @@ var gBrowser;
|
||||||
var gProgressListener;
|
var gProgressListener;
|
||||||
var gDebugger;
|
var gDebugger;
|
||||||
|
|
||||||
const NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID = "@mozilla.org/layout-debug/layout-debuggingtools;1";
|
const NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID =
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
"@mozilla.org/layout-debug/layout-debuggingtools;1";
|
||||||
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
function nsLDBBrowserContentListener()
|
function nsLDBBrowserContentListener() {
|
||||||
{
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsLDBBrowserContentListener.prototype = {
|
nsLDBBrowserContentListener.prototype = {
|
||||||
|
init: function() {
|
||||||
|
this.mStatusText = document.getElementById("status-text");
|
||||||
|
this.mURLBar = document.getElementById("urlbar");
|
||||||
|
this.mForwardButton = document.getElementById("forward-button");
|
||||||
|
this.mBackButton = document.getElementById("back-button");
|
||||||
|
this.mStopButton = document.getElementById("stop-button");
|
||||||
|
},
|
||||||
|
|
||||||
init : function()
|
QueryInterface: ChromeUtils.generateQI([
|
||||||
{
|
Ci.nsIWebProgressListener,
|
||||||
this.mStatusText = document.getElementById("status-text");
|
Ci.nsISupportsWeakReference,
|
||||||
this.mURLBar = document.getElementById("urlbar");
|
]),
|
||||||
this.mForwardButton = document.getElementById("forward-button");
|
|
||||||
this.mBackButton = document.getElementById("back-button");
|
|
||||||
this.mStopButton = document.getElementById("stop-button");
|
|
||||||
},
|
|
||||||
|
|
||||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
|
|
||||||
Ci.nsISupportsWeakReference]),
|
|
||||||
|
|
||||||
// nsIWebProgressListener implementation
|
// nsIWebProgressListener implementation
|
||||||
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
|
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||||
{
|
if (
|
||||||
if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) ||
|
!(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) ||
|
||||||
aWebProgress != gBrowser.webProgress)
|
aWebProgress != gBrowser.webProgress
|
||||||
return;
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
|
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
|
||||||
this.setButtonEnabled(this.mStopButton, true);
|
this.setButtonEnabled(this.mStopButton, true);
|
||||||
this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
|
|
||||||
this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
|
|
||||||
this.mStatusText.value = "loading...";
|
|
||||||
this.mLoading = true;
|
|
||||||
|
|
||||||
} else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
|
||||||
this.setButtonEnabled(this.mStopButton, false);
|
|
||||||
this.mStatusText.value = this.mURLBar.value + " loaded";
|
|
||||||
this.mLoading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onProgressChange : function(aWebProgress, aRequest,
|
|
||||||
aCurSelfProgress, aMaxSelfProgress,
|
|
||||||
aCurTotalProgress, aMaxTotalProgress)
|
|
||||||
{
|
|
||||||
},
|
|
||||||
|
|
||||||
onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags)
|
|
||||||
{
|
|
||||||
this.mURLBar.value = aLocation.spec;
|
|
||||||
this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
|
this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
|
||||||
this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
|
this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
|
||||||
},
|
this.mStatusText.value = "loading...";
|
||||||
|
this.mLoading = true;
|
||||||
|
} else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||||
|
this.setButtonEnabled(this.mStopButton, false);
|
||||||
|
this.mStatusText.value = this.mURLBar.value + " loaded";
|
||||||
|
this.mLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
|
onProgressChange: function(
|
||||||
{
|
aWebProgress,
|
||||||
this.mStatusText.value = aMessage;
|
aRequest,
|
||||||
},
|
aCurSelfProgress,
|
||||||
|
aMaxSelfProgress,
|
||||||
|
aCurTotalProgress,
|
||||||
|
aMaxTotalProgress
|
||||||
|
) {},
|
||||||
|
|
||||||
onSecurityChange : function(aWebProgress, aRequest, aState)
|
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
|
||||||
{
|
this.mURLBar.value = aLocation.spec;
|
||||||
},
|
this.setButtonEnabled(this.mForwardButton, gBrowser.canGoForward);
|
||||||
|
this.setButtonEnabled(this.mBackButton, gBrowser.canGoBack);
|
||||||
|
},
|
||||||
|
|
||||||
onContentBlockingEvent : function(aWebProgress, aRequest, aEvent)
|
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
|
||||||
{
|
this.mStatusText.value = aMessage;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onSecurityChange: function(aWebProgress, aRequest, aState) {},
|
||||||
|
|
||||||
|
onContentBlockingEvent: function(aWebProgress, aRequest, aEvent) {},
|
||||||
|
|
||||||
// non-interface methods
|
// non-interface methods
|
||||||
setButtonEnabled : function(aButtonElement, aEnabled)
|
setButtonEnabled: function(aButtonElement, aEnabled) {
|
||||||
{
|
if (aEnabled) {
|
||||||
if (aEnabled)
|
aButtonElement.removeAttribute("disabled");
|
||||||
aButtonElement.removeAttribute("disabled");
|
} else {
|
||||||
else
|
aButtonElement.setAttribute("disabled", "true");
|
||||||
aButtonElement.setAttribute("disabled", "true");
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mStatusText : null,
|
mStatusText: null,
|
||||||
mURLBar : null,
|
mURLBar: null,
|
||||||
mForwardButton : null,
|
mForwardButton: null,
|
||||||
mBackButton : null,
|
mBackButton: null,
|
||||||
mStopButton : null,
|
mStopButton: null,
|
||||||
|
|
||||||
mLoading : false
|
mLoading: false,
|
||||||
|
};
|
||||||
|
|
||||||
}
|
function OnLDBLoad() {
|
||||||
|
|
||||||
function OnLDBLoad()
|
|
||||||
{
|
|
||||||
gBrowser = document.getElementById("browser");
|
gBrowser = document.getElementById("browser");
|
||||||
|
|
||||||
gProgressListener = new nsLDBBrowserContentListener();
|
gProgressListener = new nsLDBBrowserContentListener();
|
||||||
gBrowser.addProgressListener(gProgressListener);
|
gBrowser.addProgressListener(gProgressListener);
|
||||||
|
|
||||||
gDebugger = Cc[NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID].
|
gDebugger = Cc[NS_LAYOUT_DEBUGGINGTOOLS_CONTRACTID].createInstance(
|
||||||
createInstance(Ci.nsILayoutDebuggingTools);
|
Ci.nsILayoutDebuggingTools
|
||||||
|
);
|
||||||
|
|
||||||
if (window.arguments && window.arguments[0]) {
|
if (window.arguments && window.arguments[0]) {
|
||||||
gBrowser.loadURI(window.arguments[0], {
|
gBrowser.loadURI(window.arguments[0], {
|
||||||
|
|
@ -110,7 +107,9 @@ function OnLDBLoad()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
gBrowser.loadURI("about:blank", {
|
gBrowser.loadURI("about:blank", {
|
||||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
|
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
|
||||||
|
{}
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,14 +118,12 @@ function OnLDBLoad()
|
||||||
checkPersistentMenus();
|
checkPersistentMenus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPersistentMenu(item)
|
function checkPersistentMenu(item) {
|
||||||
{
|
|
||||||
var menuitem = document.getElementById("menu_" + item);
|
var menuitem = document.getElementById("menu_" + item);
|
||||||
menuitem.setAttribute("checked", gDebugger[item]);
|
menuitem.setAttribute("checked", gDebugger[item]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPersistentMenus()
|
function checkPersistentMenus() {
|
||||||
{
|
|
||||||
// Restore the toggles that are stored in prefs.
|
// Restore the toggles that are stored in prefs.
|
||||||
checkPersistentMenu("paintFlashing");
|
checkPersistentMenu("paintFlashing");
|
||||||
checkPersistentMenu("paintDumping");
|
checkPersistentMenu("paintDumping");
|
||||||
|
|
@ -137,28 +134,26 @@ function checkPersistentMenus()
|
||||||
checkPersistentMenu("reflowCounts");
|
checkPersistentMenu("reflowCounts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function OnLDBUnload() {
|
||||||
function OnLDBUnload()
|
|
||||||
{
|
|
||||||
gBrowser.removeProgressListener(gProgressListener);
|
gBrowser.removeProgressListener(gProgressListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle(menuitem)
|
function toggle(menuitem) {
|
||||||
{
|
|
||||||
// trim the initial "menu_"
|
// trim the initial "menu_"
|
||||||
var feature = menuitem.id.substring(5);
|
var feature = menuitem.id.substring(5);
|
||||||
gDebugger[feature] = menuitem.getAttribute("checked") == "true";
|
gDebugger[feature] = menuitem.getAttribute("checked") == "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
function openFile()
|
function openFile() {
|
||||||
{
|
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"]
|
|
||||||
.createInstance(Ci.nsIFilePicker);
|
|
||||||
fp.init(window, "Select a File", Ci.nsIFilePicker.modeOpen);
|
fp.init(window, "Select a File", Ci.nsIFilePicker.modeOpen);
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterHTML | Ci.nsIFilePicker.filterAll);
|
fp.appendFilters(Ci.nsIFilePicker.filterHTML | Ci.nsIFilePicker.filterAll);
|
||||||
fp.open(rv => {
|
fp.open(rv => {
|
||||||
if (rv == Ci.nsIFilePicker.returnOK && fp.fileURL.spec &&
|
if (
|
||||||
fp.fileURL.spec.length > 0) {
|
rv == Ci.nsIFilePicker.returnOK &&
|
||||||
|
fp.fileURL.spec &&
|
||||||
|
fp.fileURL.spec.length > 0
|
||||||
|
) {
|
||||||
gBrowser.loadURI(fp.fileURL.spec, {
|
gBrowser.loadURI(fp.fileURL.spec, {
|
||||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,61 +3,67 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
function RecordingCmdLineHandler() {}
|
function RecordingCmdLineHandler() {}
|
||||||
RecordingCmdLineHandler.prototype =
|
RecordingCmdLineHandler.prototype = {
|
||||||
{
|
/* nsISupports */
|
||||||
/* nsISupports */
|
QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]),
|
||||||
QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]),
|
|
||||||
|
|
||||||
/* nsICommandLineHandler */
|
/* nsICommandLineHandler */
|
||||||
handle : function handler_handle(cmdLine) {
|
handle: function handler_handle(cmdLine) {
|
||||||
var args = { };
|
var args = {};
|
||||||
args.wrappedJSObject = args;
|
args.wrappedJSObject = args;
|
||||||
try {
|
try {
|
||||||
var uristr = cmdLine.handleFlagWithParam("recording", false);
|
var uristr = cmdLine.handleFlagWithParam("recording", false);
|
||||||
if (uristr == null)
|
if (uristr == null) {
|
||||||
return;
|
return;
|
||||||
try {
|
}
|
||||||
args.uri = cmdLine.resolveURI(uristr).spec;
|
try {
|
||||||
}
|
args.uri = cmdLine.resolveURI(uristr).spec;
|
||||||
catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
cmdLine.handleFlag("recording", true);
|
||||||
cmdLine.handleFlag("recording", true);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manipulate preferences by adding to the *default* branch. Adding
|
* Manipulate preferences by adding to the *default* branch. Adding
|
||||||
* to the default branch means the changes we make won't get written
|
* to the default branch means the changes we make won't get written
|
||||||
* back to user preferences.
|
* back to user preferences.
|
||||||
*
|
*
|
||||||
* We want to do this here rather than in reftest.js because it's
|
* We want to do this here rather than in reftest.js because it's
|
||||||
* important to set the recording pref before the platform Init gets
|
* important to set the recording pref before the platform Init gets
|
||||||
* called.
|
* called.
|
||||||
*/
|
*/
|
||||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(
|
||||||
getService(Ci.nsIPrefService);
|
Ci.nsIPrefService
|
||||||
var branch = prefs.getDefaultBranch("");
|
);
|
||||||
|
var branch = prefs.getDefaultBranch("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var outputstr = cmdLine.handleFlagWithParam("recording-output", false);
|
var outputstr = cmdLine.handleFlagWithParam("recording-output", false);
|
||||||
if (outputstr != null) {
|
if (outputstr != null) {
|
||||||
branch.setCharPref("gfx.2d.recordingfile", outputstr);
|
branch.setCharPref("gfx.2d.recordingfile", outputstr);
|
||||||
}
|
}
|
||||||
} catch (e) { }
|
} catch (e) {}
|
||||||
|
|
||||||
branch.setBoolPref("gfx.2d.recording", true);
|
branch.setBoolPref("gfx.2d.recording", true);
|
||||||
|
|
||||||
var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(
|
||||||
.getService(Ci.nsIWindowWatcher);
|
Ci.nsIWindowWatcher
|
||||||
wwatch.openWindow(null, "chrome://recording/content/recording.xul", "_blank",
|
);
|
||||||
"chrome,dialog=no,all", args);
|
wwatch.openWindow(
|
||||||
cmdLine.preventDefault = true;
|
null,
|
||||||
},
|
"chrome://recording/content/recording.xul",
|
||||||
|
"_blank",
|
||||||
|
"chrome,dialog=no,all",
|
||||||
|
args
|
||||||
|
);
|
||||||
|
cmdLine.preventDefault = true;
|
||||||
|
},
|
||||||
|
|
||||||
helpInfo : " --recording <file> Record drawing for a given URL.\n" +
|
helpInfo:
|
||||||
" --recording-output <file> Specify destination file for a drawing recording.\n"
|
" --recording <file> Record drawing for a given URL.\n" +
|
||||||
|
" --recording-output <file> Specify destination file for a drawing recording.\n",
|
||||||
};
|
};
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["RecordingCmdLineHandler"];
|
var EXPORTED_SYMBOLS = ["RecordingCmdLineHandler"];
|
||||||
|
|
|
||||||
|
|
@ -11,36 +11,42 @@ var gContainingWindow = null;
|
||||||
var gBrowser;
|
var gBrowser;
|
||||||
|
|
||||||
function OnDocumentLoad(evt) {
|
function OnDocumentLoad(evt) {
|
||||||
if (evt.target != gBrowser.contentDocument || evt.target.location == "about:blank")
|
if (
|
||||||
return;
|
evt.target != gBrowser.contentDocument ||
|
||||||
gBrowser.removeEventListener("load", OnDocumentLoad, true);
|
evt.target.location == "about:blank"
|
||||||
gContainingWindow.close();
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gBrowser.removeEventListener("load", OnDocumentLoad, true);
|
||||||
|
gContainingWindow.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.OnRecordingLoad = function OnRecordingLoad(win) {
|
this.OnRecordingLoad = function OnRecordingLoad(win) {
|
||||||
if (win === undefined || win == null) {
|
if (win === undefined || win == null) {
|
||||||
win = window;
|
win = window;
|
||||||
}
|
}
|
||||||
if (gContainingWindow == null && win != null) {
|
if (gContainingWindow == null && win != null) {
|
||||||
gContainingWindow = win;
|
gContainingWindow = win;
|
||||||
}
|
}
|
||||||
|
|
||||||
gBrowser = gContainingWindow.document.getElementById("browser");
|
gBrowser = gContainingWindow.document.getElementById("browser");
|
||||||
|
|
||||||
var gfxInfo = (NS_GFXINFO_CONTRACTID in Cc) && Cc[NS_GFXINFO_CONTRACTID].getService(Ci.nsIGfxInfo);
|
var gfxInfo =
|
||||||
var info = gfxInfo.getInfo();
|
NS_GFXINFO_CONTRACTID in Cc &&
|
||||||
dump(info.AzureContentBackend + "\n");
|
Cc[NS_GFXINFO_CONTRACTID].getService(Ci.nsIGfxInfo);
|
||||||
if (info.AzureContentBackend == "none") {
|
var info = gfxInfo.getInfo();
|
||||||
alert("Page recordings may only be made with Azure content enabled.");
|
dump(info.AzureContentBackend + "\n");
|
||||||
gContainingWindow.close();
|
if (info.AzureContentBackend == "none") {
|
||||||
return;
|
alert("Page recordings may only be made with Azure content enabled.");
|
||||||
}
|
gContainingWindow.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gBrowser.addEventListener("load", OnDocumentLoad, true);
|
gBrowser.addEventListener("load", OnDocumentLoad, true);
|
||||||
|
|
||||||
var args = window.arguments[0].wrappedJSObject;
|
var args = window.arguments[0].wrappedJSObject;
|
||||||
|
|
||||||
gBrowser.loadURI(args.uri, {
|
gBrowser.loadURI(args.uri, {
|
||||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
|
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
ChromeUtils.import("resource://testing-common/CustomizableUITestUtils.jsm", this);
|
ChromeUtils.import(
|
||||||
|
"resource://testing-common/CustomizableUITestUtils.jsm",
|
||||||
|
this
|
||||||
|
);
|
||||||
let gCUITestUtils = new CustomizableUITestUtils(window);
|
let gCUITestUtils = new CustomizableUITestUtils(window);
|
||||||
|
|
||||||
add_task(async function test_setup() {
|
add_task(async function test_setup() {
|
||||||
|
|
@ -12,8 +15,11 @@ add_task(async function() {
|
||||||
BrowserSearch.searchBar.focus();
|
BrowserSearch.searchBar.focus();
|
||||||
|
|
||||||
let DOMWindowUtils = EventUtils._getDOMWindowUtils();
|
let DOMWindowUtils = EventUtils._getDOMWindowUtils();
|
||||||
is(DOMWindowUtils.IMEStatus, DOMWindowUtils.IME_STATUS_ENABLED,
|
is(
|
||||||
"IME should be available when searchbar has focus");
|
DOMWindowUtils.IMEStatus,
|
||||||
|
DOMWindowUtils.IME_STATUS_ENABLED,
|
||||||
|
"IME should be available when searchbar has focus"
|
||||||
|
);
|
||||||
|
|
||||||
let searchPopup = document.getElementById("PopupSearchAutoComplete");
|
let searchPopup = document.getElementById("PopupSearchAutoComplete");
|
||||||
|
|
||||||
|
|
@ -23,8 +29,11 @@ add_task(async function() {
|
||||||
await shownPromise;
|
await shownPromise;
|
||||||
await new Promise(r => setTimeout(r, 0));
|
await new Promise(r => setTimeout(r, 0));
|
||||||
|
|
||||||
is(DOMWindowUtils.IMEStatus, DOMWindowUtils.IME_STATUS_ENABLED,
|
is(
|
||||||
"IME should be available even when the popup of searchbar is open");
|
DOMWindowUtils.IMEStatus,
|
||||||
|
DOMWindowUtils.IME_STATUS_ENABLED,
|
||||||
|
"IME should be available even when the popup of searchbar is open"
|
||||||
|
);
|
||||||
|
|
||||||
// Activate the menubar, then, the popup should be closed
|
// Activate the menubar, then, the popup should be closed
|
||||||
let hiddenPromise = BrowserTestUtils.waitForEvent(searchPopup, "popuphidden");
|
let hiddenPromise = BrowserTestUtils.waitForEvent(searchPopup, "popuphidden");
|
||||||
|
|
@ -32,10 +41,16 @@ add_task(async function() {
|
||||||
await hiddenPromise;
|
await hiddenPromise;
|
||||||
await new Promise(r => setTimeout(r, 0));
|
await new Promise(r => setTimeout(r, 0));
|
||||||
|
|
||||||
is(DOMWindowUtils.IMEStatus, DOMWindowUtils.IME_STATUS_DISABLED,
|
is(
|
||||||
"IME should not be available when menubar is active");
|
DOMWindowUtils.IMEStatus,
|
||||||
|
DOMWindowUtils.IME_STATUS_DISABLED,
|
||||||
|
"IME should not be available when menubar is active"
|
||||||
|
);
|
||||||
// Inactivate the menubar (and restore the focus to the searchbar
|
// Inactivate the menubar (and restore the focus to the searchbar
|
||||||
EventUtils.synthesizeKey("KEY_Escape");
|
EventUtils.synthesizeKey("KEY_Escape");
|
||||||
is(DOMWindowUtils.IMEStatus, DOMWindowUtils.IME_STATUS_ENABLED,
|
is(
|
||||||
"IME should be available after focus is back to the searchbar");
|
DOMWindowUtils.IMEStatus,
|
||||||
|
DOMWindowUtils.IME_STATUS_ENABLED,
|
||||||
|
"IME should be available after focus is back to the searchbar"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,38 @@
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
const html = "<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>";
|
const html =
|
||||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/html," + html);
|
'<p id="p1" title="tooltip is here">This paragraph has a tooltip.</p>';
|
||||||
|
await BrowserTestUtils.openNewForegroundTab(
|
||||||
|
gBrowser,
|
||||||
|
"data:text/html," + html
|
||||||
|
);
|
||||||
|
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
|
SpecialPowers.pushPrefEnv({ set: [["ui.tooltipDelay", 0]] }, resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" },
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
gBrowser.selectedBrowser);
|
"#p1",
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p1", { }, gBrowser.selectedBrowser);
|
{ type: "mousemove" },
|
||||||
|
gBrowser.selectedBrowser
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
|
"#p1",
|
||||||
|
{},
|
||||||
|
gBrowser.selectedBrowser
|
||||||
|
);
|
||||||
|
|
||||||
// Wait until the tooltip timeout triggers that would normally have opened the popup.
|
// Wait until the tooltip timeout triggers that would normally have opened the popup.
|
||||||
await new Promise(resolve => setTimeout(resolve, 0));
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
is(document.getElementById("aHTMLTooltip").state, "closed", "local tooltip is closed");
|
is(
|
||||||
is(document.getElementById("remoteBrowserTooltip").state, "closed", "remote tooltip is closed");
|
document.getElementById("aHTMLTooltip").state,
|
||||||
|
"closed",
|
||||||
|
"local tooltip is closed"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
document.getElementById("remoteBrowserTooltip").state,
|
||||||
|
"closed",
|
||||||
|
"remote tooltip is closed"
|
||||||
|
);
|
||||||
|
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,55 @@
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
const url = "data:text/html," +
|
const url =
|
||||||
|
"data:text/html," +
|
||||||
"<html onmousemove='event.stopPropagation()'" +
|
"<html onmousemove='event.stopPropagation()'" +
|
||||||
" onmouseenter='event.stopPropagation()' onmouseleave='event.stopPropagation()'" +
|
" onmouseenter='event.stopPropagation()' onmouseleave='event.stopPropagation()'" +
|
||||||
" onmouseover='event.stopPropagation()' onmouseout='event.stopPropagation()'>" +
|
" onmouseover='event.stopPropagation()' onmouseout='event.stopPropagation()'>" +
|
||||||
"<p id=\"p1\" title=\"tooltip is here\">This paragraph has a tooltip.</p>" +
|
'<p id="p1" title="tooltip is here">This paragraph has a tooltip.</p>' +
|
||||||
"<p id=\"p2\">This paragraph doesn't have tooltip.</p></html>";
|
'<p id="p2">This paragraph doesn\'t have tooltip.</p></html>';
|
||||||
|
|
||||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
||||||
let browser = gBrowser.selectedBrowser;
|
let browser = gBrowser.selectedBrowser;
|
||||||
|
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
|
SpecialPowers.pushPrefEnv({ set: [["ui.tooltipDelay", 0]] }, resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
|
let popupShownPromise = BrowserTestUtils.waitForEvent(
|
||||||
is(event.originalTarget.localName, "tooltip", "tooltip is showing");
|
document,
|
||||||
return true;
|
"popupshown",
|
||||||
});
|
false,
|
||||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden", false, event => {
|
event => {
|
||||||
is(event.originalTarget.localName, "tooltip", "tooltip is hidden");
|
is(event.originalTarget.localName, "tooltip", "tooltip is showing");
|
||||||
return true;
|
return true;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
|
||||||
|
document,
|
||||||
|
"popuphidden",
|
||||||
|
false,
|
||||||
|
event => {
|
||||||
|
is(event.originalTarget.localName, "tooltip", "tooltip is hidden");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Send a mousemove at a known position to start the test.
|
// Send a mousemove at a known position to start the test.
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, browser);
|
"#p2",
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
|
"#p1",
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupShownPromise;
|
await popupShownPromise;
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
|
"#p2",
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupHiddenPromise;
|
await popupHiddenPromise;
|
||||||
|
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,49 @@
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
const url = "data:text/html,<html><head></head><body>" +
|
const url =
|
||||||
"<a id=\"target\" href=\"about:blank\" title=\"This is tooltip text\" " +
|
"data:text/html,<html><head></head><body>" +
|
||||||
"style=\"display:block;height:20px;margin:10px;\" " +
|
'<a id="target" href="about:blank" title="This is tooltip text" ' +
|
||||||
"onclick=\"return false;\">here is an anchor element</a></body></html>";
|
'style="display:block;height:20px;margin:10px;" ' +
|
||||||
|
'onclick="return false;">here is an anchor element</a></body></html>';
|
||||||
|
|
||||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
||||||
let browser = gBrowser.selectedBrowser;
|
let browser = gBrowser.selectedBrowser;
|
||||||
|
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
|
SpecialPowers.pushPrefEnv({ set: [["ui.tooltipDelay", 0]] }, resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send a mousemove at a known position to start the test.
|
// Send a mousemove at a known position to start the test.
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", -5, -5, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
-5,
|
||||||
|
-5,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
|
||||||
// show tooltip by mousemove into target.
|
// show tooltip by mousemove into target.
|
||||||
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupShownPromise;
|
await popupShownPromise;
|
||||||
|
|
||||||
// hide tooltip by mousemove to outside.
|
// hide tooltip by mousemove to outside.
|
||||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
|
let popupHiddenPromise = BrowserTestUtils.waitForEvent(
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
|
document,
|
||||||
|
"popuphidden"
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
-5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupHiddenPromise;
|
await popupHiddenPromise;
|
||||||
|
|
||||||
// mousemove into the target and start drag by emulation via nsIDragService.
|
// mousemove into the target and start drag by emulation via nsIDragService.
|
||||||
|
|
@ -32,48 +54,96 @@ add_task(async function() {
|
||||||
// Emulate a buggy mousemove event. widget might dispatch mousemove event
|
// Emulate a buggy mousemove event. widget might dispatch mousemove event
|
||||||
// during drag.
|
// during drag.
|
||||||
|
|
||||||
function tooltipNotExpected()
|
function tooltipNotExpected() {
|
||||||
{
|
|
||||||
ok(false, "tooltip is shown during drag");
|
ok(false, "tooltip is shown during drag");
|
||||||
}
|
}
|
||||||
addEventListener("popupshown", tooltipNotExpected, true);
|
addEventListener("popupshown", tooltipNotExpected, true);
|
||||||
|
|
||||||
let dragService = Cc["@mozilla.org/widget/dragservice;1"].
|
let dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(
|
||||||
getService(Ci.nsIDragService);
|
Ci.nsIDragService
|
||||||
|
);
|
||||||
dragService.startDragSession();
|
dragService.startDragSession();
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
removeEventListener("popupshown", tooltipNotExpected, true);
|
removeEventListener("popupshown", tooltipNotExpected, true);
|
||||||
dragService.endDragSession(true);
|
dragService.endDragSession(true);
|
||||||
|
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", -5, -5, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
-5,
|
||||||
|
-5,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
|
||||||
// If tooltip listener used a flag for managing D&D state, we would need
|
// If tooltip listener used a flag for managing D&D state, we would need
|
||||||
// to test if the tooltip is shown after drag.
|
// to test if the tooltip is shown after drag.
|
||||||
|
|
||||||
// show tooltip by mousemove into target.
|
// show tooltip by mousemove into target.
|
||||||
popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupShownPromise;
|
await popupShownPromise;
|
||||||
|
|
||||||
// hide tooltip by mousemove to outside.
|
// hide tooltip by mousemove to outside.
|
||||||
popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
|
popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
-5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupHiddenPromise;
|
await popupHiddenPromise;
|
||||||
|
|
||||||
// Show tooltip after mousedown
|
// Show tooltip after mousedown
|
||||||
popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown");
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousemove" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupShownPromise;
|
await popupShownPromise;
|
||||||
|
|
||||||
popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
|
popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden");
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mousedown" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mousedown" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
await popupHiddenPromise;
|
await popupHiddenPromise;
|
||||||
|
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", 5, 15, { type: "mouseup" }, browser);
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
await BrowserTestUtils.synthesizeMouse("#target", -5, 15, { type: "mousemove" }, browser);
|
"#target",
|
||||||
|
5,
|
||||||
|
15,
|
||||||
|
{ type: "mouseup" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.synthesizeMouse(
|
||||||
|
"#target",
|
||||||
|
-5,
|
||||||
|
15,
|
||||||
|
{ type: "mousemove" },
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
|
||||||
ok(true, "tooltips appear properly");
|
ok(true, "tooltips appear properly");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue