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