Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2017-03-17 14:55:15 +01:00
Родитель 51a03b479f 1cefb9fb2f
Коммит 3e0a5441c6
332 изменённых файлов: 3511 добавлений и 36302 удалений

Просмотреть файл

@ -7,12 +7,11 @@ require("sdk/clipboard");
const { Cc, Ci } = require("chrome");
const imageTools = Cc["@mozilla.org/image/tools;1"].
getService(Ci.imgITools);
const io = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
const imageTools = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
const io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].getService(Ci.nsIAppShellService);
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const base64png = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA" +
"AABzenr0AAAASUlEQVRYhe3O0QkAIAwD0eyqe3Q993AQ3cBSUKpygfsNTy" +
"N5ugbQpK0BAADgP0BRDWXWlwEAAAAAgPsA3rzDaAAAAHgPcGrpgAnzQ2FG" +
@ -24,58 +23,6 @@ const { platform } = require("sdk/system");
// For Windows, Mac and Linux, platform returns the following: winnt, darwin and linux.
var isWindows = platform.toLowerCase().indexOf("win") == 0;
const canvasHTML = "data:text/html," + encodeURIComponent(
"<html>\
<body>\
<canvas width='32' height='32'></canvas>\
</body>\
</html>"
);
function comparePixelImages(imageA, imageB, callback) {
let tabs = require("sdk/tabs");
tabs.open({
url: canvasHTML,
onReady: function onReady(tab) {
let worker = tab.attach({
contentScript: "new " + function() {
let canvas = document.querySelector("canvas");
let context = canvas.getContext("2d");
self.port.on("draw-image", function(imageURI) {
let img = new Image();
img.onload = function() {
context.drawImage(this, 0, 0);
let pixels = Array.join(context.getImageData(0, 0, 32, 32).data);
self.port.emit("image-pixels", pixels);
}
img.src = imageURI;
});
}
});
let compared = "";
worker.port.on("image-pixels", function (pixels) {
if (!compared) {
compared = pixels;
this.emit("draw-image", imageB);
} else {
tab.close(callback.bind(null, compared === pixels))
}
});
worker.port.emit("draw-image", imageA);
}
});
}
// Test the typical use case, setting & getting with no flavors specified
exports["test With No Flavor"] = function(assert) {
var contents = "hello there";
@ -160,20 +107,39 @@ exports["test Set Image"] = function(assert) {
assert.equal(clip.currentFlavors[0], flavor, "flavor is set");
};
exports["test Get Image"] = function(assert, done) {
exports["test Get Image"] = function* (assert) {
var clip = require("sdk/clipboard");
clip.set(base64png, "image");
var contents = clip.get();
const hiddenWindow = appShellService.hiddenDOMWindow;
const Image = hiddenWindow.Image;
const canvas = hiddenWindow.document.createElementNS(XHTML_NS, "canvas");
let context = canvas.getContext("2d");
comparePixelImages(base64png, contents, function (areEquals) {
assert.ok(areEquals,
"Image gets from clipboard equals to image sets to the clipboard");
const imageURLToPixels = (imageURL) => {
return new Promise((resolve) => {
let img = new Image();
done();
});
}
img.onload = function() {
context.drawImage(this, 0, 0);
let pixels = Array.join(context.getImageData(0, 0, 32, 32).data);
resolve(pixels);
};
img.src = imageURL;
});
};
let [base64pngPixels, clipboardPixels] = yield Promise.all([
imageURLToPixels(base64png), imageURLToPixels(contents),
]);
assert.ok(base64pngPixels === clipboardPixels,
"Image gets from clipboard equals to image sets to the clipboard");
};
exports["test Set Image Type Not Supported"] = function(assert) {
var clip = require("sdk/clipboard");

Просмотреть файл

@ -889,9 +889,6 @@ pref("layout.accessiblecaret.enabled", true);
// by the spec in bug 921965.
pref("layout.accessiblecaret.bar.enabled", true);
// Hide the caret in cursor mode after 3 seconds.
pref("layout.accessiblecaret.timeout_ms", 3000);
// Hide carets and text selection dialog during scrolling.
pref("layout.accessiblecaret.always_show_when_scrolling", false);

Просмотреть файл

@ -72,7 +72,7 @@ add_task(function* () {
// Hack the planet! Load our blocklist shim, so we can mess with blocklist
// return results in the content process. Active until we close our tab.
let mm = gTestBrowser.messageManager;
info("test 3a: loading " + gChromeRoot + "blocklist_proxy.js" + "\n");
info("test 3a: loading " + gChromeRoot + "blocklist_proxy.js\n");
mm.loadFrameScript(gChromeRoot + "blocklist_proxy.js", true);
yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_test.html");

Просмотреть файл

@ -0,0 +1,9 @@
"use strict";
module.exports = {
rules: {
// XXX Bug 1326071 - This should be reduced down - probably to 20 or to
// be removed & synced with the toolkit/.eslintrc.js value.
"complexity": ["error", {"max": 69}],
}
};

Просмотреть файл

@ -42,7 +42,7 @@ function waitForPageLoad(aTab) {
function onTabLoad(event) {
clearTimeout(timeoutId);
aTab.linkedBrowser.removeEventListener("load", onTabLoad, true);
info("Tab event received: " + "load");
info("Tab event received: load");
deferred.resolve();
}
aTab.linkedBrowser.addEventListener("load", onTabLoad, true, true);

Просмотреть файл

@ -86,6 +86,8 @@ support-files =
[browser_ext_sessions_restore.js]
[browser_ext_sidebarAction.js]
[browser_ext_sidebarAction_context.js]
[browser_ext_sidebarAction_tabs.js]
[browser_ext_sidebarAction_windows.js]
[browser_ext_simple.js]
[browser_ext_tab_runtimeConnect.js]
[browser_ext_tabs_audio.js]

Просмотреть файл

@ -85,36 +85,6 @@ add_task(function* sidebar_two_sidebar_addons() {
yield extension2.unload();
});
add_task(function* sidebar_windows() {
let extension = ExtensionTestUtils.loadExtension(extData);
yield extension.startup();
// Test sidebar is opened on install
yield extension.awaitMessage("sidebar");
ok(!document.getElementById("sidebar-box").hidden, "sidebar box is visible in first window");
// Check that the menuitem has our image styling.
let elements = document.getElementsByClassName("webextension-menuitem");
is(elements.length, 1, "have one menuitem");
let style = elements[0].getAttribute("style");
ok(style.includes("webextension-menuitem-image"), "this menu has style");
let secondSidebar = extension.awaitMessage("sidebar");
// SidebarUI relies on window.opener being set, which is normal behavior when
// using menu or key commands to open a new browser window.
let win = yield BrowserTestUtils.openNewBrowserWindow({opener: window});
yield secondSidebar;
ok(!win.document.getElementById("sidebar-box").hidden, "sidebar box is visible in second window");
// Check that the menuitem has our image styling.
elements = win.document.getElementsByClassName("webextension-menuitem");
is(elements.length, 1, "have one menuitem");
style = elements[0].getAttribute("style");
ok(style.includes("webextension-menuitem-image"), "this menu has style");
yield extension.unload();
yield BrowserTestUtils.closeWindow(win);
});
add_task(function* sidebar_empty_panel() {
let extension = ExtensionTestUtils.loadExtension(extData);
yield extension.startup();
@ -126,49 +96,6 @@ add_task(function* sidebar_empty_panel() {
yield extension.unload();
});
add_task(function* sidebar_tab_query_bug_1340739() {
let data = {
manifest: {
"permissions": [
"tabs",
],
"sidebar_action": {
"default_panel": "sidebar.html",
},
},
useAddonManager: "temporary",
files: {
"sidebar.html": `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/>
<script src="sidebar.js"></script>
</head>
<body>
A Test Sidebar
</body></html>
`,
"sidebar.js": function() {
Promise.all([
browser.tabs.query({}).then((tabs) => {
browser.test.assertEq(1, tabs.length, "got tab without currentWindow");
}),
browser.tabs.query({currentWindow: true}).then((tabs) => {
browser.test.assertEq(1, tabs.length, "got tab with currentWindow");
}),
]).then(() => {
browser.test.sendMessage("sidebar");
});
},
},
};
let extension = ExtensionTestUtils.loadExtension(data);
yield extension.startup();
yield extension.awaitMessage("sidebar");
yield extension.unload();
});
add_task(function* cleanup() {
// This is set on initial sidebar install.
Services.prefs.clearUserPref("extensions.sidebar-button.shown");

Просмотреть файл

@ -0,0 +1,52 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* sidebar_tab_query_bug_1340739() {
let data = {
manifest: {
"permissions": [
"tabs",
],
"sidebar_action": {
"default_panel": "sidebar.html",
},
},
useAddonManager: "temporary",
files: {
"sidebar.html": `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/>
<script src="sidebar.js"></script>
</head>
<body>
A Test Sidebar
</body></html>
`,
"sidebar.js": function() {
Promise.all([
browser.tabs.query({}).then((tabs) => {
browser.test.assertEq(1, tabs.length, "got tab without currentWindow");
}),
browser.tabs.query({currentWindow: true}).then((tabs) => {
browser.test.assertEq(1, tabs.length, "got tab with currentWindow");
}),
]).then(() => {
browser.test.sendMessage("sidebar");
});
},
},
};
let extension = ExtensionTestUtils.loadExtension(data);
yield extension.startup();
yield extension.awaitMessage("sidebar");
yield extension.unload();
// Move toolbar button back to customization.
CustomizableUI.removeWidgetFromArea("sidebar-button", CustomizableUI.AREA_NAVBAR);
ok(!document.getElementById("sidebar-button"), "sidebar button is not in UI");
// This is set on initial sidebar install.
Services.prefs.clearUserPref("extensions.sidebar-button.shown");
});

Просмотреть файл

@ -0,0 +1,67 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
let extData = {
manifest: {
"sidebar_action": {
"default_panel": "sidebar.html",
},
},
useAddonManager: "temporary",
files: {
"sidebar.html": `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/>
<script src="sidebar.js"></script>
</head>
<body>
A Test Sidebar
</body></html>
`,
"sidebar.js": function() {
window.onload = () => {
browser.test.sendMessage("sidebar");
};
},
},
};
add_task(function* sidebar_windows() {
let extension = ExtensionTestUtils.loadExtension(extData);
yield extension.startup();
// Test sidebar is opened on install
yield extension.awaitMessage("sidebar");
ok(!document.getElementById("sidebar-box").hidden, "sidebar box is visible in first window");
// Check that the menuitem has our image styling.
let elements = document.getElementsByClassName("webextension-menuitem");
is(elements.length, 1, "have one menuitem");
let style = elements[0].getAttribute("style");
ok(style.includes("webextension-menuitem-image"), "this menu has style");
let secondSidebar = extension.awaitMessage("sidebar");
// SidebarUI relies on window.opener being set, which is normal behavior when
// using menu or key commands to open a new browser window.
let win = yield BrowserTestUtils.openNewBrowserWindow({opener: window});
yield secondSidebar;
ok(!win.document.getElementById("sidebar-box").hidden, "sidebar box is visible in second window");
// Check that the menuitem has our image styling.
elements = win.document.getElementsByClassName("webextension-menuitem");
is(elements.length, 1, "have one menuitem");
style = elements[0].getAttribute("style");
ok(style.includes("webextension-menuitem-image"), "this menu has style");
yield extension.unload();
yield BrowserTestUtils.closeWindow(win);
// Move toolbar button back to customization.
CustomizableUI.removeWidgetFromArea("sidebar-button", CustomizableUI.AREA_NAVBAR);
ok(!document.getElementById("sidebar-button"), "sidebar button is not in UI");
// This is set on initial sidebar install.
Services.prefs.clearUserPref("extensions.sidebar-button.shown");
});

Просмотреть файл

@ -19,7 +19,7 @@ module.exports = { // eslint-disable-line no-undef
"comma-dangle": "off",
"comma-spacing": ["warn", {"before": false, "after": true}],
"comma-style": ["warn", "last"],
// "complexity": "warn",
"complexity": ["error", {"max": 21}],
"consistent-return": "error",
//"curly": "error",
"dot-notation": "error",
@ -79,4 +79,3 @@ module.exports = { // eslint-disable-line no-undef
"yoda": "error"
}
};

Просмотреть файл

@ -432,7 +432,7 @@ ESEDB.prototype = {
// Deal with null values:
buffer = null;
} else {
Cu.reportError("Unexpected JET error: " + err + ";" + " retrieving value for column " + column.name);
Cu.reportError("Unexpected JET error: " + err + "; retrieving value for column " + column.name);
throw new Error(convertESEError(err));
}
}

Просмотреть файл

@ -30,7 +30,7 @@ add_task(function* test() {
} else {
page_with_title = test_title + " - " + app_name;
page_without_title = app_name;
about_pb_title = "Open a private window?" + " - " + app_name;
about_pb_title = "Open a private window? - " + app_name;
pb_page_with_title = test_title + " - " + app_name + " (Private Browsing)";
pb_page_without_title = app_name + " (Private Browsing)";
pb_about_pb_title = "Private Browsing - " + app_name + " (Private Browsing)";

Просмотреть файл

@ -109,7 +109,7 @@ module.exports = { // eslint-disable-line no-undef
"comma-dangle": ["error", "always-multiline"],
// Warn about cyclomatic complexity in functions.
"complexity": "warn",
"complexity": ["error", {"max": 20}],
// Don't warn for inconsistent naming when capturing this (not so important
// with auto-binding fat arrow functions).

Просмотреть файл

@ -72,7 +72,7 @@ add_task(function* test() {
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
function* (newTabBrowser) {
yield waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf" + "#zoom=100");
yield waitForPdfJS(newTabBrowser, TESTROOT + "file_pdfjs_test.pdf#zoom=100");
yield ContentTask.spawn(newTabBrowser, TESTS, function* (contentTESTS) {
let document = content.document;

Просмотреть файл

@ -26,7 +26,7 @@ add_task(function* () {
" color: orang;" +
// Override.
" background-color: blue;" +
" background-color: #f0c;" +
" background-color: #f06;" +
"} ");
let elementStyle = view._elementStyle;

Просмотреть файл

@ -14,10 +14,10 @@
* {String} result: expected value of the color property after edition.
*/
const colors = [
{name: "hex", id: "test1", color: "#f0c", result: "#0f0"},
{name: "hex", id: "test1", color: "#f06", result: "#0f0"},
{name: "rgb", id: "test2", color: "rgb(0,128,250)", result: "rgb(0, 255, 0)"},
// Test case preservation.
{name: "hex", id: "test3", color: "#F0C", result: "#0F0"},
{name: "hex", id: "test3", color: "#F06", result: "#0F0"},
];
add_task(function* () {

Просмотреть файл

@ -23,7 +23,7 @@ span {
background: #ffffff;
}
to {
background: #f0c;
background: #f06;
}
}

Просмотреть файл

@ -152,7 +152,7 @@ function testParseCssProperty(doc, parser) {
" 100%)"]),
// Note the lack of a space before the color here.
makeColorTest("border", "1px dotted#f0c", ["1px dotted ", {name: "#f0c"}]),
makeColorTest("border", "1px dotted#f06", ["1px dotted ", {name: "#f06"}]),
];
let target = doc.querySelector("div");

Просмотреть файл

@ -24,8 +24,8 @@ const CLASSIFY_TESTS = [
{ input: "hsl(5, 5%, 5%)", output: "hsl" },
{ input: "hsla(5, 5%, 5%, 0.25)", output: "hsl" },
{ input: "hSlA(5, 5%, 5%, 0.25)", output: "hsl" },
{ input: "#f0c", output: "hex" },
{ input: "#f0c0", output: "hex" },
{ input: "#f06", output: "hex" },
{ input: "#f060", output: "hex" },
{ input: "#fe01cb", output: "hex" },
{ input: "#fe01cb80", output: "hex" },
{ input: "#FE01CB", output: "hex" },

Просмотреть файл

@ -457,7 +457,7 @@ const TEST_DATA = [
{
desc: "delete disabled property",
input: "\n a:b;\n /* color:#f0c; */\n e:f;",
input: "\n a:b;\n /* color:#f06; */\n e:f;",
instruction: {type: "remove", name: "color", index: 1},
expected: "\n a:b;\n e:f;",
},
@ -469,7 +469,7 @@ const TEST_DATA = [
},
{
desc: "delete disabled property leaving other disabled property",
input: "\n a:b;\n /* color:#f0c; background-color: seagreen; */\n e:f;",
input: "\n a:b;\n /* color:#f06; background-color: seagreen; */\n e:f;",
instruction: {type: "remove", name: "color", index: 1},
expected: "\n a:b;\n /* background-color: seagreen; */\n e:f;",
},

Просмотреть файл

@ -2,7 +2,9 @@
# Summary
* [Tool Architectures](tools.md)
* [Inspector](inspector-panel.md)
* [Inspector](inspector.md)
* [Panel Architecture](inspector-panel.md)
* [Highlighters](highlighters.md)
* [Memory](memory-panel.md)
* [Debugger](debugger-panel.md)
* [Responsive Design Mode](responsive-design-mode.md)

Просмотреть файл

@ -0,0 +1,201 @@
# Highlighters
This article provides technical documentation about DevTools highlighters.
By highlighter, we mean anything that DevTools displays on top of the content page, in order to highlight an element, a set of elements or shapes to users.
The most obvious form of highlighter is the box-model highlighter, whose job is to display the 4 box-model regions on top of a given element in the content page, as illustrated in the following screen capture:
![Box-model highlighter](./img/box-model-highlighter-screenshot.png)
But there can be a wide variety of highlighters. In particular, highlighters are a pretty good way to give detailed information about:
* the exact form of a css shape,
* how a css transform applied to an element,
* where are the color stops of a css gradient,
* which are all the elements that match a given selector,
* ...
## Using highlighters
Highlighters run on the debuggee side, not on the toolbox side. This is so that it's possible to highlight elements on a remote device for instance. This means you need to go through the [Remote Debugging Protocol](protocol.md) to use a highlighter.
### The highlighter utils
The easiest way to access the highlighters from toolbox-side DevTools code is by using the highlighter utils, which is conveniently available on the toolbox object. Here is how you can access the utils:
```js
let hUtils = toolbox.highlighterUtils;
```
Since the box-model highlighter is the most used type of highlighter (for instance it's displayed when you move your mouse over nodes in the inspector), the utils provides a set of methods to interact with it:
| Method | Description |
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `startPicker()` | Starts the node picker mode which will highlight every node you hover over in the page, and will change the current node selection in the inspector on click. “picker-node-hovered” and “picker-node-picked” events are sent. |
| `stopPicker()` | Stops the node picker mode. |
| `highlightNodeFront(nodeFront)` | Display the box-model highlighter on a given node. NodeFront objects are what the WalkerActor return. |
| `highlightDomValueGrip(valueGrip)` | Display the box-model highlighter on a given node, represented by a debugger object value grip. |
| `unhighlight()` | Hide the box-model highlighter. |
But the box-model highlighter isn't the only type of highlighter, so the highlighter utils provides the following method:
| Method | Description |
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getHighlighterByType(typeName)` | Instantiate a new highlighter, given its type (as a String). At the time of writing, the available types of highlighters are: `BoxModelHighlighter`, `CssTransformHighlighter`, `SelectorHighlighter` and `RectHighlighter`. This returns a promise that resolves to the new instance of [protocol.js](https://wiki.mozilla.org/DevTools/protocol.js) actor. |
### The highlighter API
When getting a highlighter via `toolbox.highlighterUtils.getHighlighterByType(typeName)`, the right type of highlighter will be instantiated on the server-side and will be wrapped into a `CustomHighlighterActor` and that's what will be returned to the caller. This means that all types of highlighters share the same following API:
| Method | Description |
|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `show(NodeActor node[, Object options])` | Highlighters are hidden by default. Calling this method is what makes them visible. The first, mandatory, parameter should be a NodeActor. NodeActors are what the WalkerActor return. It's easy to get a NodeActor for an existing DOM node. For example `toolbox.walker.querySelector(toolbox.walker.rootNode, "css selector")` resolves to a NodeFront (the client-side version of the NodeActor) which can be used as the first parameter. The second, optional, parameter depends on the type of highlighter being used. |
| `hide()` | Hides the highlighter. |
| `finalize()` | Destroys the highlighter. |
## Creating new highlighters
Before digging into how one goes about adding a new type of highlighter to the DevTools, it is worth understanding how are highlighters displayed in the page.
### Inserting content in the page
Highlighters use web technology themselves to display the required information on screen. For instance, the box-model highlighter uses SVG to draw the margin, border, padding and content regions over the highlighted node.
This means the highlighter content needs to be inserted in the page, but in a non-intrusive way. Indeed, the DevTools should never alter the page unless the alteration was done by the user (like changing the DOM using the inspector or a CSS rule via the style-editor for example). So simply appending the highlighter's markup in the content document is not an option.
Furthermore, highlighters not only need to work with Firefox Desktop, but they should work just as well on Firefox OS, Firefox for Android, and more generally anything that runs the Gecko rendering engine. Therefore appending the highlighter's markup to the browser chrome XUL structure isn't an option either.
To this end, DevTools highlighters make use of a (chrome-only) API:
```
/**
* Chrome document anonymous content management.
* This is a Chrome-only API that allows inserting fixed positioned anonymous
* content on top of the current page displayed in the document.
* The supplied content is cloned and inserted into the document's CanvasFrame.
* Note that this only works for HTML documents.
*/
partial interface Document {
/**
* Deep-clones the provided element and inserts it into the CanvasFrame.
* Returns an AnonymousContent instance that can be used to manipulate the
* inserted element.
*/
[ChromeOnly, NewObject, Throws]
AnonymousContent insertAnonymousContent(Element aElement);
/**
* Removes the element inserted into the CanvasFrame given an AnonymousContent
* instance.
*/
[ChromeOnly, Throws]
void removeAnonymousContent(AnonymousContent aContent);
};
```
Using this API, it is possible for chrome-privileged JS to insert arbitrary DOM elements on top of the content page.
Technically, the DOM element is inserted into the `CanvasFrame` of the document. The `CanvasFrame` is part of the rendered frame tree and the DOM element is part of the native anonymous elements of the `CanvasFrame`.
Consider the following simple example:
```js
let el = document.createElement("div");
el.textContent = "My test element";
let insertedEl = document.insertAnonymousContent(el);
```
In this example, the test DIV will be inserted in the page, and will be displayed on top of everything else, in a way that doesn't impact the current layout.
### The AnonymousContent API
In the previous example, the returned `insertedEl` object isn't a DOM node, and it certainly is not `el`. It is a new object, whose type is `AnonymousContent` ([see the WebIDL here](http://mxr.mozilla.org/mozilla-central/source/dom/webidl/AnonymousContent.webidl?force=1)).
Because of the way content is inserted into the page, it isn't wanted to give consumers a direct reference to the inserted DOM node. This is why `document.insertAnonymousContent(el)` actually **clones** `el` and returns a new object whose API lets consumers make changes to the inserted element in a way that never gives back a reference to the inserted DOM node.
### CanvasFrameAnonymousContentHelper
In order to help with the API described in the previous section, the `CanvasFrameAnonymousContentHelper` class was introduced.
Its goal is to provide a simple way for highlighters to insert their content into the page and modify it dynamically later. One of its goal is also to re-insert the highlighters' content on page navigation. Indeed, the frame tree is destroyed when the page is navigated away from since it represents the document element.
Using this helper is quite simple:
```js
let helper = new CanvasFrameAnonymousContentHelper(tabActor, this.buildMarkup.bind(this));
```
It only requires a `tabActor`, which highlighters get when they are instantiated, and a callback function that will be used to create and insert the content the first time the highlighter is shown, and every time there's a page navigation.
The returned object provides the following API:
| Method | Description |
|-------------------------------------------|------------------------------------------------------------|
| `getTextContentForElement(id)` | Get the textContent of an element given its ID. |
| `setTextContentForElement(id, text)` | Set the textContent of an element given its ID. |
| `setAttributeForElement(id, name, value)` | Set an attribute value of an element given its ID. |
| `getAttributeForElement(id, name)` | Get an attribute value of an element given its ID. |
| `removeAttributeForElement(id, name)` | Remove an attribute of an element given its ID. |
| `content` | This property returns the wrapped AnonymousContent object. |
| `destroy()` | Destroy the helper instance. |
### Creating a new highlighter class
A good way to get started is by taking a look at [existing highlighters here](http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/highlighter.js).
Here is some boilerplate code for a new highlighter class:
```js
function MyNewHighlighter(tabActor) {
this.doc = tabActor.window.document;
this.markup = new CanvasFrameAnonymousContentHelper(tabActor, this._buildMarkup.bind(this));
}
MyNewHighlighter.prototype = {
destroy: function() {
this.doc = null;
this.markup.destroy();
},
_buildMarkup: function() {
let container = this.doc.createElement("div");
container.innerHTML = '<div id="new-highlighted-" style="display:none;">';
return container;
},
show: function(node, options) {
this.markup.removeAttributeForElement("new-highlighted-el", "style");
},
hide: function() {
this.markup.setAttributeForElement("new-highlighted-el", "style", "display:none;");
}
};
```
In most situations, the `container` returned by `_buildMarkup` will be absolutely positioned, and will need to contain elements with IDs, so that these can then later be moved, resized, hidden or shown in `show` and `hide` using the AnonymousContent API.
### The AutoRefreshHighlighter parent class
It is worth mentioning this class as it may be a useful parent class to inherit a new highlighter from in some situations.
If the new highlighter's job is to highlight an element in the DOM, then it most likely should inherit from `AutoRefreshHighlighter`.
The `AutoRefreshHighlighter` class updates itself in a loop, checking if the currently highlighted node's geometry has changed since the last iteration. This is useful to make sure the highlighter **follows** the highlighted node around, in case the layout around it changes, or in case it is an animated node.
Sub classes must implement the following methods:
| Method | Description |
|-------------|-------------------------------------------------------------------------------------|
| `_show()` | Called when the highlighter should be shown. |
| `_update()` | Called while the highlighter is shown and the geometry of the current node changes. |
| `_hide()` | Called when the highlighter should be hidden. |
Sub classes will have access to the following properties:
| Property | Description |
|---------------------|-------------------------------------------|
| `this.currentNode` | The node to be shown. |
| `this.currentQuads` | All of the node's box model region quads. |
| `this.win` | The current window |

Двоичные данные
devtools/docs/img/box-model-highlighter-screenshot.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Просмотреть файл

@ -0,0 +1,2 @@
These files provide information about the Inspector panel architecture.

Просмотреть файл

@ -38,7 +38,7 @@ exports.ProfilerActor = ActorClassWithSpec(profilerSpec, {
getBufferInfo: actorBridgeWithSpec("getBufferInfo"),
getStartOptions: actorBridgeWithSpec("getStartOptions"),
isActive: actorBridgeWithSpec("isActive"),
getSharedLibraryInformation: actorBridgeWithSpec("getSharedLibraryInformation"),
sharedLibraries: actorBridgeWithSpec("sharedLibraries"),
registerEventNotifications: actorBridgeWithSpec("registerEventNotifications"),
unregisterEventNotifications: actorBridgeWithSpec("unregisterEventNotifications"),
setProfilerStatusInterval: actorBridgeWithSpec("setProfilerStatusInterval"),

Просмотреть файл

@ -248,14 +248,12 @@ const ProfilerManager = (function () {
},
/**
* Returns a stringified JSON object that describes the shared libraries
* Returns an array of objects that describes the shared libraries
* which are currently loaded into our process. Can be called while the
* profiler is stopped.
*/
getSharedLibraryInformation: function () {
return {
sharedLibraryInformation: nsIProfilerModule.getSharedLibraryInformation()
};
get sharedLibraries() {
return nsIProfilerModule.sharedLibraries;
},
/**
@ -471,10 +469,10 @@ var Profiler = exports.Profiler = Class({
},
/**
* @see ProfilerManager.isActive
* @see ProfilerManager.sharedLibraries
*/
getSharedLibraryInformation: function () {
return ProfilerManager.getSharedLibraryInformation();
sharedLibraries: function () {
return ProfilerManager.sharedLibraries;
},
/**

Просмотреть файл

@ -8,7 +8,7 @@
const {StyleSheetsFront} = require("devtools/shared/fronts/stylesheets");
const CONTENT = "<style>body { background-color: #f0c; }</style>";
const CONTENT = "<style>body { background-color: #f06; }</style>";
const TEST_URI = "data:text/html;charset=utf-8," + encodeURIComponent(CONTENT);
add_task(function* () {

Просмотреть файл

@ -4,16 +4,14 @@
"use strict";
/**
* Tests whether the profiler responds to "getSharedLibraryInformation" adequately.
* Tests whether the profiler responds to "sharedLibraries" adequately.
*/
const Profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
function run_test()
{
get_chrome_actors((client, form) => {
let actor = form.profilerActor;
test_getsharedlibraryinformation(client, actor, () => {
test_sharedlibraries(client, actor, () => {
client.close().then(() => {
do_test_finished();
});
@ -23,20 +21,19 @@ function run_test()
do_test_pending();
}
function test_getsharedlibraryinformation(client, actor, callback)
function test_sharedlibraries(client, actor, callback)
{
client.request({ to: actor, type: "getSharedLibraryInformation" }, response => {
do_check_eq(typeof response.sharedLibraryInformation, "string");
let libs = [];
try {
libs = JSON.parse(response.sharedLibraryInformation);
} catch (e) {
do_check_true(false);
}
client.request({ to: actor, type: "sharedLibraries" }, libs => {
do_check_eq(typeof libs, "object");
do_check_true(Array.isArray(libs));
do_check_eq(typeof libs, "object");
do_check_true(libs.length >= 1);
do_check_eq(typeof libs[0], "object");
do_check_eq(typeof libs[0].name, "string");
do_check_eq(typeof libs[0].path, "string");
do_check_eq(typeof libs[0].debugName, "string");
do_check_eq(typeof libs[0].debugPath, "string");
do_check_eq(typeof libs[0].arch, "string");
do_check_eq(typeof libs[0].start, "number");
do_check_eq(typeof libs[0].end, "number");
do_check_true(libs[0].start <= libs[0].end);

Просмотреть файл

@ -203,7 +203,7 @@ reason = only ran on B2G
[test_profiler_events-02.js]
[test_profiler_getbufferinfo.js]
[test_profiler_getfeatures.js]
[test_profiler_getsharedlibraryinformation.js]
[test_profiler_sharedlibraries.js]
[test_unsafeDereference.js]
[test_add_actors.js]
[test_ignore_caught_exceptions.js]

Просмотреть файл

@ -92,7 +92,7 @@ const profilerSpec = generateActorSpec({
isActive: {
response: RetVal("json")
},
getSharedLibraryInformation: {
sharedLibraries: {
response: RetVal("json")
},
registerEventNotifications: {

Просмотреть файл

@ -0,0 +1,19 @@
<html>
<head>
<style>
body, html {
height: 100%;
}
.spacer {
height: 80%;
}
</style>
</head>
<body onload='(parent || opener).childLoad()'>
<div class="spacer"></div>
<div id="content">content</div>
<div class="spacer"></div>
</body>
</html>

Просмотреть файл

@ -33,6 +33,7 @@ support-files =
file_bug680257.html
file_bug703855.html
file_bug728939.html
file_bug1151421.html
file_pushState_after_document_open.html
historyframes.html
@ -86,6 +87,7 @@ support-files = file_bug668513.html
[test_bug797909.html]
[test_bug1045096.html]
[test_bug1121701.html]
[test_bug1151421.html]
[test_bug1186774.html]
[test_forceinheritprincipal_overrule_owner.html]
[test_framedhistoryframes.html]

Просмотреть файл

@ -26,7 +26,7 @@
}
case 2: {
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
opener.isnot(window.scrollY, 0, "Should have restored scrolling.");
opener.isnot(Math.round(window.scrollY), 0, "Should have restored scrolling.");
opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload.");
history.scrollRestoration = "manual";
window.onunload = function() {} // Disable bfcache.
@ -45,7 +45,7 @@
}
case 4: {
opener.is(event.persisted, true, "Should have persisted session history entry.");
opener.isnot(window.scrollY, 0, "Should have kept the old scroll position.");
opener.isnot(Math.round(window.scrollY), 0, "Should have kept the old scroll position.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
window.scrollTo(0, 0);
window.location.hash = "hash";
@ -53,7 +53,7 @@
break;
}
case 5: {
opener.isnot(window.scrollY, 0, "Should have scrolled to #hash.");
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to #hash.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
window.onunload = function() {} // Disable bfcache.
opener.setTimeout("is(testWindow.history.scrollRestoration, 'auto'); testWindow.history.back();", 250);
@ -70,7 +70,7 @@
history.pushState({ state: "state2" }, "state2");
window.scrollTo(0, 0);
history.back();
opener.isnot(window.scrollY, 0, "Should have scrolled back to the state1's position");
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state1's position");
opener.is(history.state.state, "state1", "Unexpected state.");
history.scrollRestoration = "manual";
@ -79,17 +79,17 @@
history.pushState({ state: "state4" }, "state4");
window.scrollTo(0, 0);
history.back();
opener.is(window.scrollY, 0, "Shouldn't have scrolled back to the state3's position");
opener.is(Math.round(window.scrollY), 0, "Shouldn't have scrolled back to the state3's position");
opener.is(history.state.state, "state3", "Unexpected state.");
history.pushState({ state: "state5" }, "state5");
history.scrollRestoration = "auto";
document.getElementById("bottom").scrollIntoView();
opener.isnot(window.scrollY, 0, "Should have scrolled to 'bottom'.");
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to 'bottom'.");
history.back();
window.scrollTo(0, 0);
history.forward();
opener.isnot(window.scrollY, 0, "Should have scrolled back to the state5's position");
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state5's position");
var ifr = document.createElement("iframe");
ifr.src = "data:text/html,";

Просмотреть файл

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1151421
-->
<head>
<title>Test for Bug 1151421</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1151421">Mozilla Bug 1151421</a>
<script type="application/javascript">
/** Test for Bug 1151421 **/
SimpleTest.waitForExplicitFinish();
function childLoad() {
// Spin the event loop so we leave the onload handler.
SimpleTest.executeSoon(childLoad2);
}
function childLoad2() {
let cw = iframe.contentWindow;
let content = cw.document.getElementById("content");
// Create a function to calculate an invariant.
let topPlusOffset = function()
{
return Math.round(content.getBoundingClientRect().top + cw.pageYOffset);
}
let initialTPO = topPlusOffset();
// Scroll the iframe to various positions, and check the TPO.
// Scrolling down to the bottom will adjust the page offset by a fractional amount.
let positions = [-100, 0.17, 0, 1.5, 10.41, 1e6, 12.1];
// Run some tests with scrollTo() and ensure we have the same invariant after scrolling.
positions.forEach(function(pos) {
cw.scrollTo(0, pos);
is(topPlusOffset(), initialTPO, "Top plus offset should remain invariant across scrolling.");
});
positions.reverse().forEach(function(pos) {
cw.scrollTo(0, pos);
is(topPlusOffset(), initialTPO, "(reverse) Top plus offset should remain invariant across scrolling.");
});
SimpleTest.finish();
}
</script>
<!-- When the iframe loads, it calls childLoad(). -->
<br>
<iframe height='100px' id='iframe' src='file_bug1151421.html'></iframe>
</body>
</html>

Просмотреть файл

@ -28,7 +28,7 @@ function runTest() {
}
child.onpopstate = function() {
is(child.scrollY, 6000, "Shouldn't have scrolled before popstate");
is(Math.round(child.scrollY), 6000, "Shouldn't have scrolled before popstate");
child.close();
SimpleTest.finish();
}

Просмотреть файл

@ -147,21 +147,21 @@ function* testBody()
popup.scroll(0, 100);
popup.history.pushState('', '', '?pushed');
is(popup.scrollY, 100, "test 2");
is(Math.round(popup.scrollY), 100, "test 2");
popup.scroll(0, 200); // set state-2's position to 200
popup.history.back();
is(popup.scrollY, 100, "test 3");
is(Math.round(popup.scrollY), 100, "test 3");
popup.scroll(0, 150); // set original page's position to 150
popup.history.forward();
is(popup.scrollY, 200, "test 4");
is(Math.round(popup.scrollY), 200, "test 4");
popup.history.back();
is(popup.scrollY, 150, "test 5");
is(Math.round(popup.scrollY), 150, "test 5");
popup.history.forward();
is(popup.scrollY, 200, "test 6");
is(Math.round(popup.scrollY), 200, "test 6");
// At this point, the history looks like:
// PATH POSITION
@ -202,13 +202,13 @@ function* testBody()
is(popup.location.search, "?pushed");
ok(popup.document.getElementById('div1'), 'page should have div1.');
is(popup.scrollY, 200, "test 8");
is(Math.round(popup.scrollY), 200, "test 8");
popup.history.back();
is(popup.scrollY, 150, "test 9");
is(Math.round(popup.scrollY), 150, "test 9");
popup.history.forward();
is(popup.scrollY, 200, "test 10");
is(Math.round(popup.scrollY), 200, "test 10");
// Spin one last time...
setTimeout(pageLoad, 0);

Просмотреть файл

@ -24,10 +24,10 @@ function childLoad() {
function childLoad2() {
let cw = $('iframe').contentWindow;
// Save the Y offset. For sanity's sake, make sure it's not 0, because we
// should be at the bottom of the page!
let origYOffset = cw.pageYOffset;
let origYOffset = Math.round(cw.pageYOffset);
ok(origYOffset != 0, 'Original Y offset is not 0.');
// Scroll the iframe to the top, then navigate to #bottom again.
@ -37,7 +37,7 @@ function childLoad2() {
// bottom again.
cw.location = cw.location + '';
is(cw.pageYOffset, origYOffset, 'Correct offset after reloading page.');
is(Math.round(cw.pageYOffset), origYOffset, 'Correct offset after reloading page.');
SimpleTest.finish();
}

Просмотреть файл

@ -27,12 +27,12 @@ function childLoad2() {
// When we initially load the page, we should be at the top.
is(cw.pageYOffset, 0, 'Initial Y offset should be 0.');
// Scroll the iframe to the bottom.
cw.scrollTo(0, 300);
// Did we actually scroll somewhere?
isnot(cw.pageYOffset, 0, 'Y offset should be non-zero after scrolling.');
isnot(Math.round(cw.pageYOffset), 0, 'Y offset should be non-zero after scrolling.');
// Now load file_bug662170.html#, which should take us to the top of the
// page.

Просмотреть файл

@ -1213,7 +1213,8 @@ Navigator::SendBeaconInternal(const nsAString& aUrl,
aRv.Throw(NS_ERROR_DOM_BAD_URI);
return false;
}
rv = httpChannel->SetReferrer(documentURI);
mozilla::net::ReferrerPolicy referrerPolicy = doc->GetReferrerPolicy();
rv = httpChannel->SetReferrerWithPolicy(documentURI, referrerPolicy);
MOZ_ASSERT(NS_SUCCEEDED(rv));
nsCOMPtr<nsIInputStream> in;

Просмотреть файл

@ -1487,7 +1487,8 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
#ifdef DEBUG
mIsValidatingTabGroup(false),
#endif
mCanSkipCCGeneration(0)
mCanSkipCCGeneration(0),
mAutoActivateVRDisplayID(0)
{
AssertIsOnMainThread();
@ -3781,6 +3782,27 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor)
mIsHandlingResizeEvent = false;
} else if (aVisitor.mEvent->mMessage == eUnload &&
aVisitor.mEvent->IsTrusted()) {
// If any VR display presentation is active at unload, the next page
// will receive a vrdisplayactive event to indicate that it should
// immediately begin vr presentation. This should occur when navigating
// forwards, navigating backwards, and on page reload.
for (auto display : mVRDisplays) {
if (display->IsPresenting()) {
// Save this VR display ID to trigger vrdisplayactivate event
// after the next load event.
nsGlobalWindow* outer = GetOuterWindowInternal();
if (outer) {
outer->SetAutoActivateVRDisplayID(display->DisplayId());
}
// XXX The WebVR 1.1 spec does not define which of multiple VR
// presenting VR displays will be chosen during navigation.
// As the underlying platform VR API's currently only allow a single
// VR display, it is safe to choose the first VR display for now.
break;
}
}
// Execute bindingdetached handlers before we tear ourselves
// down.
if (mDoc) {
@ -3814,6 +3836,16 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor)
// null as the pres context all the time here.
EventDispatcher::Dispatch(element, nullptr, &event, nullptr, &status);
}
uint32_t autoActivateVRDisplayID = 0;
nsGlobalWindow* outer = GetOuterWindowInternal();
if (outer) {
autoActivateVRDisplayID = outer->GetAutoActivateVRDisplayID();
}
if (autoActivateVRDisplayID) {
DispatchVRDisplayActivate(autoActivateVRDisplayID,
VRDisplayEventReason::Navigation);
}
}
return NS_OK;
@ -6337,7 +6369,7 @@ nsGlobalWindow::GetScrollMaxY(ErrorResult& aError)
FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0);
}
CSSIntPoint
CSSPoint
nsGlobalWindow::GetScrollXY(bool aDoFlush)
{
MOZ_ASSERT(IsOuterWindow());
@ -6361,30 +6393,30 @@ nsGlobalWindow::GetScrollXY(bool aDoFlush)
return GetScrollXY(true);
}
return sf->GetScrollPositionCSSPixels();
return CSSPoint::FromAppUnits(scrollPos);
}
int32_t
double
nsGlobalWindow::GetScrollXOuter()
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
return GetScrollXY(false).x;
}
int32_t
double
nsGlobalWindow::GetScrollX(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0);
}
int32_t
double
nsGlobalWindow::GetScrollYOuter()
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
return GetScrollXY(false).y;
}
int32_t
double
nsGlobalWindow::GetScrollY(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0);
@ -13503,6 +13535,22 @@ nsGlobalWindow::NotifyActiveVRDisplaysChanged()
}
}
uint32_t
nsGlobalWindow::GetAutoActivateVRDisplayID()
{
MOZ_ASSERT(IsOuterWindow());
uint32_t retVal = mAutoActivateVRDisplayID;
mAutoActivateVRDisplayID = 0;
return retVal;
}
void
nsGlobalWindow::SetAutoActivateVRDisplayID(uint32_t aAutoActivateVRDisplayID)
{
MOZ_ASSERT(IsOuterWindow());
mAutoActivateVRDisplayID = aAutoActivateVRDisplayID;
}
void
nsGlobalWindow::DispatchVRDisplayActivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason)
@ -13510,10 +13558,14 @@ nsGlobalWindow::DispatchVRDisplayActivate(uint32_t aDisplayID,
// Search for the display identified with aDisplayID and fire the
// event if found.
for (auto display : mVRDisplays) {
if (display->DisplayId() == aDisplayID
&& !display->IsAnyPresenting()) {
// We only want to trigger this event if nobody is presenting to the
// display already.
if (display->DisplayId() == aDisplayID) {
if (aReason != VRDisplayEventReason::Navigation &&
display->IsAnyPresenting()) {
// We only want to trigger this event if nobody is presenting to the
// display already or when a page is loaded by navigating away
// from a page with an active VR Presentation.
continue;
}
VRDisplayEventInit init;
init.mBubbles = false;

Просмотреть файл

@ -767,6 +767,11 @@ public:
// Called to inform that the set of active VR displays has changed.
void NotifyActiveVRDisplaysChanged();
// Outer windows only.
uint32_t GetAutoActivateVRDisplayID();
// Outer windows only.
void SetAutoActivateVRDisplayID(uint32_t aAutoActivateVRDisplayID);
void DispatchVRDisplayActivate(uint32_t aDisplayID,
mozilla::dom::VRDisplayEventReason aReason);
void DispatchVRDisplayDeactivate(uint32_t aDisplayID,
@ -1090,15 +1095,15 @@ public:
void SetInnerHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aError);
int32_t GetScrollXOuter();
int32_t GetScrollX(mozilla::ErrorResult& aError);
int32_t GetPageXOffset(mozilla::ErrorResult& aError)
double GetScrollXOuter();
double GetScrollX(mozilla::ErrorResult& aError);
double GetPageXOffset(mozilla::ErrorResult& aError)
{
return GetScrollX(aError);
}
int32_t GetScrollYOuter();
int32_t GetScrollY(mozilla::ErrorResult& aError);
int32_t GetPageYOffset(mozilla::ErrorResult& aError)
double GetScrollYOuter();
double GetScrollY(mozilla::ErrorResult& aError);
double GetPageYOffset(mozilla::ErrorResult& aError)
{
return GetScrollY(aError);
}
@ -1635,7 +1640,7 @@ public:
// If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
// just flush our parent and only flush ourselves if we think we need to.
// Outer windows only.
mozilla::CSSIntPoint GetScrollXY(bool aDoFlush);
mozilla::CSSPoint GetScrollXY(bool aDoFlush);
int32_t GetScrollBoundaryOuter(mozilla::Side aSide);
@ -2040,6 +2045,11 @@ protected:
RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
// When non-zero, the document should receive a vrdisplayactivate event
// after loading. The value is the ID of the VRDisplay that content should
// begin presentation on.
uint32_t mAutoActivateVRDisplayID; // Outer windows only
#ifdef ENABLE_INTL_API
RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
#endif

Просмотреть файл

@ -28,10 +28,10 @@ function subtest(winProp, elemProp, win, correctElement, elemToSet, otherElem1,
win.scrollTo(50, 50);
elemToSet[elemProp] = 100;
if (elemToSet == correctElement) {
is(win[winProp], 100, "Setting " + elemToSet.name + "." + elemProp + " should scroll");
is(Math.round(win[winProp]), 100, "Setting " + elemToSet.name + "." + elemProp + " should scroll");
is(elemToSet[elemProp], 100, "Reading back " + elemToSet.name + "." + elemProp + " after scrolling");
} else {
is(win[winProp], 50, "Setting " + elemToSet.name + "." + elemProp + " should not scroll");
is(Math.round(win[winProp]), 50, "Setting " + elemToSet.name + "." + elemProp + " should not scroll");
is(elemToSet[elemProp], 0, "Reading back " + elemToSet.name + "." + elemProp + " after not scrolling");
}
if (otherElem1 == correctElement) {

Просмотреть файл

@ -16,8 +16,8 @@ function runTest() {
iframe.addEventListener("mozbrowserscroll", function(e) {
ok(true, "got mozbrowserscroll event.");
ok(e.detail, "event.detail is not null.");
ok(e.detail.top === 4000, "top position is correct.");
ok(e.detail.left === 4000, "left position is correct.");
ok(Math.round(e.detail.top) == 4000, "top position is correct.");
ok(Math.round(e.detail.left) == 4000, "left position is correct.");
SimpleTest.finish();
});

Просмотреть файл

@ -12,7 +12,7 @@
namespace mozilla {
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 9
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 12
/**
* EventStates is the class used to represent the event states of nsIContent
@ -217,6 +217,12 @@ private:
// Content is the full screen element, or a frame containing the
// current full-screen element.
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(9)
// Content is valid (and can be invalid).
#define NS_EVENT_STATE_VALID NS_DEFINE_EVENT_STATE_MACRO(10)
// Content is invalid.
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(11)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
/*
* Bits below here do not have Servo-related ordering constraints.
@ -226,54 +232,48 @@ private:
*/
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(10)
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(13)
// Content is required.
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(11)
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(14)
// Content is optional (and can be required).
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(12)
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(15)
// Link has been visited.
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(13)
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(16)
// Link hasn't been visited.
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(14)
// Content is valid (and can be invalid).
#define NS_EVENT_STATE_VALID NS_DEFINE_EVENT_STATE_MACRO(15)
// Content is invalid.
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(16)
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(17)
// Content value is in-range (and can be out-of-range).
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(17)
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(18)
// Content value is out-of-range.
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(18)
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(19)
// These two are temporary (see bug 302188)
// Content is read-only.
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(19)
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(20)
// Content is editable.
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(20)
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(21)
// Content is the default one (meaning depends of the context).
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(21)
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(22)
// Content could not be rendered (image/object/etc).
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(22)
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(23)
// Content disabled by the user (images turned off, say).
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(23)
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(24)
// Content suppressed by the user (ad blocking, etc).
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(24)
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(25)
// Content is still loading such that there is nothing to show the
// user (eg an image which hasn't started coming in yet).
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(25)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(26)
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(26)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(27)
// Handler for the content has been blocked.
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(27)
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(28)
// Handler for the content has been disabled.
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(28)
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(29)
// Handler for the content has crashed
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(29)
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(30)
// Content has focus and should show a ring.
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(30)
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(31)
// Content is a submit control and the form isn't valid.
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(32)
// UI friendly version of :invalid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(33)
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(34)
// Handler for click to play plugin

Просмотреть файл

@ -225,7 +225,7 @@ RemoveControlCharactersFrom(nsAString& aStr, TextRangeArray* aRanges)
size_t i = firstControlCharOffset;
for (const char16_t* source = sourceBegin + firstControlCharOffset;
source < sourceEnd; ++source) {
if (*source == '\t' || !IsControlChar(*source)) {
if (*source == '\t' || *source == '\n' || !IsControlChar(*source)) {
*curDest = *source;
++curDest;
++i;

Просмотреть файл

@ -1527,11 +1527,11 @@ HTMLMediaElement::SetVisible(bool aVisible)
mDecoder->SetForcedHidden(!aVisible);
}
layers::Image*
already_AddRefed<layers::Image>
HTMLMediaElement::GetCurrentImage()
{
// Mark the decoder owned by the element as tainted so that the
// suspend-vide-decoder is suspended.
// suspend-video-decoder is disabled.
mHasSuspendTaint = true;
if (mDecoder) {
mDecoder->SetSuspendTaint(true);
@ -1544,7 +1544,8 @@ HTMLMediaElement::GetCurrentImage()
}
AutoLockImage lockImage(container);
return lockImage.GetImage();
RefPtr<layers::Image> image = lockImage.GetImage();
return image.forget();
}
bool

Просмотреть файл

@ -629,7 +629,7 @@ public:
// This function is synchronous for cases where decoding has been suspended
// and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement()
// via drawImage().
layers::Image* GetCurrentImage();
already_AddRefed<layers::Image> GetCurrentImage();
already_AddRefed<DOMMediaStream> GetSrcObject() const;
void SetSrcObject(DOMMediaStream& aValue);

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/dom/TextTrackRegion.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "nsGlobalWindow.h"
namespace mozilla {
namespace dom {
@ -330,8 +331,13 @@ TextTrack::GetLanguage(nsAString& aLanguage) const
void
TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName)
{
nsPIDOMWindowInner* win = GetOwner();
if (!win) {
return;
}
RefPtr<TextTrack> self = this;
NS_DispatchToMainThread(
nsGlobalWindow::Cast(win)->Dispatch(
"TextTrack::DispatchAsyncTrustedEvent", TaskCategory::Other,
NS_NewRunnableFunction([self, aEventName]() {
self->DispatchTrustedEvent(aEventName);
})

Просмотреть файл

@ -136,6 +136,9 @@ TextTrackCue::GetCueAsHTML()
nsCOMPtr<nsIDOMDocumentFragment> frag;
sParserWrapper->ConvertCueToDOMTree(window, this,
getter_AddRefs(frag));
if (!frag) {
return mDocument->CreateDocumentFragment();
}
return frag.forget().downcast<DocumentFragment>();
}

Просмотреть файл

@ -317,6 +317,10 @@ Cu.import('resource://gre/modules/Services.jsm');
}
var m = input.match(/^([^<]*)(<[^>]+>?)?/);
// The input doesn't contain a complete tag.
if (!m[0]) {
return null;
}
// If there is some text before the next tag, return it, otherwise return
// the tag.
return consume(m[1] ? m[1] : m[2]);

Просмотреть файл

@ -271,7 +271,7 @@ CSP_CreateHostSrcFromURI(nsIURI* aURI)
{
// Create the host first
nsCString host;
aURI->GetHost(host);
aURI->GetAsciiHost(host);
nsCSPHostSrc *hostsrc = new nsCSPHostSrc(NS_ConvertUTF8toUTF16(host));
// Add the scheme.
@ -643,7 +643,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
// Before we can check if the host matches, we have to
// extract the host part from aUri.
nsAutoCString uriHost;
nsresult rv = aUri->GetHost(uriHost);
nsresult rv = aUri->GetAsciiHost(uriHost);
NS_ENSURE_SUCCESS(rv, false);
nsString decodedUriHost;

Просмотреть файл

@ -0,0 +1,2 @@
const LOADED = true;
parent.postMessage({result: 'script-allowed'}, "*");

Просмотреть файл

@ -0,0 +1,45 @@
// custom *.sjs for Bug 1224225
// Punycode in CSP host sources
const HTML_PART1 =
"<!DOCTYPE HTML>" +
"<html><head><meta charset=\"utf-8\">" +
"<title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>" +
"</head>" +
"<body>" +
"<script id='script' src='";
const TESTCASE1 = "http://sub2.ält.example.org/";
const TESTCASE2 = "http://sub2.xn--lt-uia.example.org/"
const HTML_PART2 = "tests/dom/security/test/csp/file_punycode_host_src.js'></script>" +
"</body>" +
"</html>";
function handleRequest(request, response)
{
// avoid confusing cache behaviors
response.setHeader("Cache-Control", "no-cache", false);
response.setHeader("Content-Type", "text/html", false);
Components.utils.importGlobalProperties(["URLSearchParams"]);
const query = new URLSearchParams(request.queryString);
if (query.get("csp")) {
response.setHeader("Content-Security-Policy", query.get("csp"), false);
}
if (query.get("action") == "script-unicode-csp-punycode") {
response.write(HTML_PART1 + TESTCASE1 + HTML_PART2);
return
}
if (query.get("action") == "script-punycode-csp-punycode") {
response.write(HTML_PART1 + TESTCASE2 + HTML_PART2);
return
}
// we should never get here, but just in case
// return something unexpected
response.write("do'h");
}

Просмотреть файл

@ -203,6 +203,8 @@ support-files =
file_strict_dynamic_default_src.html
file_strict_dynamic_default_src.js
file_upgrade_insecure_navigation.sjs
file_punycode_host_src.sjs
file_punycode_host_src.js
[test_base-uri.html]
[test_blob_data_schemes.html]
@ -290,3 +292,4 @@ tags = mcb
[test_strict_dynamic_parser_inserted.html]
[test_strict_dynamic_default_src.html]
[test_upgrade_insecure_navigation.html]
[test_punycode_host_src.html]

Просмотреть файл

@ -0,0 +1,81 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe style="width:100%;" id="testframe"></iframe>
<script class="testbody" type="text/javascript">
/* Description of the test:
* We load scripts within an iframe and make sure that the
* CSP matching is same for punycode domain names as well as IDNA.
*/
SimpleTest.waitForExplicitFinish();
var curTest;
var counter = -1;
const tests = [
{ // test 1
description: "loads script as sub2.ält.example.org, but whitelist in CSP as sub2.xn--lt-uia.example.org",
action: "script-unicode-csp-punycode",
csp: "script-src http://sub2.xn--lt-uia.example.org;",
expected: "script-allowed",
},
{ // test 2
description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
action: "script-punycode-csp-punycode",
csp: "script-src http://sub2.xn--lt-uia.example.org;",
expected: "script-allowed",
},
{ // test 3
description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
action: "script-punycode-csp-punycode",
csp: "script-src *.xn--lt-uia.example.org;",
expected: "script-allowed",
},
];
function finishTest() {
window.removeEventListener("message", receiveMessage);
SimpleTest.finish();
}
function checkResults(result) {
is(result, curTest.expected, curTest.description);
loadNextTest();
}
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
checkResults(event.data.result);
}
function loadNextTest() {
counter++;
if (counter == tests.length) {
finishTest();
return;
}
curTest = tests[counter];
var testframe = document.getElementById("testframe");
testframe.src = `file_punycode_host_src.sjs?action=${curTest.action}&csp=${curTest.csp}`;
}
loadNextTest();
</script>
</body>
</html>

Просмотреть файл

@ -204,6 +204,8 @@ TEST(CSPParser, Directives)
{
static const PolicyTest policies[] =
{
{ "connect-src xn--mnchen-3ya.de",
"connect-src http://xn--mnchen-3ya.de"},
{ "default-src http://www.example.com",
"default-src http://www.example.com" },
{ "script-src http://www.example.com",

Просмотреть файл

@ -31,13 +31,13 @@
function checkGetScrollXYState(flush, vals, testName) {
let scrollX = {}, scrollY = {};
domWindowUtils.getScrollXY(flush, scrollX, scrollY);
is(scrollX.value, vals[0], "getScrollXY x for test: " + testName);
is(scrollY.value, vals[1], "getScrollXY y for test: " + testName);
is(Math.round(scrollX.value), vals[0], "getScrollXY x for test: " + testName);
is(Math.round(scrollY.value), vals[1], "getScrollXY y for test: " + testName);
}
function checkWindowScrollState(vals, testName) {
is(cwindow.scrollX, vals[0], "scrollX for test: " + testName);
is(cwindow.scrollY, vals[1], "scrollY for test: " + testName);
is(Math.round(cwindow.scrollX), vals[0], "scrollX for test: " + testName);
is(Math.round(cwindow.scrollY), vals[1], "scrollY for test: " + testName);
}
// Check initial state (0, 0)
@ -67,8 +67,8 @@
let scrollX = {}, scrollY = {};
domWindowUtils.getScrollXY(false, scrollX, scrollY);
is(scrollX.value, 0, "scrollX is zero for display:none iframe");
is(scrollY.value, 0, "scrollY is zero for display:none iframe");
is(Math.round(scrollX.value), 0, "scrollX is zero for display:none iframe");
is(Math.round(scrollY.value), 0, "scrollY is zero for display:none iframe");
}
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -28,6 +28,7 @@ NS_IMPL_RELEASE_INHERITED(VRMockDisplay, DOMEventTargetHelper)
VRMockDisplay::VRMockDisplay(const nsCString& aID, uint32_t aDeviceID)
: mDeviceID(aDeviceID)
, mTimestamp(TimeStamp::Now())
{
mDisplayInfo.mDisplayName = aID;
mDisplayInfo.mType = VRDeviceType::Puppet;
@ -77,6 +78,8 @@ VRMockDisplay::SetPose(const Nullable<Float32Array>& aPosition,
const Nullable<Float32Array>& aAngularVelocity,
const Nullable<Float32Array>& aAngularAcceleration)
{
mSensorState.Clear();
mSensorState.timestamp = (TimeStamp::Now() - mTimestamp).ToSeconds();
mSensorState.flags = VRDisplayCapabilityFlags::Cap_Orientation |
VRDisplayCapabilityFlags::Cap_Position |
VRDisplayCapabilityFlags::Cap_AngularAcceleration |

Просмотреть файл

@ -36,6 +36,7 @@ private:
uint32_t mDeviceID;
gfx::VRDisplayInfo mDisplayInfo;
gfx::VRHMDSensorState mSensorState;
TimeStamp mTimestamp;
};
class VRMockController : public DOMEventTargetHelper

Просмотреть файл

@ -1,33 +1,40 @@
var VRServiceTest;
var vrMockDisplay;
var VRSimulationDriver = (function() {
"use strict";
var AttachWebVRDisplay = function() {
return VRServiceTest.attachVRDisplay("VRDisplayTest");
var promise = VRServiceTest.attachVRDisplay("VRDisplayTest");
promise.then(function (display) {
assert_true(display != null, "AttachWebVRDisplay should success.");
vrMockDisplay = display;
});
return promise;
};
var SetVRDisplayPose = function(vrDisplay, position,
var SetVRDisplayPose = function(position,
linearVelocity, linearAcceleration,
orientation, angularVelocity,
angularAcceleration) {
vrDisplay.setPose(position, linearVelocity, linearAcceleration,
orientation, angularVelocity, angularAcceleration);
vrMockDisplay.setPose(position, linearVelocity, linearAcceleration,
orientation, angularVelocity, angularAcceleration);
};
var SetEyeResolution = function(width, height) {
vrDisplay.setEyeResolution(width, height);
vrMockDisplay.setEyeResolution(width, height);
}
var SetEyeParameter = function(vrDisplay, eye, offsetX, offsetY, offsetZ,
var SetEyeParameter = function(eye, offsetX, offsetY, offsetZ,
upDegree, rightDegree, downDegree, leftDegree) {
vrDisplay.setEyeParameter(eye, offsetX, offsetY, offsetZ, upDegree, rightDegree,
downDegree, leftDegree);
vrMockDisplay.setEyeParameter(eye, offsetX, offsetY, offsetZ, upDegree, rightDegree,
downDegree, leftDegree);
}
var UpdateVRDisplay = function(vrDisplay) {
vrDisplay.update();
var UpdateVRDisplay = function() {
vrMockDisplay.update();
}
var API = {

Просмотреть файл

@ -5,5 +5,6 @@ support-files =
runVRTest.js
WebVRHelpers.js
[test_vrDisplay_getFrameData.html]
[test_vrDisplay_requestPresent.html]
skip-if = true
skip-if = true

Просмотреть файл

@ -2,6 +2,11 @@
//
// This file provides helpers for testing VRDisplay requestPresent.
function attachVRDisplay(test) {
assert_equals(typeof (navigator.getVRDisplays), "function", "'navigator.getVRDisplays()' must be defined.");
return VRSimulationDriver.AttachWebVRDisplay();
}
function setupVRDisplay(test) {
assert_equals(typeof (navigator.getVRDisplays), "function", "'navigator.getVRDisplays()' must be defined.");
return VRSimulationDriver.AttachWebVRDisplay().then(() => {

Просмотреть файл

@ -1,6 +1,7 @@
function runVRTest(callback) {
SpecialPowers.pushPrefEnv({"set" : [["dom.vr.enabled", true],
["dom.vr.puppet.enabled", true],
["dom.vr.require-gesture", false],
["dom.vr.test.enabled", true]]},
() => {
VRServiceTest = navigator.requestVRServiceTest();

Просмотреть файл

@ -0,0 +1,150 @@
<!DOCTYPE html>
<html>
<head>
<title>VRDisplay GetFrameData</title>
<meta name="timeout" content="long"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="VRSimulationDriver.js"></script>
<script src="WebVRHelpers.js"></script>
<script src="requestPresent.js"></script>
<script src="runVRTest.js"></script>
</head>
<body id="body">
<canvas id="webglCanvas"></canvas>
<div id="testDiv"></div>
<script>
"use strict";
var vrDisplay;
var vrRAF;
var canvas = document.getElementById('webglCanvas');
var div = document.getElementById('testDiv');
function startTest() {
promise_test((test) => {
return attachVRDisplay(test).then(() => {
VRSimulationDriver.SetEyeResolution(1332, 1586);
VRSimulationDriver.SetEyeParameter("left", -0.029, 0, 0, 41.65, 35.57, 48.00, 43.97);
VRSimulationDriver.SetEyeParameter("right", 0.029, 0, 0, 41.65, 43.97, 48.00, 35.57);
var poseOrient = new Float32Array([-0.188, -0.007, 0.045, -0.980]);
var posePos = new Float32Array([-0.161, 0.076, -0.250]);
var poseAngVel = new Float32Array([0.008, -0.002, -0.006]);
var poseAngAcc = new Float32Array([3.404, -1.469, -5.901]);
var poseLinVel = new Float32Array([0.001, -0.003, -0.002]);
var poseLinAcc = new Float32Array([0.007, 0.068, -0.052]);
VRSimulationDriver.SetVRDisplayPose(posePos, poseLinVel, poseLinAcc,
poseOrient, poseAngVel, poseAngAcc);
VRSimulationDriver.UpdateVRDisplay();
}).then(() => {
return promise_test((test) => {
return setupVRDisplay(test).then(() => {
return WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay,
[{ source: canvas }]);
}).then(() => {
assert_true(vrDisplay.isPresenting, "vrDisplay.isPresenting must be true if requestPresent is fulfilled.");
assert_equals(vrDisplay.getLayers().length, 1, "vrDisplay.getLayers() should return one layer.");
verifyFrameData();
})
}, "WebVR requestPresent fulfilled");
})
}, "Finish setting up VR test data.");
function verifyFrameData() {
async_test(function (test) {
navigator.getVRDisplays().then((displays) => {
assert_equals(displays.length, 1, "displays.length must be one after attach.");
vrDisplay = displays[0];
vrDisplay.requestAnimationFrame(callback);
function callback() {
var frameData1 = new VRFrameData();
vrDisplay.getFrameData(frameData1);
// We insert a new frame to confirm we still can get
// the same data as the last getter.
insertNewFrameData();
var frameData2 = new VRFrameData();
vrDisplay.getFrameData(frameData2);
assert_equals(frameData1.timestamp, frameData2.timestamp,
"frameData.timestamp at a frame should be equal.");
assert_true(checkValueInFloat32Array(frameData1.leftProjectionMatrix,
frameData2.leftProjectionMatrix),
"frameData.leftProjectionMatrix at a frame should be equal.");
assert_true(checkValueInFloat32Array(frameData1.leftViewMatrix,
frameData2.leftViewMatrix),
"frameData.leftViewMatrix at a frame should be equal.");
assert_true(checkValueInFloat32Array(frameData1.rightProjectionMatrix,
frameData2.rightProjectionMatrix),
"frameData.rightProjectionMatrix at a frame should be equal.");
assert_true(checkValueInFloat32Array(frameData1.rightViewMatrix,
frameData2.rightViewMatrix),
"frameData.rightViewMatrix at a frame should be equal.");
var pose1 = frameData1.pose;
var pose2 = frameData2.pose;
assert_true(checkValueInFloat32Array(pose1.position,
pose2.position),
"pose.position at a frame should be equal.");
assert_true(checkValueInFloat32Array(pose1.linearVelocity,
pose2.linearVelocity),
"pose.linearVelocity at a frame should be equal.");
assert_true(checkValueInFloat32Array(pose1.linearAcceleration,
pose2.linearAcceleration),
"pose.linearAcceleration at a frame should be equal.");
assert_true(checkValueInFloat32Array(pose1.orientation,
pose2.orientation),
"pose.orientation at a frame should be equal.");
assert_true(checkValueInFloat32Array(pose1.angularVelocity,
pose2.angularVelocity),
"pose.angularVelocity at a frame should be equal.");
assert_true(checkValueInFloat32Array(pose1.angularAcceleration,
pose2.angularAcceleration),
"pose.angularAcceleration at a frame should be equal.");
test.done();
};
});
}, "WebVR returns the same frameData within a frame fulfilled");
}
function insertNewFrameData() {
var poseOrient = new Float32Array([-0.208, -0.017, 0.055, -0.930]);
var posePos = new Float32Array([-0.261, 0.036, -0.150]);
var poseAngVel = new Float32Array([0.018, -0.001, -0.003]);
var poseAngAcc = new Float32Array([1.504, -1.339, -4.901]);
var poseLinVel = new Float32Array([0.002, -0.001, -0.003]);
var poseLinAcc = new Float32Array([0.017, 0.061, -0.022]);
VRSimulationDriver.SetVRDisplayPose(posePos, poseLinVel, poseLinAcc,
poseOrient, poseAngVel, poseAngAcc);
VRSimulationDriver.UpdateVRDisplay();
}
function checkValueInFloat32Array(array1, array2) {
if (array1.length != array2.length) {
return false;
}
var index = 0;
while (index < array2.length) {
if (array1[index] != array2[index]) {
return false;
}
++index;
}
return true;
}
}
runVRTest(startTest);
</script>
</body>
</html>

Просмотреть файл

@ -183,14 +183,10 @@ partial interface Window {
[ChromeOnly] void mozScrollSnap();
// The four properties below are double per spec at the moment, but whether
// that will continue is unclear.
//[Replaceable, Throws] readonly attribute double scrollX;
//[Replaceable, Throws] readonly attribute double pageXOffset;
//[Replaceable, Throws] readonly attribute double scrollY;
//[Replaceable, Throws] readonly attribute double pageYOffset;
[Replaceable, Throws] readonly attribute long scrollX;
[Replaceable, Throws] readonly attribute long pageXOffset;
[Replaceable, Throws] readonly attribute long scrollY;
[Replaceable, Throws] readonly attribute long pageYOffset;
[Replaceable, Throws] readonly attribute double scrollX;
[Replaceable, Throws] readonly attribute double pageXOffset;
[Replaceable, Throws] readonly attribute double scrollY;
[Replaceable, Throws] readonly attribute double pageYOffset;
// client
// These are writable because we allow chrome to write them. And they need

Просмотреть файл

@ -1623,10 +1623,16 @@ private:
Pattern *pat;
RefPtr<gfxPattern> fillPattern;
if (!mFontParams.contextPaint ||
!(fillPattern = mFontParams.contextPaint->GetFillPattern(
mRunParams.context->GetDrawTarget(),
mRunParams.context->CurrentMatrix()))) {
if (mFontParams.contextPaint) {
mozilla::image::DrawResult result = mozilla::image::DrawResult::SUCCESS;
Tie(result, fillPattern) =
mFontParams.contextPaint->GetFillPattern(
mRunParams.context->GetDrawTarget(),
mRunParams.context->CurrentMatrix());
// XXX cku Flush should return result to the caller?
Unused << result;
}
if (!fillPattern) {
if (state.pattern) {
pat = state.pattern->GetPattern(mRunParams.dt,
state.patternTransformChanged ?

Просмотреть файл

@ -325,7 +325,7 @@ private:
DECL_GFX_PREF(Once, "dom.vr.openvr.enabled", VROpenVREnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.osvr.enabled", VROSVREnabled, bool, false);
DECL_GFX_PREF(Live, "dom.vr.poseprediction.enabled", VRPosePredictionEnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.require-gesture", VRRequireGesture, bool, true);
DECL_GFX_PREF(Live, "dom.vr.require-gesture", VRRequireGesture, bool, true);
DECL_GFX_PREF(Live, "dom.vr.puppet.enabled", VRPuppetEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.w3c_pointer_events.enabled", PointerEventsEnabled, bool, false);
DECL_GFX_PREF(Live, "dom.w3c_touch_events.enabled", TouchEventsEnabled, int32_t, 0);

Просмотреть файл

@ -202,24 +202,26 @@ public:
mStrokeMatrix = SetupDeviceToPatternMatrix(aStrokePattern, aCTM);
}
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
if (mFillPattern) {
mFillPattern->SetMatrix(aCTM * mFillMatrix);
}
RefPtr<gfxPattern> fillPattern = mFillPattern;
return fillPattern.forget();
return MakePair(DrawResult::SUCCESS, Move(fillPattern));
}
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
if (mStrokePattern) {
mStrokePattern->SetMatrix(aCTM * mStrokeMatrix);
}
RefPtr<gfxPattern> strokePattern = mStrokePattern;
return strokePattern.forget();
return MakePair(DrawResult::SUCCESS, Move(strokePattern));
}
float GetFillOpacity() const {

Просмотреть файл

@ -89,7 +89,6 @@ VRDisplayPuppet::VRDisplayPuppet()
mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
mSensorState.Clear();
mSensorState.timestamp = PR_Now();
gfx::Quaternion rot;
@ -119,7 +118,12 @@ VRDisplayPuppet::~VRDisplayPuppet()
void
VRDisplayPuppet::SetDisplayInfo(const VRDisplayInfo& aDisplayInfo)
{
mDisplayInfo = aDisplayInfo;
// We are only interested in the eye info of the display info.
mDisplayInfo.mEyeResolution = aDisplayInfo.mEyeResolution;
memcpy(&mDisplayInfo.mEyeFOV, &aDisplayInfo.mEyeFOV,
sizeof(mDisplayInfo.mEyeFOV[0]) * VRDisplayInfo::NumEyes);
memcpy(&mDisplayInfo.mEyeTranslation, &aDisplayInfo.mEyeTranslation,
sizeof(mDisplayInfo.mEyeTranslation[0]) * VRDisplayInfo::NumEyes);
}
void
@ -148,7 +152,7 @@ VRDisplayPuppet::GetSensorState(double timeOffset)
void
VRDisplayPuppet::SetSensorState(const VRHMDSensorState& aSensorState)
{
mSensorState = aSensorState;
memcpy(&mSensorState, &aSensorState, sizeof(mSensorState));
}
void

Просмотреть файл

@ -45,6 +45,7 @@ VRManagerChild::VRManagerChild()
, mFrameRequestCallbackCounter(0)
, mBackend(layers::LayersBackend::LAYERS_NONE)
, mPromiseID(0)
, mVRMockDisplay(nullptr)
{
MOZ_ASSERT(NS_IsMainThread());
@ -519,7 +520,11 @@ VRManagerChild::RecvReplyCreateVRServiceTestDisplay(const nsCString& aID,
MOZ_CRASH("We should always have a promise.");
}
p->MaybeResolve(new VRMockDisplay(aID, aDeviceID));
// We only allow one VRMockDisplay in VR tests.
if (!mVRMockDisplay) {
mVRMockDisplay = new VRMockDisplay(aID, aDeviceID);
}
p->MaybeResolve(mVRMockDisplay);
mPromiseList.Remove(aPromiseID);
return IPC_OK();
}

Просмотреть файл

@ -21,6 +21,7 @@ class GamepadManager;
class Navigator;
class VRDisplay;
class VREventObserver;
class VRMockDisplay;
} // namespace dom
namespace layers {
class TextureClient;
@ -187,6 +188,7 @@ private:
RefPtr<layers::SyncObject> mSyncObject;
uint32_t mPromiseID;
nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList;
RefPtr<dom::VRMockDisplay> mVRMockDisplay;
DISALLOW_COPY_AND_ASSIGN(VRManagerChild);
};

Просмотреть файл

@ -391,8 +391,9 @@ VRManagerParent::RecvSetDisplayInfoToMockDisplay(const uint32_t& aDeviceID,
const VRDisplayInfo& aDisplayInfo)
{
RefPtr<impl::VRDisplayPuppet> displayPuppet;
MOZ_ASSERT(mVRDisplayTests.Get(mDisplayTestID,
getter_AddRefs(displayPuppet)));
mVRDisplayTests.Get(mDisplayTestID,
getter_AddRefs(displayPuppet));
MOZ_ASSERT(displayPuppet);
displayPuppet->SetDisplayInfo(aDisplayInfo);
return IPC_OK();
}
@ -402,8 +403,9 @@ VRManagerParent::RecvSetSensorStateToMockDisplay(const uint32_t& aDeviceID,
const VRHMDSensorState& aSensorState)
{
RefPtr<impl::VRDisplayPuppet> displayPuppet;
MOZ_ASSERT(mVRDisplayTests.Get(mControllerTestID,
getter_AddRefs(displayPuppet)));
mVRDisplayTests.Get(mDisplayTestID,
getter_AddRefs(displayPuppet));
MOZ_ASSERT(displayPuppet);
displayPuppet->SetSensorState(aSensorState);
return IPC_OK();
}
@ -413,8 +415,9 @@ VRManagerParent::RecvNewButtonEventToMockController(const uint32_t& aDeviceID, c
const bool& aPressed)
{
RefPtr<impl::VRControllerPuppet> controllerPuppet;
MOZ_ASSERT(mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet)));
mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet));
MOZ_ASSERT(controllerPuppet);
controllerPuppet->SetButtonPressState(aButton, aPressed);
return IPC_OK();
}
@ -424,8 +427,9 @@ VRManagerParent::RecvNewAxisMoveEventToMockController(const uint32_t& aDeviceID,
const double& aValue)
{
RefPtr<impl::VRControllerPuppet> controllerPuppet;
MOZ_ASSERT(mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet)));
mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet));
MOZ_ASSERT(controllerPuppet);
controllerPuppet->SetAxisMoveState(aAxis, aValue);
return IPC_OK();
}
@ -435,8 +439,9 @@ VRManagerParent::RecvNewPoseMoveToMockController(const uint32_t& aDeviceID,
const GamepadPoseState& pose)
{
RefPtr<impl::VRControllerPuppet> controllerPuppet;
MOZ_ASSERT(mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet)));
mVRControllerTests.Get(mControllerTestID,
getter_AddRefs(controllerPuppet));
MOZ_ASSERT(controllerPuppet);
controllerPuppet->SetPoseMoveState(pose);
return IPC_OK();
}

Просмотреть файл

@ -26,3 +26,4 @@ skip-if = toolkit == "android" # bug 1309447
skip-if = toolkit == "android" # bug 1344596
[test_localeService.js]
[test_localeService_negotiateLanguages.js]
skip-if = toolkit == "android" # bug 1347431

Просмотреть файл

@ -85,6 +85,7 @@ head = head_ongc.js
head = head_ongc.js
[test_reflect_parse.js]
[test_localeCompare.js]
skip-if = toolkit == "android" # bug 1347431
[test_recursive_import.js]
[test_xpcomutils.js]
[test_unload.js]

Просмотреть файл

@ -98,8 +98,6 @@ AccessibleCaretManager::AccessibleCaretManager(nsIPresShell* aPresShell)
mFirstCaret = MakeUnique<AccessibleCaret>(mPresShell);
mSecondCaret = MakeUnique<AccessibleCaret>(mPresShell);
mCaretTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1");
static bool addedPrefs = false;
if (!addedPrefs) {
Preferences::AddBoolVarCache(&sSelectionBarEnabled,
@ -131,8 +129,6 @@ AccessibleCaretManager::~AccessibleCaretManager()
void
AccessibleCaretManager::Terminate()
{
CancelCaretTimeoutTimer();
mCaretTimeoutTimer = nullptr;
mFirstCaret = nullptr;
mSecondCaret = nullptr;
mActiveCaret = nullptr;
@ -219,7 +215,6 @@ AccessibleCaretManager::HideCarets()
mFirstCaret->SetAppearance(Appearance::None);
mSecondCaret->SetAppearance(Appearance::None);
DispatchCaretStateChangedEvent(CaretChangedReason::Visibilitychange);
CancelCaretTimeoutTimer();
}
}
@ -337,8 +332,6 @@ AccessibleCaretManager::UpdateCaretsForCursorMode(UpdateCaretsHintSet aHints)
mFirstCaret->SetSelectionBarEnabled(false);
mSecondCaret->SetAppearance(Appearance::None);
LaunchCaretTimeoutTimer();
if (!aHints.contains(UpdateCaretsHint::DispatchNoEvent) &&
!mActiveCaret) {
DispatchCaretStateChangedEvent(CaretChangedReason::Updateposition);
@ -501,7 +494,6 @@ AccessibleCaretManager::PressCaret(const nsPoint& aPoint,
mActiveCaret->LogicalPosition().y - aPoint.y;
SetSelectionDragState(true);
DispatchCaretStateChangedEvent(CaretChangedReason::Presscaret);
CancelCaretTimeoutTimer();
rv = NS_OK;
}
@ -528,7 +520,6 @@ AccessibleCaretManager::ReleaseCaret()
mActiveCaret = nullptr;
SetSelectionDragState(false);
DispatchCaretStateChangedEvent(CaretChangedReason::Releasecaret);
LaunchCaretTimeoutTimer();
return NS_OK;
}
@ -688,7 +679,7 @@ AccessibleCaretManager::OnScrollEnd()
if (GetCaretMode() == CaretMode::Cursor) {
if (!mFirstCaret->IsLogicallyVisible()) {
// If the caret is hidden (Appearance::None) due to timeout or blur, no
// If the caret is hidden (Appearance::None) due to blur, no
// need to update it.
return;
}
@ -1382,48 +1373,6 @@ AccessibleCaretManager::AdjustDragBoundary(const nsPoint& aPoint) const
return adjustedPoint;
}
uint32_t
AccessibleCaretManager::CaretTimeoutMs() const
{
static bool added = false;
static uint32_t caretTimeoutMs = 0;
if (!added) {
Preferences::AddUintVarCache(&caretTimeoutMs,
"layout.accessiblecaret.timeout_ms");
added = true;
}
return caretTimeoutMs;
}
void
AccessibleCaretManager::LaunchCaretTimeoutTimer()
{
if (!mPresShell || !mCaretTimeoutTimer || CaretTimeoutMs() == 0 ||
GetCaretMode() != CaretMode::Cursor || mActiveCaret) {
return;
}
nsTimerCallbackFunc callback = [](nsITimer* aTimer, void* aClosure) {
auto self = static_cast<AccessibleCaretManager*>(aClosure);
if (self->GetCaretMode() == CaretMode::Cursor) {
self->HideCarets();
}
};
mCaretTimeoutTimer->InitWithFuncCallback(callback, this, CaretTimeoutMs(),
nsITimer::TYPE_ONE_SHOT);
}
void
AccessibleCaretManager::CancelCaretTimeoutTimer()
{
if (mCaretTimeoutTimer) {
mCaretTimeoutTimer->Cancel();
}
}
void
AccessibleCaretManager::DispatchCaretStateChangedEvent(CaretChangedReason aReason) const
{

Просмотреть файл

@ -128,7 +128,7 @@ protected:
Default,
// Update everything while respecting the old appearance. For example, if
// the caret in cursor mode is hidden due to timeout, do not change its
// the caret in cursor mode is hidden due to blur, do not change its
// appearance to Normal.
RespectOldAppearance,
@ -218,12 +218,6 @@ protected:
// @return true if the aOffsets is suitable for changing the selection.
bool RestrictCaretDraggingOffsets(nsIFrame::ContentOffsets& aOffsets);
// Timeout in milliseconds to hide the AccessibleCaret under cursor mode while
// no one touches it.
uint32_t CaretTimeoutMs() const;
void LaunchCaretTimeoutTimer();
void CancelCaretTimeoutTimer();
// ---------------------------------------------------------------------------
// The following functions are made virtual for stubbing or mocking in gtest.
//
@ -280,10 +274,6 @@ protected:
// The caret being pressed or dragged.
AccessibleCaret* mActiveCaret = nullptr;
// The timer for hiding the caret in cursor mode after timeout behind the
// preference "layout.accessiblecaret.timeout_ms".
nsCOMPtr<nsITimer> mCaretTimeoutTimer;
// The caret mode since last update carets.
CaretMode mLastUpdateCaretMode = CaretMode::None;

Просмотреть файл

@ -35,11 +35,9 @@ class AccessibleCaretCursorModeTestCase(MarionetteTestCase):
# Code to execute before every test is running.
super(AccessibleCaretCursorModeTestCase, self).setUp()
self.caret_tested_pref = 'layout.accessiblecaret.enabled'
self.caret_timeout_ms_pref = 'layout.accessiblecaret.timeout_ms'
self.hide_carets_for_mouse = 'layout.accessiblecaret.hide_carets_for_mouse_input'
self.prefs = {
self.caret_tested_pref: True,
self.caret_timeout_ms_pref: 0,
self.hide_carets_for_mouse: False,
}
self.marionette.set_prefs(self.prefs)
@ -130,40 +128,6 @@ class AccessibleCaretCursorModeTestCase(MarionetteTestCase):
self.actions.key_down(content_to_add).key_up(content_to_add).perform()
self.assertEqual(target_content, sel.content)
@parameterized(_input_id, el_id=_input_id)
@parameterized(_textarea_id, el_id=_textarea_id)
@parameterized(_contenteditable_id, el_id=_contenteditable_id)
def test_dragging_caret_to_top_left_corner_after_timeout(self, el_id):
self.open_test_html(self._cursor_html)
el = self.marionette.find_element(By.ID, el_id)
sel = SelectionManager(el)
content_to_add = '!'
non_target_content = content_to_add + sel.content
# Set caret timeout to be 1 second.
timeout = 1
self.marionette.set_pref(self.caret_timeout_ms_pref, timeout * 1000)
# Set a 3x timeout margin to prevent intermittent test failures.
timeout *= 3
# Tap to make first caret appear. Note: it's strange that when the caret
# is at the end, the rect of the caret in <textarea> cannot be obtained.
# A bug perhaps.
el.tap()
sel.move_cursor_to_end()
sel.move_cursor_by_offset(1, backward=True)
el.tap(*sel.cursor_location())
# Wait until first caret disappears, then pretend to move it to the
# top-left corner of the input box.
src_x, src_y = sel.first_caret_location()
dest_x, dest_y = 0, 0
self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform()
self.actions.key_down(content_to_add).key_up(content_to_add).perform()
self.assertNotEqual(non_target_content, sel.content)
def test_caret_not_appear_when_typing_in_scrollable_content(self):
self.open_test_html(self._cursor_html)
el = self.marionette.find_element(By.ID, self._input_id)

Просмотреть файл

@ -23,7 +23,7 @@ addLoadEvent(function() {
setTimeout(function() {
// Make sure that we're scrolled by 5000px
is(window.pageYOffset, 5000, "Make sure we're scrolled correctly");
is(Math.round(window.pageYOffset), 5000, "Make sure we're scrolled correctly");
// Scroll back up, and mess with the input box along the way
var input = document.getElementById("WhyDoYouFocusMe");
@ -38,14 +38,14 @@ addLoadEvent(function() {
window.scrollTo(0, 5000);
setTimeout(function() {
is(window.pageYOffset, 5000, "Sanity check");
is(Math.round(window.pageYOffset), 5000, "Sanity check");
window.scrollTo(0, 0);
input.focus();
input.blur();
setTimeout(function() {
isnot(window.pageYOffset, 0, "This time we shouldn't be scrolled up");
isnot(Math.round(window.pageYOffset), 0, "This time we shouldn't be scrolled up");
SimpleTest.finish();
}, 0);

Просмотреть файл

@ -30,12 +30,12 @@ addLoadEvent(function() {
win.scrollTo(0, 5000);
setTimeout(function() {
is(win.pageYOffset, 5000, "Page should be scrolled correctly");
is(Math.round(win.pageYOffset), 5000, "Page should be scrolled correctly");
// Refocus the window
SimpleTest.waitForFocus(function() {
SimpleTest.waitForFocus(function() {
is(win.pageYOffset, 5000,
is(Math.round(win.pageYOffset), 5000,
"The page's scroll offset should not have been changed");
win.close();

Просмотреть файл

@ -6401,11 +6401,17 @@ Selection::NotifySelectionListeners()
if (!mFrameSelection)
return NS_OK;//nothing to do
// Our internal code should not move focus with using this class while
// this moves focus nor from selection listeners.
AutoRestore<bool> calledByJSRestorer(mCalledByJS);
mCalledByJS = false;
// When normal selection is changed by Selection API, we need to move focus
// if common ancestor of all ranges are in an editing host. Note that we
// don't need to move focus *to* the other focusable node because other
// browsers don't do it either.
if (mSelectionType == SelectionType::eNormal && mCalledByJS) {
if (mSelectionType == SelectionType::eNormal &&
calledByJSRestorer.SavedValue()) {
nsPIDOMWindowOuter* window = GetWindow();
nsIDocument* document = GetDocument();
// If the document is in design mode or doesn't have contenteditable
@ -6439,11 +6445,6 @@ Selection::NotifySelectionListeners()
}
}
// After moving focus, especially in selection listeners, our internal code
// should not move focus with using this class.
AutoRestore<bool> calledFromExternalRestorer(mCalledByJS);
mCalledByJS = false;
if (mFrameSelection->GetBatching()) {
mFrameSelection->SetDirty();
return NS_OK;

Просмотреть файл

@ -2902,7 +2902,7 @@ ClampColorStops(nsTArray<ColorStop>& aStops)
void
nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
gfxContext& aContext,
nsStyleGradient* aGradient,
const nsRect& aDirtyRect,
const nsRect& aDest,
@ -2920,7 +2920,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
return;
}
gfxContext *ctx = aRenderingContext.ThebesContext();
nscoord appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
gfxSize srcSize = gfxSize(gfxFloat(aIntrinsicSize.width)/appUnitsPerDevPixel,
gfxFloat(aIntrinsicSize.height)/appUnitsPerDevPixel);
@ -3263,7 +3262,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
rawStops[i].offset = stopScale * (stops[i].mPosition - stopOrigin);
}
RefPtr<mozilla::gfx::GradientStops> gs =
gfxGradientCache::GetOrCreateGradientStops(ctx->GetDrawTarget(),
gfxGradientCache::GetOrCreateGradientStops(aContext.GetDrawTarget(),
rawStops,
isRepeat ? gfx::ExtendMode::REPEAT : gfx::ExtendMode::CLAMP);
gradientPattern->SetColorStops(gs);
@ -3281,7 +3280,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
gfxRect dirtyAreaToFill = nsLayoutUtils::RectToGfxRect(dirty, appUnitsPerDevPixel);
dirtyAreaToFill.RoundOut();
gfxMatrix ctm = ctx->CurrentMatrix();
gfxMatrix ctm = aContext.CurrentMatrix();
bool isCTMPreservingAxisAlignedRectangles = ctm.PreservesAxisAlignedRectangles();
// xStart/yStart are the top-left corner of the top-left tile.
@ -3309,9 +3308,9 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
// Snap three points instead of just two to ensure we choose the
// correct orientation if there's a reflection.
if (isCTMPreservingAxisAlignedRectangles &&
ctx->UserToDevicePixelSnapped(snappedFillRectTopLeft, true) &&
ctx->UserToDevicePixelSnapped(snappedFillRectBottomRight, true) &&
ctx->UserToDevicePixelSnapped(snappedFillRectTopRight, true)) {
aContext.UserToDevicePixelSnapped(snappedFillRectTopLeft, true) &&
aContext.UserToDevicePixelSnapped(snappedFillRectBottomRight, true) &&
aContext.UserToDevicePixelSnapped(snappedFillRectTopRight, true)) {
if (snappedFillRectTopLeft.x == snappedFillRectBottomRight.x ||
snappedFillRectTopLeft.y == snappedFillRectBottomRight.y) {
// Nothing to draw; avoid scaling by zero and other weirdness that
@ -3324,10 +3323,10 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
gfxMatrix transform = gfxUtils::TransformRectToRect(fillRect,
snappedFillRectTopLeft, snappedFillRectTopRight,
snappedFillRectBottomRight);
ctx->SetMatrix(transform);
aContext.SetMatrix(transform);
}
ctx->NewPath();
ctx->Rectangle(fillRect);
aContext.NewPath();
aContext.Rectangle(fillRect);
gfxRect dirtyFillRect = fillRect.Intersect(dirtyAreaToFill);
gfxRect fillRectRelativeToTile = dirtyFillRect - tileRect.TopLeft();
@ -3336,14 +3335,14 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
RectIsBeyondLinearGradientEdge(fillRectRelativeToTile, matrix, stops,
gradientStart, gradientEnd, &edgeColor)) {
edgeColor.a *= aOpacity;
ctx->SetColor(edgeColor);
aContext.SetColor(edgeColor);
} else {
ctx->SetMatrix(
ctx->CurrentMatrix().Copy().Translate(tileRect.TopLeft()));
ctx->SetPattern(gradientPattern);
aContext.SetMatrix(
aContext.CurrentMatrix().Copy().Translate(tileRect.TopLeft()));
aContext.SetPattern(gradientPattern);
}
ctx->Fill();
ctx->SetMatrix(ctm);
aContext.Fill();
aContext.SetMatrix(ctm);
}
}
}

Просмотреть файл

@ -237,7 +237,7 @@ struct nsCSSRendering {
* aIntrinsicSize is the size of the source gradient.
*/
static void PaintGradient(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
gfxContext& aContext,
nsStyleGradient* aGradient,
const nsRect& aDirtyRect,
const nsRect& aDest,

Просмотреть файл

@ -508,7 +508,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
}
case eStyleImageType_Gradient:
{
nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
nsCSSRendering::PaintGradient(aPresContext, *ctx,
mGradientData, aDirtyRect,
aDest, aFill, aRepeatSize, aSrc, mSize,
aOpacity);
@ -516,8 +516,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
}
case eStyleImageType_Element:
{
RefPtr<gfxDrawable> drawable = DrawableForElement(aDest,
aRenderingContext);
RefPtr<gfxDrawable> drawable = DrawableForElement(aDest, *ctx);
if (!drawable) {
NS_WARNING("Could not create drawable for element");
return DrawResult::TEMPORARY_ERROR;
@ -563,7 +562,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
already_AddRefed<gfxDrawable>
nsImageRenderer::DrawableForElement(const nsRect& aImageRect,
nsRenderingContext& aRenderingContext)
gfxContext& aContext)
{
NS_ASSERTION(mType == eStyleImageType_Element,
"DrawableForElement only makes sense if backed by an element");
@ -581,8 +580,8 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect,
RefPtr<gfxDrawable> drawable =
nsSVGIntegrationUtils::DrawableFromPaintServer(
mPaintServerFrame, mForFrame, mSize, imageSize,
aRenderingContext.GetDrawTarget(),
aRenderingContext.ThebesContext()->CurrentMatrix(),
aContext.GetDrawTarget(),
aContext.CurrentMatrix(),
nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES);
return drawable.forget();
@ -775,8 +774,9 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
// invalidate that cache, and it's not clear that it's worth the trouble
// since using border-image with -moz-element is rare.
RefPtr<gfxDrawable> drawable = DrawableForElement(nsRect(nsPoint(), mSize),
aRenderingContext);
RefPtr<gfxDrawable> drawable =
DrawableForElement(nsRect(nsPoint(), mSize),
*aRenderingContext.ThebesContext());
if (!drawable) {
NS_WARNING("Could not create drawable for element");
return DrawResult::TEMPORARY_ERROR;

Просмотреть файл

@ -262,7 +262,7 @@ private:
* Returns null if we cannot create the drawable.
*/
already_AddRefed<gfxDrawable> DrawableForElement(const nsRect& aImageRect,
nsRenderingContext& aRenderingContext);
gfxContext& aContext);
nsIFrame* mForFrame;
const nsStyleImage* mImage;

Просмотреть файл

@ -55,7 +55,7 @@ fails == select-1.html select-1.html
fails == select-1-dynamic.html select-1-dynamic.html
fails == select-2.html select-2.html
fails == select-3.html select-3.html
fails == multi-column-1.html multi-column-1.html
== multi-column-1.html multi-column-1.html
== button-1.html button-1.html
== button-2.html button-2.html
== relative-row-animation-1.html relative-row-animation-1.html

Просмотреть файл

@ -69,7 +69,7 @@ fails == 115921-2.html 115921-2.html
== 229367-1.html 229367-1.html
fails == 229367-2.html 229367-2.html
== 229367-3.html 229367-3.html
fails == 258928-1.html 258928-1.html
== 258928-1.html 258928-1.html
fails == 263359-1.html 263359-1.html
fails == 263359-1a.html 263359-1a.html
fails == 263359-1b.html 263359-1b.html

Просмотреть файл

@ -306,8 +306,8 @@ fails == 280708-1b.html 280708-1b.html
== 283686-2.html 283686-2.html
== 283686-3.html 283686-3.html
fails == 289384-1.xhtml 289384-1.xhtml
fails == 289480.html#top 289480-ref.html
fails == 289480-ref.html 289480-ref.html
== 289480.html#top 289480-ref.html
== 289480-ref.html 289480-ref.html
fails == 290129-1.html 290129-1.html
fails == 291078-1.html 291078-1.html
== 291078-2.html 291078-2.html
@ -794,7 +794,7 @@ fails == 391994-1.html 391994-1.html
== 392047.html 392047.html
fails == 392435-1.html 392435-1.html
== 393330-1.html 393330-1.html
fails == 393490-1.html 393490-1.html
== 393490-1.html 393490-1.html
== 393517-1.xhtml 393517-1.xhtml
== 393649-1.html 393649-1.html
== 393655-1.html 393655-1.html
@ -1518,8 +1518,8 @@ fails-if(Android) == 560455-1.xul 560455-1.xul
== 561981-6.html 561981-6.html
== 561981-7.html 561981-7.html
== 561981-8.html 561981-8.html
fails == 562835-1.html 562835-1.html
fails == 562835-2.html 562835-2.html
== 562835-1.html 562835-1.html
== 562835-2.html 562835-2.html
== 563584-1.html 563584-1.html
== 563584-2.html 563584-2.html
== 563584-3.html 563584-3.html

Просмотреть файл

@ -57,17 +57,17 @@ fails == grid-auto-min-sizing-intrinsic-001.html grid-auto-min-sizing-intrinsic-
fails == grid-auto-min-sizing-intrinsic-002.html grid-auto-min-sizing-intrinsic-002.html
fails == grid-auto-min-sizing-intrinsic-003.html grid-auto-min-sizing-intrinsic-003.html
fails == grid-auto-min-sizing-intrinsic-004.html grid-auto-min-sizing-intrinsic-004.html
fails == grid-auto-min-sizing-transferred-size-001.html grid-auto-min-sizing-transferred-size-001.html
== grid-auto-min-sizing-transferred-size-001.html grid-auto-min-sizing-transferred-size-001.html
fails == grid-auto-min-sizing-transferred-size-002.html grid-auto-min-sizing-transferred-size-002.html
fails == grid-auto-min-sizing-transferred-size-003.html grid-auto-min-sizing-transferred-size-003.html
fails == grid-auto-min-sizing-transferred-size-004.html grid-auto-min-sizing-transferred-size-004.html
fails == grid-auto-min-sizing-min-content-min-size-001.html grid-auto-min-sizing-min-content-min-size-001.html
== grid-auto-min-sizing-min-content-min-size-001.html grid-auto-min-sizing-min-content-min-size-001.html
fails == grid-auto-min-sizing-min-content-min-size-002.html grid-auto-min-sizing-min-content-min-size-002.html
fails == grid-auto-min-sizing-min-content-min-size-003.html grid-auto-min-sizing-min-content-min-size-003.html
# == grid-auto-min-sizing-min-content-min-size-004.html grid-auto-min-sizing-min-content-min-size-004.html # bug 1342710
fails == grid-min-content-min-sizing-transferred-size-001.html grid-min-content-min-sizing-transferred-size-001.html
== grid-min-content-min-sizing-transferred-size-001.html grid-min-content-min-sizing-transferred-size-001.html
fails == grid-min-content-min-sizing-transferred-size-002.html grid-min-content-min-sizing-transferred-size-002.html
fails == grid-min-content-min-sizing-transferred-size-003.html grid-min-content-min-sizing-transferred-size-003.html
== grid-min-content-min-sizing-transferred-size-003.html grid-min-content-min-sizing-transferred-size-003.html
fails == grid-min-content-min-sizing-transferred-size-004.html grid-min-content-min-sizing-transferred-size-004.html
fails == grid-auto-min-sizing-percent-001.html grid-auto-min-sizing-percent-001.html
fails == grid-track-intrinsic-sizing-001.html grid-track-intrinsic-sizing-001.html

Просмотреть файл

@ -1,13 +1,13 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
== button-valid.html button-valid.html
fails == button-invalid.html button-invalid.html
== button-invalid.html button-invalid.html
== button-disabled.html button-disabled.html
== button-dyn-disabled.html button-dyn-disabled.html
fails == button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-button.html button-button.html
== button-reset.html button-reset.html
fails == button-type-invalid.html button-type-invalid.html
== button-type-invalid.html button-type-invalid.html
== button-type-barred.html button-type-barred.html
== button-disabled-fieldset-1.html button-disabled-fieldset-1.html
== button-disabled-fieldset-2.html button-disabled-fieldset-2.html
fails == button-fieldset-legend.html button-fieldset-legend.html
== button-fieldset-legend.html button-fieldset-legend.html

Просмотреть файл

@ -1,30 +1,30 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == fieldset-valid.html fieldset-valid.html
fails == fieldset-invalid.html fieldset-invalid.html
fails == fieldset-add-invalid-barred.html fieldset-add-invalid-barred.html
fails == fieldset-add-invalid-element-dynamic.html fieldset-add-invalid-element-dynamic.html
fails == fieldset-add-invalid-element.html fieldset-add-invalid-element.html
fails == fieldset-add-invalid-with-valid-element.html fieldset-add-invalid-with-valid-element.html
fails == fieldset-add-valid-element.html fieldset-add-valid-element.html
fails == fieldset-add-valid-with-invalid-element.html fieldset-add-valid-with-invalid-element.html
fails == fieldset-add-valid-with-no-element.html fieldset-add-valid-with-no-element.html
fails == fieldset-dynamic-invalid-barred.html fieldset-dynamic-invalid-barred.html
fails == fieldset-dynamic-invalid-not-barred.html fieldset-dynamic-invalid-not-barred.html
fails == fieldset-dynamic-invalid.html fieldset-dynamic-invalid.html
fails == fieldset-dynamic-valid.html fieldset-dynamic-valid.html
fails == fieldset-invalid-and-barred-remove-barred.html fieldset-invalid-and-barred-remove-barred.html
fails == fieldset-invalid-and-barred-remove-invalid.html fieldset-invalid-and-barred-remove-invalid.html
fails == fieldset-invalid-and-barred.html fieldset-invalid-and-barred.html
fails == fieldset-remove-invalid-element.html fieldset-remove-invalid-element.html
fails == fieldset-static-invalid-barred.html fieldset-static-invalid-barred.html
fails == fieldset-static-invalid.html fieldset-static-invalid.html
fails == fieldset-static-valid.html fieldset-static-valid.html
fails == fieldset-valid-and-barred-remove-barred.html fieldset-valid-and-barred-remove-barred.html
fails == fieldset-valid-and-barred.html fieldset-valid-and-barred.html
fails == fieldset-with-invalid-element-add-barred-dynamic.html fieldset-with-invalid-element-add-barred-dynamic.html
fails == fieldset-with-valid-and-invalid.html fieldset-with-valid-and-invalid.html
fails == fieldset-with-valid-element-add-barred-dynamic.html fieldset-with-valid-element-add-barred-dynamic.html
fails == fieldset-nested-invalid.html fieldset-nested-invalid.html
fails == fieldset-div-invalid.html fieldset-div-invalid.html
== fieldset-valid.html fieldset-valid.html
== fieldset-invalid.html fieldset-invalid.html
== fieldset-add-invalid-barred.html fieldset-add-invalid-barred.html
== fieldset-add-invalid-element-dynamic.html fieldset-add-invalid-element-dynamic.html
== fieldset-add-invalid-element.html fieldset-add-invalid-element.html
== fieldset-add-invalid-with-valid-element.html fieldset-add-invalid-with-valid-element.html
== fieldset-add-valid-element.html fieldset-add-valid-element.html
== fieldset-add-valid-with-invalid-element.html fieldset-add-valid-with-invalid-element.html
== fieldset-add-valid-with-no-element.html fieldset-add-valid-with-no-element.html
== fieldset-dynamic-invalid-barred.html fieldset-dynamic-invalid-barred.html
== fieldset-dynamic-invalid-not-barred.html fieldset-dynamic-invalid-not-barred.html
== fieldset-dynamic-invalid.html fieldset-dynamic-invalid.html
== fieldset-dynamic-valid.html fieldset-dynamic-valid.html
== fieldset-invalid-and-barred-remove-barred.html fieldset-invalid-and-barred-remove-barred.html
== fieldset-invalid-and-barred-remove-invalid.html fieldset-invalid-and-barred-remove-invalid.html
== fieldset-invalid-and-barred.html fieldset-invalid-and-barred.html
== fieldset-remove-invalid-element.html fieldset-remove-invalid-element.html
== fieldset-static-invalid-barred.html fieldset-static-invalid-barred.html
== fieldset-static-invalid.html fieldset-static-invalid.html
== fieldset-static-valid.html fieldset-static-valid.html
== fieldset-valid-and-barred-remove-barred.html fieldset-valid-and-barred-remove-barred.html
== fieldset-valid-and-barred.html fieldset-valid-and-barred.html
== fieldset-with-invalid-element-add-barred-dynamic.html fieldset-with-invalid-element-add-barred-dynamic.html
== fieldset-with-valid-and-invalid.html fieldset-with-valid-and-invalid.html
== fieldset-with-valid-element-add-barred-dynamic.html fieldset-with-valid-element-add-barred-dynamic.html
== fieldset-nested-invalid.html fieldset-nested-invalid.html
== fieldset-div-invalid.html fieldset-div-invalid.html
fails == fieldset-nested-valid-invalid.html fieldset-nested-valid-invalid.html
fails == fieldset-nested-barred.html fieldset-nested-barred.html

Просмотреть файл

@ -2,24 +2,24 @@
fails == form-static-valid.html form-static-valid.html
fails == form-dynamic-valid.html form-dynamic-valid.html
== form-remove-invalid-element.html form-remove-invalid-element.html
fails == form-static-invalid.html form-static-invalid.html
fails == form-dynamic-invalid.html form-dynamic-invalid.html
fails == form-add-control.html form-add-control.html
fails == form-dynamic-invalid-not-barred.html form-dynamic-invalid-not-barred.html
== form-static-invalid.html form-static-invalid.html
== form-dynamic-invalid.html form-dynamic-invalid.html
== form-add-control.html form-add-control.html
== form-dynamic-invalid-not-barred.html form-dynamic-invalid-not-barred.html
== form-remove-invalid-element.html form-remove-invalid-element.html
fails == form-dynamic-invalid-barred.html form-dynamic-invalid-barred.html
fails == form-static-invalid-barred.html form-static-invalid-barred.html
fails == form-add-invalid-element.html form-add-invalid-element.html
fails == form-add-valid-with-invalid-element.html form-add-valid-with-invalid-element.html
== form-add-invalid-element.html form-add-invalid-element.html
== form-add-valid-with-invalid-element.html form-add-valid-with-invalid-element.html
fails == form-invalid-barred.html form-invalid-barred.html
fails == form-add-valid-element.html form-add-valid-element.html
fails == form-add-valid-with-no-element.html form-add-valid-with-no-element.html
fails == form-add-invalid-with-valid-element.html form-add-invalid-with-valid-element.html
fails == form-with-valid-and-invalid.html form-with-valid-and-invalid.html
fails == form-add-invalid-element-dynamic.html form-add-invalid-element-dynamic.html
fails == form-invalid-and-barred.html form-invalid-and-barred.html
fails == form-invalid-and-barred-remove-barred.html form-invalid-and-barred-remove-barred.html
== form-add-invalid-with-valid-element.html form-add-invalid-with-valid-element.html
== form-with-valid-and-invalid.html form-with-valid-and-invalid.html
== form-add-invalid-element-dynamic.html form-add-invalid-element-dynamic.html
== form-invalid-and-barred.html form-invalid-and-barred.html
== form-invalid-and-barred-remove-barred.html form-invalid-and-barred-remove-barred.html
fails == form-valid-and-barred.html form-valid-and-barred.html
fails == form-valid-and-barred-remove-barred.html form-valid-and-barred-remove-barred.html
fails == form-with-invalid-element-add-barred-dynamic.html form-with-invalid-element-add-barred-dynamic.html
== form-with-invalid-element-add-barred-dynamic.html form-with-invalid-element-add-barred-dynamic.html
fails == form-with-valid-element-add-barred-dynamic.html form-with-valid-element-add-barred-dynamic.html

Просмотреть файл

@ -22,13 +22,13 @@ fails == input-type-invalid.html input-type-invalid.html
fails == input-disabled-fieldset-1.html input-disabled-fieldset-1.html
fails == input-disabled-fieldset-2.html input-disabled-fieldset-2.html
fails == input-fieldset-legend.html input-fieldset-legend.html
fails == input-radio-required.html input-radio-required.html
fails == input-radio-customerror.html input-radio-customerror.html
== input-radio-required.html input-radio-required.html
== input-radio-customerror.html input-radio-customerror.html
== input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html
== input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html
fails == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html
== input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html
== input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html
fails == input-radio-focus-click.html input-radio-focus-click.html
== input-radio-focus-click.html input-radio-focus-click.html
fails == input-submit.html input-submit.html
fails == input-image.html input-image.html
# input type='hidden' shouldn't show

Просмотреть файл

@ -1,3 +1,3 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
== output-valid.html output-valid.html
fails == output-invalid.html output-invalid.html
== output-invalid.html output-invalid.html

Просмотреть файл

@ -13,5 +13,5 @@ fails == add-submit-control.html add-submit-control.html
fails == remove-submit-control.html remove-submit-control.html
fails == change-type-submit-control.html change-type-submit-control.html
fails == change-type-not-submit-control.html change-type-not-submit-control.html
fails == self-invalid.html self-invalid.html
== self-invalid.html self-invalid.html
fails == remove-form.html remove-form.html

Просмотреть файл

@ -13,5 +13,5 @@ fails == add-submit-control.html add-submit-control.html
fails == remove-submit-control.html remove-submit-control.html
fails == change-type-submit-control.html change-type-submit-control.html
fails == change-type-not-submit-control.html change-type-not-submit-control.html
fails == self-invalid.html self-invalid.html
== self-invalid.html self-invalid.html
fails == remove-form.html remove-form.html

Просмотреть файл

@ -1,14 +1,14 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == button-valid.html button-valid.html
== button-valid.html button-valid.html
== button-invalid.html button-invalid.html
== button-disabled.html button-disabled.html
== button-dyn-disabled.html button-dyn-disabled.html
fails == button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-button.html button-button.html
== button-reset.html button-reset.html
== button-type-invalid.html button-type-invalid.html
== button-type-barred.html button-type-barred.html
== button-disabled-fieldset-1.html button-disabled-fieldset-1.html
== button-disabled-fieldset-2.html button-disabled-fieldset-2.html
fails == button-fieldset-legend.html button-fieldset-legend.html
== button-fieldset-legend.html button-fieldset-legend.html
== button-novalidate.html button-novalidate.html

Просмотреть файл

@ -1,4 +1,4 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == output-valid.html output-valid.html # Bug 1341739
== output-valid.html output-valid.html
== output-invalid.html output-invalid.html
== output-novalidate.html output-novalidate.html

Просмотреть файл

@ -1,13 +1,13 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == button-valid.html button-valid.html
== button-valid.html button-valid.html
== button-invalid.html button-invalid.html
== button-disabled.html button-disabled.html
== button-dyn-disabled.html button-dyn-disabled.html
fails == button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-dyn-not-disabled.html button-dyn-not-disabled.html
== button-button.html button-button.html
== button-reset.html button-reset.html
== button-type-invalid.html button-type-invalid.html
== button-type-barred.html button-type-barred.html
== button-disabled-fieldset-1.html button-disabled-fieldset-1.html
== button-disabled-fieldset-2.html button-disabled-fieldset-2.html
fails == button-fieldset-legend.html button-fieldset-legend.html
== button-fieldset-legend.html button-fieldset-legend.html

Просмотреть файл

@ -1,3 +1,3 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == fieldset-valid.html fieldset-valid.html
fails == fieldset-invalid.html fieldset-invalid.html
== fieldset-valid.html fieldset-valid.html
== fieldset-invalid.html fieldset-invalid.html

Просмотреть файл

@ -1,3 +1,3 @@
# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
fails == output-valid.html output-valid.html # Bug 341739
== output-valid.html output-valid.html
== output-invalid.html output-invalid.html

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше