зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-central to mozilla-inbound on a CLOSED TREE
This commit is contained in:
Коммит
bfb77aa998
|
@ -53,7 +53,6 @@ module.exports = {
|
|||
// XXX Bug 1434446. These directories have jsm files still being fixed, so
|
||||
// turn off global no-unused-vars checking for them.
|
||||
"files": [
|
||||
"accessible/**/*.jsm",
|
||||
"browser/components/**/*.jsm",
|
||||
"browser/extensions/**/*.jsm",
|
||||
"services/sync/**/*.jsm",
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "Role.h"
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMXULControlElement.h"
|
||||
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* exported AccessFu */
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["AccessFu"]; // jshint ignore:line
|
||||
var EXPORTED_SYMBOLS = ["AccessFu"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
|
||||
|
@ -15,7 +13,7 @@ if (Utils.MozBuildApp === "mobile/android") {
|
|||
ChromeUtils.import("resource://gre/modules/Messaging.jsm");
|
||||
}
|
||||
|
||||
const ACCESSFU_DISABLE = 0; // jshint ignore:line
|
||||
// const ACCESSFU_DISABLE = 0;
|
||||
const ACCESSFU_ENABLE = 1;
|
||||
const ACCESSFU_AUTO = 2;
|
||||
|
||||
|
@ -23,7 +21,7 @@ const SCREENREADER_SETTING = "accessibility.screenreader";
|
|||
const QUICKNAV_MODES_PREF = "accessibility.accessfu.quicknav_modes";
|
||||
const QUICKNAV_INDEX_PREF = "accessibility.accessfu.quicknav_index";
|
||||
|
||||
var AccessFu = { // jshint ignore:line
|
||||
var AccessFu = {
|
||||
/**
|
||||
* Initialize chrome-layer accessibility functionality.
|
||||
* If accessibility is enabled on the platform, then a special accessibility
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const TEXT_NODE = 3;
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<blocklist lastupdate="1519220554330" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<blocklist lastupdate="1519390923381" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
|
||||
<prefs/>
|
||||
|
@ -2235,42 +2235,6 @@
|
|||
<infoURL>https://get.adobe.com/shockwave/</infoURL>
|
||||
<versionRange maxVersion="12.2.0.162" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="59c31ade-88d6-4b22-8601-5316f82e3977">
|
||||
<match exp="(nppdf32\.dll)|(AdobePDFViewerNPAPI\.plugin)" name="filename"/>
|
||||
<infoURL>https://get.adobe.com/reader/</infoURL>
|
||||
<versionRange maxVersion="11.0.18" minVersion="11.0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="3f136e56-4c93-4619-8c0d-d86258c1065d">
|
||||
<match exp="(nppdf32\.dll)|(AdobePDFViewerNPAPI\.plugin)" name="filename"/>
|
||||
<infoURL>https://get.adobe.com/reader/</infoURL>
|
||||
<versionRange maxVersion="15.006.30244" minVersion="15.006" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="43b45ad8-a373-42c1-89c6-64e2746885e5">
|
||||
<match exp="(nppdf32\.dll)|(AdobePDFViewerNPAPI\.plugin)" name="filename"/>
|
||||
<infoURL>https://get.adobe.com/reader/</infoURL>
|
||||
<versionRange maxVersion="15.020.20042" minVersion="15.020" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="97647cd8-03c5-416c-b9d3-cd5ef87ab39f">
|
||||
<match exp="np32dsw_1227197\.dll" name="filename"/>
|
||||
<versionRange maxVersion="12.2.7.197" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="d70fdf87-0441-479c-833f-2213b769eb40">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange maxVersion="Java 7 Update 150" minVersion="Java 7 Update 97" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="427f5ec6-d1a7-4725-ac29-d5c5e51de537">
|
||||
<match exp="Java\(TM\) Platform SE 7 U(97|98|99|1([0-4][0-9]|50))(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="fdc40de3-95ab-41a5-94cf-9b400221a713">
|
||||
<match exp="Java(\(TM\))? Plug-in 10\.(97|98|99|1([0-4]\d|50))(\.\d+)?([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="832dc9ff-3314-4df2-abcf-7bd65a645371">
|
||||
<match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
|
||||
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
|
||||
|
@ -2281,246 +2245,6 @@
|
|||
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
|
||||
<versionRange maxVersion="27.0.0.159" minVersion="0" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="f24ffd6f-e02b-4cf4-91d9-d54cd793e4bf">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange maxVersion="Java 8 Update 160" minVersion="Java 8 Update" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="ab59635e-2e93-423a-9d57-871dde8ae675">
|
||||
<match exp="Java(\(TM\))? Plug-in 11\.(7[6-9]|[8-9]\d|1([0-5]\d|60))(\.\d+)?([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="33147281-45b2-487e-9fea-f66c6517252d">
|
||||
<match exp="Java\(TM\) Platform SE 8 U(7[6-9]|[8-9]\d|1([0-5]\d|60))(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p416">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 6 Update 45" minVersion="Java 6 Update 42" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p328">
|
||||
<match exp="Silverlight\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="5.1.20124.9999" minVersion="5.1" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="19.0a1"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p414">
|
||||
<match exp="Java\(TM\) Platform SE 6 U4[2-5](\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p184">
|
||||
<match exp="Java\(TM\) Plug-in 1\.7\.0(_0?([0-9]|(1[0-1]))?)?([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p412">
|
||||
<match exp="Java\(TM\) Plug-in 1\.6\.0_4[2-5]([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p457">
|
||||
<match exp="Java(\(TM\))? Plug-in ((1\.7\.0_(2[5-9]|3\d|4[0-4]))|(10\.4[0-4](\.[0-9]+)?))([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p294">
|
||||
<match exp="Java\(TM\) Platform SE 7 U1[2-5](\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p186">
|
||||
<match exp="Java\(TM\) Platform SE 6 U3[1-8](\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p242" os="Darwin">
|
||||
<match exp="Flip4Mac" name="description"/>
|
||||
<versionRange maxVersion="2.4.3.999" minVersion="0" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="18.0a1"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p459">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 7 Update 44" minVersion="Java 7 Update 25" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p188">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 6 Update 38" minVersion="Java 6 Update 0" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p292">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 7 Update 15" minVersion="Java 7 Update 12" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p190">
|
||||
<match exp="Java\(TM\) Plug-in 1\.6\.0_3[1-8]([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p418">
|
||||
<match exp="Java\(TM\) Plug-in 1\.7\.0_(1[6-9]|2[0-4])([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p182">
|
||||
<match exp="Java\(TM\) Platform SE 7 U([0-9]|(1[0-1]))(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p422">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 7 Update 24" minVersion="Java 7 Update 16" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p302">
|
||||
<match exp="Java\(TM\) Plug-in 1\.6\.0_(39|40|41)([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p296">
|
||||
<match exp="Java\(TM\) Plug-in 1\.7\.0_1[2-5]([^\d\._]|$)" name="name"/>
|
||||
<match exp="libnpjp2\.so" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p298">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="Java 6 Update 41" minVersion="Java 6 Update 39" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p458">
|
||||
<match exp="Java\(TM\) Platform SE 7 U(2[5-9]|3\d|4[0-4])(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p420">
|
||||
<match exp="Java\(TM\) Platform SE 7 U(1[6-9]|2[0-4])(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p254">
|
||||
<match exp="PDF Browser Plugin\.plugin" name="filename"/>
|
||||
<versionRange maxVersion="2.4.2" minVersion="0" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="18.0a1"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p34">
|
||||
<match exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" name="filename"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="3.6a1pre"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p180">
|
||||
<match exp="JavaAppletPlugin\.plugin" name="filename"/>
|
||||
<infoURL>https://java.com/</infoURL>
|
||||
<versionRange maxVersion="Java 7 Update 10" minVersion="Java 7 Update 0" severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p32">
|
||||
<match exp="npViewpoint.dll" name="filename"/>
|
||||
<versionRange>
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="3.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p300">
|
||||
<match exp="Java\(TM\) Platform SE 6 U(39|40|41)(\s[^\d\._U]|$)" name="name"/>
|
||||
<match exp="npjp2\.dll" name="filename"/>
|
||||
<versionRange severity="0" vulnerabilitystatus="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange maxVersion="*" minVersion="17.0"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
<gfxItems>
|
||||
<gfxBlacklistEntry blockID="g194">
|
||||
|
|
|
@ -623,7 +623,6 @@
|
|||
#ifdef CAN_DRAW_IN_TITLEBAR
|
||||
#ifndef XP_MACOSX
|
||||
<hbox class="titlebar-placeholder" type="caption-buttons" ordinal="1000"
|
||||
persist="width"
|
||||
skipintoolbarset="true"/>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -697,7 +696,6 @@
|
|||
ordinal="1000"/>
|
||||
#ifdef CAN_DRAW_IN_TITLEBAR
|
||||
<hbox class="titlebar-placeholder" type="caption-buttons"
|
||||
persist="width"
|
||||
#ifndef XP_MACOSX
|
||||
ordinal="1000"
|
||||
#endif
|
||||
|
@ -705,7 +703,6 @@
|
|||
|
||||
#ifdef XP_MACOSX
|
||||
<hbox class="titlebar-placeholder" type="fullscreen-button"
|
||||
persist="width"
|
||||
skipintoolbarset="true"/>
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
<hbox class="search-container" pack="end">
|
||||
<textbox
|
||||
type="search" id="searchInput"
|
||||
data-l10n-id="search-field"
|
||||
data-l10n-id="search-input"
|
||||
data-l10n-attrs="style"
|
||||
hidden="true" clickSelectsAll="true"/>
|
||||
</hbox>
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
============================
|
||||
Full Installer Configuration
|
||||
============================
|
||||
|
||||
Command-line Options
|
||||
--------------------
|
||||
|
||||
The full installer provides a number of options that can be used either from the GUI or from silent mode. It accepts these two command-line options:
|
||||
|
||||
``/S``
|
||||
Silent installation. This option doesn't open the GUI, instead running the installation in the background using all the default settings. It's useful as part of a script for configuring a new system, for example.
|
||||
|
||||
For backwards compatibility, this option can also be spelled ``-ms``.
|
||||
|
||||
``/INI=[absolute path to .ini file]``
|
||||
Read configuration from an .ini file. Also triggers silent mode, but instead of using all the default settings, allows you to control them by providing a settings file.
|
||||
|
||||
|
||||
INI File Settings
|
||||
-----------------
|
||||
|
||||
All of these settings should be placed into one section, called ``[Install]``, in the standard INI syntax. All of them are optional; they can be included or left out in any combination. Order does not matter.
|
||||
|
||||
``InstallDirectoryPath``
|
||||
Absolute path specifying the complete install location. This directory does not need to exist already (but it can).
|
||||
|
||||
If ``InstallDirectoryName`` is set, then this setting will be ignored.
|
||||
|
||||
``InstallDirectoryName``
|
||||
Name of the installation directory to create within Program Files. For example, if ``InstallDirectoryName`` is set to ``Firefox Release``, then the installation path will be something like ``C:\Program Files\Firefox Release``. The Program Files path used will be the correct one for the architecture of the application being installed and the locale/configuration of the machine; this setting is mainly useful to keep you from having to worry about those differences.
|
||||
|
||||
If this is set, then ``InstallDirectoryPath`` will be ignored.
|
||||
|
||||
``TaskbarShortcut``
|
||||
Set to ``false`` to disable pinning a shortcut to the taskbar. ``true`` by default. This feature only works on Windows 7 and 8; it isn't possible to create taskbar pins from the installer on later versions.
|
||||
|
||||
``DesktopShortcut``
|
||||
Set to ``false`` to disable creating a shortcut on the desktop. ``true`` by default.
|
||||
|
||||
``StartMenuShortcuts``
|
||||
Set to ``false`` to disable creating a Start menu shortcut. ``true`` by default. The name is historical; only one shortcut is ever created in the Start menu.
|
||||
|
||||
``MaintenanceService``
|
||||
Set to ``false`` to disable installing the Mozilla Maintenance Service. This will effectively prevent users from installing Firefox updates if they do not have write permissions to the installation directory. ``true`` by default.
|
||||
|
||||
``RemoveDistributionDir``
|
||||
Set to ``false`` to disable removing the ``distribution`` directory from an existing installation that's being paved over. By default this is ``true`` and the directory is removed.
|
||||
|
||||
``PreventRebootRequired``
|
||||
Set to ``true`` to keep the installer from taking actions that would require rebooting the machine to complete, normally because files are in use. This should not be needed under normal circumstances because no such actions should be required unless you're paving over a copy of Firefox that was running while the installer was trying to run, and setting this option in that case may result in an incomplete installation. ``false`` by default.
|
||||
|
||||
``OptionalExtensions``
|
||||
Set to ``false`` to disable installing any bundled extensions that are present. Normally none of these exist, except in special distributions of Firefox such as the one produced by Mozilla China or by other partner organizations. ``true`` by default.
|
||||
|
||||
|
||||
Example INI File
|
||||
~~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
[Install]
|
||||
; Semicolons can be used to add comments
|
||||
InstallDirectoryName=Firefox Release
|
||||
DesktopShortcut=false
|
||||
MaintenanceService=false
|
||||
OptionalExtensions=false
|
|
@ -0,0 +1,10 @@
|
|||
==============
|
||||
Full Installer
|
||||
==============
|
||||
|
||||
The full installer is actually responsible for installing the browser; it's what the stub launches in order to do the "real" installing work, but it's also available separately. It uses a traditional "wizard" interface design, as is (somewhat) natively supported by NSIS. It can also be :doc:`configured <FullConfig>` to launch in a silent mode, suitable for scripting or managed deployments.
|
||||
|
||||
The full installer's main script is `installer.nsi <https://searchfox.org/mozilla-central/source/browser/installer/windows/nsis/installer.nsi>`_, but most of the heavy lifting is done by the shared functions in `common.nsh <https://searchfox.org/mozilla-central/source/toolkit/mozapps/installer/windows/nsis/common.nsh>`_.
|
||||
|
||||
.. toctree::
|
||||
FullConfig
|
|
@ -0,0 +1,32 @@
|
|||
======
|
||||
Helper
|
||||
======
|
||||
helper.exe contains the uninstaller, plus a routine that's run by the application updater after it applies an update, as well as a few utilities used for default browser handling and shortcut maintenance. It mainly consists of two files, uninstaller.nsi_, which is the main script and contains the entry point and the uninstall logic, and shared.nsh_, which contains most of the logic for the other functions.
|
||||
|
||||
Uninstaller
|
||||
-----------
|
||||
The uninstaller may be the most straightforward of the installer components. The only complexity comes from a need to avoid accidentally removing any user files that may have found their way into the installation directory; the general philosophy of the uninstaller is to remove everything that the installer creates, and nothing that it doesn't.
|
||||
|
||||
First, any registry entries the installer would have created are removed, even ones only used by very old installer versions. Then all the files that the uninstaller knows were created by the installer or are owned by the application are deleted, or flagged for deletion on reboot if any are in use. There are a few hard-coded directories that are known to be safe to delete (for example, the distribution directory, and any temporary directories created by the updater). For a list of application files that are safe to uninstall, we read a file from the application directory called ``precomplete``. This file is mainly used to tell the updater what it should do to clean out the directory when applying a complete update (one that replaces all application files), but that means it contains a handy auto-generated list of all application files, so it can be reused for uninstallation. If the application directory is empty after that, then it is removed, but it's left alone if any files are still present. Finally, if the copy of Firefox that was just uninstalled is the only one that was using the maintenance service, the maintenance service uninstaller is also run.
|
||||
|
||||
Note that profiles and any other user-generated files (e.g., crash reports) are specifically not uninstalled.
|
||||
|
||||
PostUpdate
|
||||
----------
|
||||
At the end of an application update cycle, after the new files are in place, the updater invokes the helper with the ``/PostUpdate`` command-line switch. The PostUpdate function fills a grab bag of responsibilities which are all focused around maintaining system integration objects created by the installer. For example, a number of registry entires contain the version number, so that has to be changed on updates. If the branding name of the application changes and shortcuts have to be renamed, that's done here as well. For one counterexample, changing icons does not require any code in PostUpdate, or anywhere else; new icons are automatically picked up by the shell. The PostUpdate function also keeps the maintenance service up to date.
|
||||
|
||||
It's important to remember that PostUpdate is, indeed, post-update. It doesn't run until after its own code has already been updated. This makes it really the only phase of the update process where changes can go into affect immediately in the first build that contains a patch, instead of having to wait for the next update after that. This makes it a good place to put anything that needs to be done before the new version of the application can run; this includes things like registering DLL's, which the installer also handles, but that PostUpdate has to take care of for existing installations.
|
||||
|
||||
It's also important to remember that PostUpdate, being part of the installer code, only exists on Windows, so it can't be used to fix things up on other platforms the same way.
|
||||
|
||||
Default Browser and Shortcut Handling
|
||||
-------------------------------------
|
||||
Windows versions older than 10 contain a control panel called Set Program Access and Defaults, or SPAD. As the name suggests, this was the UI for setting default programs for classes of activities ("web browser" or "e-mail client" for example), as the Windows 10 default program settings page is, but it also controls program "access," which is typically defined as whether or not shortcuts for the program exist. To support this interface, an application has to register a set of commands that the interface can invoke to hide or show the shortcuts, and to have the application make itself the default. We implement these actions in helper.exe; they're triggered by invoking it with the command-line switches ``/ShowShortcuts``, ``/HideShortcuts``, or ``/SetAsDefaultAppGlobal``.
|
||||
|
||||
The helper also implements the ``/SetAsDefaultAppUser`` switch, which is invoked by the "Make Default" button in the Firefox preferences UI.
|
||||
|
||||
On Windows 10 neither SetAsDefaultAppUser nor SetAsDefaultAppGlobal is effective because the default programs settings can only be modified by the Windows settings app. However they do still write the registry entries that are needed to get us an entry in the system default browser menu, should those entries not already exist (the installer always creates them, but running Firefox without having run the installer is supported). ShowShortcuts and HideShortcuts are never called on Windows 10 because the SPAD control panel no longer exists.
|
||||
|
||||
|
||||
.. _uninstaller.nsi: https://searchfox.org/mozilla-central/source/browser/installer/windows/nsis/uninstaller.nsi
|
||||
.. _shared.nsh: https://searchfox.org/mozilla-central/source/browser/installer/windows/nsis/shared.nsh
|
|
@ -0,0 +1,49 @@
|
|||
===============
|
||||
Installer Build
|
||||
===============
|
||||
|
||||
How to build the installers
|
||||
---------------------------
|
||||
|
||||
The easiest way to build an installer in your local tree is to run ``mach build installer``. The finished installers will be in ``$OBJDIR/dist/install/sea/``. You have to have a build of the application already done before that will work, but `artifact builds <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds>`_ are supported, so that can save you a lot of time if you're only doing installer work.
|
||||
|
||||
You'll also need to be on a Windows machine; the installer build depends on tools that aren't available for other platforms.
|
||||
|
||||
Stub installer
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The stub installer probably won't be built by default in a local tree; normally unless the build has been set to use one of the official update channels, only the full installer is built. If you need to work on the stub installer, you can override the default and get one built along with the full installer by adding ``export MOZ_STUB_INSTALLER=1`` to your mozconfig.
|
||||
|
||||
Uninstaller
|
||||
~~~~~~~~~~~
|
||||
|
||||
The uninstaller is built as part of the main application build, not the installer target, so ``mach build`` is what will get you an uninstaller. You'll find it at ``$OBJDIR/dist/bin/uninstaller/helper.exe``.
|
||||
|
||||
Branding
|
||||
~~~~~~~~
|
||||
|
||||
By default local builds use "unofficial" branding, which somewhat resembles a previous version of the Nightly branding, but is designed not to resemble any official channel too closely.
|
||||
|
||||
But sometimes you'll need to test installers that are built using one or more of the official channel branding configurations, perhaps to try out different strings, make sure different sets of art look good, or to test behavior around installing multiple channels at the same time.
|
||||
|
||||
You can build installers (and the entire application) with official branding by adding ``ac_add_options --with-branding=browser/branding/{nightly|aurora|official}`` to your mozconfig (the default branding is ``browser/branding/unofficial``).
|
||||
|
||||
Build process
|
||||
-------------
|
||||
|
||||
Both the full and stub installers are built through a similar process, which is summarized here along with references to the relevant bits of code.
|
||||
|
||||
Most of this procedure is done in `makensis.mk <http://searchfox.org/mozilla-central/source/toolkit/mozapps/installer/windows/nsis/makensis.mk>`_.
|
||||
|
||||
0. The application has to be in a packaged state, so the equivalent of ``mach package`` is run.
|
||||
1. All required files are copied into the instgen directory. This includes .nsi and .nsh script files, plugin DLL files, image and icon files, and the 7-zip SFX module and its configuration files.
|
||||
2. The NSIS scripts are compiled, resulting in setup.exe and setup-stub.exe (if building the stub is enabled).
|
||||
3. The 7-zip SFX module is run through UPX.
|
||||
4. The application files and the full installer setup.exe are compressed together into one 7-zip file.
|
||||
5. The stub installer is compressed into its own 7-zip file.
|
||||
6. The (UPX-packed) 7-zip SFX module, the correct configuration data, and the 7-zip file containing the application files and setup.exe are concatenated together. This results in the final full installer.
|
||||
7. The (still UPX-packed) 7-zip SFX module, the correct configuration data, and the 7-zip file containing the stub installer are concatenated together. This results in the final stub installer.
|
||||
|
||||
|
||||
If this is an official build running on Mozilla automation infrastructure, then after this the installers will be signed, like other build products. Release engineering owns that process, it's not within the scope of this documentation.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
===========================
|
||||
Stub Installer Architecture
|
||||
===========================
|
||||
|
||||
The stub is called a stub because it doesn't actually install anything. It's just a GUI frontend that downloads and runs the full installer in silent mode. The exact full installer that will be downloaded isn't baked into the stub; the channel and the locale (which are baked in) are sent in a request to the Bouncer service, which uses that information to redirect to the URL of the specific full installer file.
|
||||
|
||||
The main stub installer source code file is `stub.nsi <https://searchfox.org/mozilla-central/source/browser/installer/windows/nsis/stub.nsi>`_. Even though the stub installer doesn't install anything, it's still built on NSIS, using it largely as a GUI framework. This means the structure of stub.nsi is a bit odd for an NSIS script. There's only one section, and it's empty, and there are no predefined pages used (including no instfiles page, which we get a warning from the compiler about). The work is all done in two custom pages, createProfileCleanup and createInstall, and the functions called by those two pages. The basic execution flow is this:
|
||||
|
||||
1. .onInit checks basic system requirements, determines whether we should install a 64-bit or a 32-bit build, looks for an existing installation that we should try to pave over, displays a UAC prompt, and initializes lots of variables and GUI objects.
|
||||
2. createProfileCleanup determines if a profile cleanup prompt should be offered (see the ShouldPromptForProfileCleanup function), and draws the UI for that if so.
|
||||
3. createInstall draws the UI for the download/install page, kicks off the periodic timer that swaps out the blurb text every few seconds, and runs StartDownload.
|
||||
4. StartDownload invokes the InetBgDl plugin to begin the full installer download on a background thread. It then starts a periodic timer for the OnDownload function.
|
||||
5. Every time OnDownload runs (every 200 ms), it checks the status of the background download, retries or restarts if the download has failed, updates the progress bar if the download is still running, and verifies and runs the full installer if the download is complete.
|
||||
6. CheckInstall waits for the full installer to exit, then deletes the file.
|
||||
7. FinishInstall copies the post-signing data, then waits for the application to launch.
|
||||
8. Once the installed application is running and has shown a window (or if another copy was already running), the stub sends its ping and then exits.
|
|
@ -0,0 +1,38 @@
|
|||
============================
|
||||
Stub Installer Configuration
|
||||
============================
|
||||
|
||||
The stub installer doesn't offer many options to the user, most of its configuration is automatic and implicit. But there are two things the user can control, and here we'll discuss those and the automated settings.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
The stub installer automatically selects whether to install a 32-bit or a 64-bit build of Firefox. 64-bit will be selected only if these conditions all pass:
|
||||
|
||||
1. The operating system is a 64-bit build.
|
||||
2. The system has enough physical memory installed. Currently an amount strictly greater than 2 GB is required (that is, exactly 2 GB is not considered enough).
|
||||
3. No third-party software that is incompatible with the 64-bit build is present on the system.
|
||||
|
||||
If any of the above conditions is not satisfied, a 32-bit build is installed.
|
||||
|
||||
Scope
|
||||
-----
|
||||
We support creating the installation in either a machine or a per-user scope. This affects whether application files, shortcuts, and registry entires are created in locations that are accessible to any user on the machine or locations that are specific to a particular user. Even in the full installer there is no UI for configuring which scope is selected; instead both installers automatically select a scope based on whether they have the privileges needed to perform a machine scope installation. This means a user with those privileges can effectively control the scope by the selection they make in the Windows UAC prompt; rejecting it will mean that the installer doesn't see that user as an administrator and will perform a per-user installation.
|
||||
|
||||
Install Location
|
||||
----------------
|
||||
The user doesn't have any control over the install location used by the stub. To determine the location that will be used, first the stub looks for any existing installations of the same channel of Firefox. If it finds one of those and the architecture of that installation is the same as the one that's been selected for the new one, then the path for the new install will be set to the same as that install, effectively overwriting it. This allows the stub to be used as a repair method for broken installations. If there isn't any existing installation fitting those criteria, then a hard-coded default is selected based on the architecture, scope, and channel.
|
||||
|
||||
Profile Cleanup
|
||||
---------------
|
||||
If the stub installer detects that this could be a helpful thing to do, it will start off the installation by offering to clean up the user's Firefox profile. This is the same cleanup that's triggered by the "refresh" button in about:support, and it's performed by the same Firefox code (the stub really just asks the browser to do the cleanup using a command-line parameter, it doesn't try to perform the operation itself). The user can control whether this cleanup is done by toggling a checkbox that's shown before the installation begins.
|
||||
|
||||
There are two variations of the profile cleanup prompt that can be shown to the user, one that appears if the new installation would overwrite an existing one (the "paveover" prompt) and another if it would be a new installation (the "reinstall" prompt). The only difference is the text that the user sees, the two function identically.
|
||||
|
||||
This is the procedure that determines when one of the two cleanup prompts is shown:
|
||||
|
||||
1. Look for the current default Firefox profile. If there are no profiles or none is set as the default, don't show either prompt.
|
||||
2. Look for an existing installation by searching the registry for any copies of Firefox that are registered for potential file type associations. If none exist, show the reinstall prompt.
|
||||
3. Check if the existing installation is for the same channel that's being installed now. If not, don't show either prompt.
|
||||
4. Check the version of Firefox that the default profile we found in step 1 was last used with. This information comes from the profile's compatibility.ini file. If that version is more than 2 versions behind the current version, show the paveover prompt. Otherwise, don't show either prompt. Information about the current version is taken from `<https://product-details.mozilla.org/1.0/firefox_versions.json>`_.
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
==============
|
||||
Stub Installer
|
||||
==============
|
||||
|
||||
The stub installer is the default installer interface that most users installing Firefox will see. It's a tiny download (200-300 KB), so it gets the user into the product experience quickly. It's also a highly streamlined experience; there are no options or prompts offered, except in the case of a returning user (see Profile Cleanup). Running the stub installer immediately starts downloading and installing the browser, and automatically runs the new installation and exits when it's done.
|
||||
|
||||
|
||||
.. toctree::
|
||||
StubConfig
|
||||
StubPing
|
||||
StubArch
|
|
@ -0,0 +1,159 @@
|
|||
=========
|
||||
Stub Ping
|
||||
=========
|
||||
|
||||
When the stub installer completes with almost any result [1]_, it generates a ping containing some data about the system and about how the installation went. This ping isn't part of Firefox unified telemetry, it's a bespoke system; we can't use the telemetry client code when it isn't installed yet.
|
||||
|
||||
|
||||
Querying the stub ping
|
||||
----------------------
|
||||
|
||||
The stub ping data is available (to those with a Mozilla LDAP login) on `Redash <https://sql.telemetry.mozilla.org>`_. Make sure to select the ``DSMO-RS`` data source. The ``download_stats`` table is the main data table. It contains the columns in the following list.
|
||||
|
||||
Some of the columns are marked [DEPRECATED] because they involve features that were removed when the stub installer was streamlined in Firefox 55. These columns were not removed to keep compatibility and so we could continue to use the old data, but they should no longer be used.
|
||||
|
||||
timestamp
|
||||
Time the ping was received
|
||||
|
||||
build_channel
|
||||
Channel the installer was built with the branding for ("release", "beta", "nightly", or "default")
|
||||
|
||||
update_channel
|
||||
Value of MOZ_UPDATE_CHANNEL for the installer build; should generally be the same as build_channel
|
||||
|
||||
version
|
||||
Version number of the installed product, or 0 if the installation failed. This is **not** the version of the installer itself.
|
||||
|
||||
build_id
|
||||
Build ID of the installed product, or 0 of the installation failed
|
||||
|
||||
locale
|
||||
Locale of the installer and of the installed product, in AB_CD format
|
||||
|
||||
amd64_bit_build
|
||||
True if a 64-bit build was selected for installation. This means the OS is 64-bit, the RAM requirement was met, and no third-party software that blocks 64-bit installations was found.
|
||||
|
||||
amd64bit_os
|
||||
True if the version of Windows on the machine was 64-bit
|
||||
|
||||
os_version
|
||||
Version number of Windows in ``major.minor.build`` format [2]_
|
||||
|
||||
service_pack
|
||||
Latest Windows service pack installed on the machine
|
||||
|
||||
server_os
|
||||
True if the installed OS is a server version of Windows
|
||||
|
||||
admin_user
|
||||
True if the installer was run by a user with administrator privileges (and the UAC prompt was accepted)
|
||||
|
||||
default_path
|
||||
[DEPRECATED] True if the default installation path was not changed. We no longer support changing this in the streamlined stub, so this should always be true once `bug 1351697 <https://bugzilla.mozilla.org/show_bug.cgi?id=1351697>`_ is fixed
|
||||
|
||||
set_default
|
||||
[DEPRECATED] True if the option to set the new installation as the default browser was left selected. We no longer attempt to change the default browser setting in the streamlined stub, so this should always be false.
|
||||
|
||||
new_default
|
||||
[DEPRECATED] True if the new installation was successfully made the default browser. We no longer attempt to change the default browser setting in the streamlined stub, so this should always be false.
|
||||
|
||||
old_default
|
||||
True if an existing installation of Firefox was already set as the default browser
|
||||
|
||||
had_old_install
|
||||
True if at least one existing installation of Firefox was found on the system prior to this installation
|
||||
|
||||
old_version
|
||||
Version of the previously existing Firefox installation, if any
|
||||
|
||||
old_build_id
|
||||
Build ID of the previously existing Firefox installation, if any
|
||||
|
||||
bytes_downloaded
|
||||
Size of the full installer data that was transferred before the download ended (whether it failed, was canceled, or completed normally)
|
||||
|
||||
download_size
|
||||
Expected size of the full installer download according to the HTTP response headers
|
||||
|
||||
download_retries
|
||||
Number of times the full installer download was retried or resumed. 10 retries is the maximum.
|
||||
|
||||
download_time
|
||||
Number of seconds spent downloading the full installer
|
||||
|
||||
download_latency
|
||||
Seconds between sending the full installer download request and receiving the first response data
|
||||
|
||||
download_ip
|
||||
IP address of the server the full installer was download from (can be either IPv4 or IPv6)
|
||||
|
||||
manual_download
|
||||
True if the user clicked on the button that opens the manual download page. The prompt to do that is shown after the installation fails or is canceled.
|
||||
|
||||
intro_time
|
||||
[DEPRECATED] Seconds the user spent on the intro screen. The streamlined stub no longer has this screen, so this should always be 0.
|
||||
|
||||
options_time
|
||||
[DEPRECATED] Seconds the user spent on the options screen. The streamlined stub no longer has this screen, so this should always be 0.
|
||||
|
||||
download_phase_time
|
||||
Seconds spent in the download phase; should be very close to download_time, since nothing else happens in this phase.
|
||||
|
||||
preinstall_time
|
||||
Seconds spent verifying the downloaded full installer and preparing to run it
|
||||
|
||||
install_time
|
||||
Seconds the full installer ran for
|
||||
|
||||
finish_time
|
||||
Seconds spent waiting for the installed application to launch
|
||||
|
||||
succeeded
|
||||
True if a new installation was successfully created. False if that didn't happen for any reason, including when the user closed the installer window.
|
||||
|
||||
disk_space_error
|
||||
[DEPRECATED] True if the installation failed because the drive we're trying to install to does not have enough space. The streamlined stub no longer sends a ping in this case, because the installation drive can no longer be selected.
|
||||
|
||||
no_write_access
|
||||
[DEPRECATED] True if the installation failed because the user doesn't have permission to write to the path we're trying to install to. The streamlined stub no longer sends a ping in this case, because the installation drive can no longer be selected.
|
||||
|
||||
download_cancelled
|
||||
True if the installation failed because the user closed the window during the download.
|
||||
|
||||
out_of_retries
|
||||
True if the installation failed because the download had to be retried too many times (currently 10)
|
||||
|
||||
file_error
|
||||
True if the installation failed because the downloaded file couldn't be read from
|
||||
|
||||
sig_not_trusted
|
||||
True if the installation failed because the signature on the downloaded file wasn't valid and/or wasn't signed by a trusted authority
|
||||
|
||||
sig_unexpected
|
||||
True if the installation failed because the signature on the downloaded file didn't have the expected subject and issuer names
|
||||
|
||||
install_timeout
|
||||
True if the installation failed because running the full installer timed out. Currently that means it ran for more than 150 seconds for a new installation, or 165 seconds for a paveover installation.
|
||||
|
||||
new_launched
|
||||
True if the installation succeeded and we were able to launch the newly installed application.
|
||||
|
||||
old_running
|
||||
True if the installation succeeded and we weren't able to launch the newly installed application because a copy of Firefox was already running.
|
||||
|
||||
attribution
|
||||
Any attribution data that was included with the installer
|
||||
|
||||
profile_cleanup_prompt
|
||||
0: neither profile cleanup prompt was shown
|
||||
|
||||
1: the "reinstall" version of the profile cleanup prompt was shown (no existing installation was found, but the user did have an old Firefox profile)
|
||||
|
||||
2: the "paveover" version of the profile cleanup prompt was shown (an installation of Firefox was already present, but it's an older version)
|
||||
|
||||
profile_cleanup_requested
|
||||
True if either profile cleanup prompt was shown and the user accepted the prompt
|
||||
|
||||
|
||||
.. [1] No ping is sent if the installer exits early because initial system requirements checks fail.
|
||||
.. [2] Previous versions of Windows have used a very small set of build numbers through their entire lifecycle. However, Windows 10 gets a new build number with every major update (about every 6 months), and many more builds have been released on its insider channels. So, to prevent a huge amount of noise, queries using this field should generally filter out the build number and only use the major and minor version numbers to differentiate Windows versions, unless the build number is specifically needed.
|
|
@ -0,0 +1,19 @@
|
|||
=========
|
||||
Installer
|
||||
=========
|
||||
|
||||
The main role of the Firefox installer is to get a user running Firefox as quickly and reliably as possible, while taking all necessary steps to make Firefox an integrated part of the system.
|
||||
|
||||
It turns out that the only platform where we need an installer in order to accomplish all of that is Windows. So we only develop and ship and installer for Windows, and on other platforms we distribute a package in a non-executable format typical of applications distributed on that platform.
|
||||
|
||||
Currently, the installers are built on the `NSIS <http://nsis.sourceforge.net/Main_Page>`_ installer framework. This is a Windows-only framework which compiles scripts written in its custom language (along with some native plugins) into an executable installer.
|
||||
|
||||
We build two different kinds of installers, the :doc:`Stub Installer <StubInstaller>` and the :doc:`Full Installer <FullInstaller>`. The stub is the default installer intended for most individual users, and the full installer is aimed at power users and administrators who need more control.
|
||||
|
||||
There's also a third installer-related program, which is called :doc:`helper.exe <Helper>`. It's also written in NSIS and has a few different jobs that involve maintaining things that the installer sets up, including the uninstaller and a post-update routine.
|
||||
|
||||
.. toctree::
|
||||
InstallerBuild
|
||||
StubInstaller
|
||||
FullInstaller
|
||||
Helper
|
|
@ -9,3 +9,5 @@ DEFINES['APP_VERSION'] = CONFIG['FIREFOX_VERSION']
|
|||
DEFINES['MOZ_APP_NAME'] = CONFIG['MOZ_APP_NAME']
|
||||
DEFINES['MOZ_APP_DISPLAYNAME'] = CONFIG['MOZ_APP_DISPLAYNAME']
|
||||
DEFINES['MOZILLA_VERSION'] = CONFIG['MOZILLA_VERSION']
|
||||
|
||||
SPHINX_TREES['installer'] = 'docs'
|
||||
|
|
|
@ -18,11 +18,11 @@ pref-page =
|
|||
# This is used to determine the width of the search field in about:preferences,
|
||||
# in order to make the entire placeholder string visible
|
||||
#
|
||||
# Notice: The value of the `.style` attribute is a CSS string, and the `min-width`
|
||||
# Notice: The value of the `.style` attribute is a CSS string, and the `width`
|
||||
# is the name of the CSS property. It is intended only to adjust the element's width.
|
||||
# Do not translate.
|
||||
search-field =
|
||||
.style = min-width: 15.4em
|
||||
search-input =
|
||||
.style = width: 15.4em
|
||||
|
||||
pane-general-title = General
|
||||
category-general =
|
||||
|
|
|
@ -58,6 +58,7 @@ class ToolboxTab extends Component {
|
|||
"data-id": id,
|
||||
title: tooltip,
|
||||
type: "button",
|
||||
"aria-pressed": currentToolId === id ? "true" : "false",
|
||||
tabIndex: focusedButton === id ? "0" : "-1",
|
||||
onFocus: () => focusButton(id),
|
||||
onMouseDown: () => selectTool(id),
|
||||
|
|
|
@ -42,6 +42,7 @@ function selectAndCheckById(id) {
|
|||
return toolbox.selectTool(id).then(function () {
|
||||
let tab = toolbox.doc.getElementById("toolbox-tab-" + id);
|
||||
is(tab.classList.contains("selected"), true, "The " + id + " tab is selected");
|
||||
is(tab.getAttribute("aria-pressed"), "true", "The " + id + " tab is pressed");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,10 @@ var Services = require("Services");
|
|||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { PrefsHelper } = require("devtools/client/shared/prefs");
|
||||
|
||||
const STATUS_REVEAL_TIME = 5000;
|
||||
// Timeout to wait before we assume that a connect() timed out without an error.
|
||||
// In milliseconds. (With the Debugger pane open, this has been reported to last
|
||||
// more than 10 seconds!)
|
||||
const STATUS_REVEAL_TIME = 15000;
|
||||
|
||||
/**
|
||||
* Shortcuts for accessing various debugger preferences.
|
||||
|
@ -37,9 +40,17 @@ function appendStatusMessage(msg) {
|
|||
}
|
||||
}
|
||||
|
||||
function revealStatusMessage() {
|
||||
function toggleStatusMessage(visible = true) {
|
||||
let statusMessageContainer = document.getElementById("status-message-container");
|
||||
statusMessageContainer.hidden = false;
|
||||
statusMessageContainer.hidden = !visible;
|
||||
}
|
||||
|
||||
function revealStatusMessage() {
|
||||
toggleStatusMessage(true);
|
||||
}
|
||||
|
||||
function hideStatusMessage() {
|
||||
toggleStatusMessage(false);
|
||||
}
|
||||
|
||||
var connect = async function () {
|
||||
|
@ -99,14 +110,14 @@ window.addEventListener("load", async function () {
|
|||
let cmdClose = document.getElementById("toolbox-cmd-close");
|
||||
cmdClose.addEventListener("command", onCloseCommand);
|
||||
setPrefDefaults();
|
||||
// Reveal status message if connecting is slow or if an error occurs
|
||||
let delayedStatusReveal = setTimeout(() => {
|
||||
revealStatusMessage();
|
||||
}, STATUS_REVEAL_TIME);
|
||||
// Reveal status message if connecting is slow or if an error occurs.
|
||||
let delayedStatusReveal = setTimeout(revealStatusMessage, STATUS_REVEAL_TIME);
|
||||
try {
|
||||
await connect();
|
||||
clearTimeout(delayedStatusReveal);
|
||||
hideStatusMessage();
|
||||
} catch (e) {
|
||||
clearTimeout(delayedStatusReveal);
|
||||
appendStatusMessage(e);
|
||||
revealStatusMessage();
|
||||
console.error(e);
|
||||
|
|
|
@ -22,199 +22,199 @@
|
|||
<?xml-stylesheet href="chrome://devtools/skin/styleeditor.css" type="text/css"?>
|
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||
|
||||
<xul:window xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="style-editor-chrome-window">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://devtools/content/shared/theme-switching.js"/>
|
||||
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<xul:script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<xul:script type="application/javascript">
|
||||
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<script type="application/javascript">
|
||||
function goUpdateSourceEditorMenuItems() {
|
||||
goUpdateGlobalEditMenuItems();
|
||||
|
||||
['cmd_undo', 'cmd_redo', 'cmd_cut', 'cmd_paste',
|
||||
'cmd_delete', 'cmd_find', 'cmd_findAgain'].forEach(goUpdateCommand);
|
||||
}
|
||||
</xul:script>
|
||||
</script>
|
||||
|
||||
<xul:popupset id="style-editor-popups">
|
||||
<xul:menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<xul:menuitem id="cMenu_undo"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="cMenu_cut"/>
|
||||
<xul:menuitem id="cMenu_copy"/>
|
||||
<xul:menuitem id="cMenu_paste"/>
|
||||
<xul:menuitem id="cMenu_delete"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="cMenu_selectAll"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-menu-find"
|
||||
<popupset id="style-editor-popups">
|
||||
<menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<menuitem id="cMenu_undo"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="cMenu_cut"/>
|
||||
<menuitem id="cMenu_copy"/>
|
||||
<menuitem id="cMenu_paste"/>
|
||||
<menuitem id="cMenu_delete"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="cMenu_selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="se-menu-find"
|
||||
label="&findCmd.label;" accesskey="&findCmd.accesskey;" command="cmd_find"/>
|
||||
<xul:menuitem id="cMenu_findAgain"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-menu-gotoLine"
|
||||
<menuitem id="cMenu_findAgain"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="se-menu-gotoLine"
|
||||
label="&gotoLineCmd.label;"
|
||||
accesskey="&gotoLineCmd.accesskey;"
|
||||
key="key_gotoLine"
|
||||
command="cmd_gotoLine"/>
|
||||
</xul:menupopup>
|
||||
<xul:menupopup id="sidebar-context">
|
||||
<xul:menuitem id="context-openlinknewtab"
|
||||
</menupopup>
|
||||
<menupopup id="sidebar-context">
|
||||
<menuitem id="context-openlinknewtab"
|
||||
label="&openLinkNewTab.label;"/>
|
||||
</xul:menupopup>
|
||||
<xul:menupopup id="style-editor-options-popup"
|
||||
position="before_start">
|
||||
<xul:menuitem id="options-origsources"
|
||||
type="checkbox"
|
||||
label="&showOriginalSources.label;"
|
||||
accesskey="&showOriginalSources.accesskey;"/>
|
||||
<xul:menuitem id="options-show-media"
|
||||
type="checkbox"
|
||||
label="&showMediaSidebar.label;"
|
||||
accesskey="&showMediaSidebar.accesskey;"/>
|
||||
</xul:menupopup>
|
||||
</xul:popupset>
|
||||
</menupopup>
|
||||
<menupopup id="style-editor-options-popup"
|
||||
position="before_start">
|
||||
<menuitem id="options-origsources"
|
||||
type="checkbox"
|
||||
label="&showOriginalSources.label;"
|
||||
accesskey="&showOriginalSources.accesskey;"/>
|
||||
<menuitem id="options-show-media"
|
||||
type="checkbox"
|
||||
label="&showMediaSidebar.label;"
|
||||
accesskey="&showMediaSidebar.accesskey;"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
<xul:commandset id="editMenuCommands"/>
|
||||
<commandset id="editMenuCommands"/>
|
||||
|
||||
<xul:commandset id="sourceEditorCommands">
|
||||
<xul:command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
|
||||
<xul:command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
|
||||
<xul:command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')"/>
|
||||
</xul:commandset>
|
||||
<commandset id="sourceEditorCommands">
|
||||
<command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
|
||||
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
|
||||
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')"/>
|
||||
</commandset>
|
||||
|
||||
<xul:keyset id="sourceEditorKeys"/>
|
||||
<keyset id="sourceEditorKeys"/>
|
||||
|
||||
<xul:stack id="style-editor-chrome" class="loading theme-body">
|
||||
<stack id="style-editor-chrome" class="loading theme-body">
|
||||
|
||||
<xul:box class="splitview-root devtools-responsive-container" context="sidebar-context">
|
||||
<xul:box class="splitview-controller">
|
||||
<xul:box class="splitview-main">
|
||||
<xul:toolbar class="devtools-toolbar">
|
||||
<xul:hbox class="devtools-toolbarbutton-group">
|
||||
<xul:toolbarbutton class="style-editor-newButton devtools-toolbarbutton"
|
||||
<box class="splitview-root devtools-responsive-container" context="sidebar-context">
|
||||
<box class="splitview-controller">
|
||||
<box class="splitview-main">
|
||||
<toolbar class="devtools-toolbar">
|
||||
<hbox class="devtools-toolbarbutton-group">
|
||||
<toolbarbutton class="style-editor-newButton devtools-toolbarbutton"
|
||||
accesskey="&newButton.accesskey;"
|
||||
tooltiptext="&newButton.tooltip;"/>
|
||||
<xul:toolbarbutton class="style-editor-importButton devtools-toolbarbutton"
|
||||
<toolbarbutton class="style-editor-importButton devtools-toolbarbutton"
|
||||
accesskey="&importButton.accesskey;"
|
||||
tooltiptext="&importButton.tooltip;"/>
|
||||
</xul:hbox>
|
||||
<xul:spacer/>
|
||||
<xul:toolbarbutton id="style-editor-options"
|
||||
</hbox>
|
||||
<spacer/>
|
||||
<toolbarbutton id="style-editor-options"
|
||||
class="devtools-toolbarbutton devtools-option-toolbarbutton"
|
||||
tooltiptext="&optionsButton.tooltip;"
|
||||
popup="style-editor-options-popup"/>
|
||||
</xul:toolbar>
|
||||
</xul:box>
|
||||
<xul:box id="splitview-resizer-target" class="theme-sidebar splitview-nav-container"
|
||||
</toolbar>
|
||||
</box>
|
||||
<box id="splitview-resizer-target" class="theme-sidebar splitview-nav-container"
|
||||
persist="height">
|
||||
<ol class="splitview-nav" tabindex="0"></ol>
|
||||
<div class="splitview-nav placeholder empty">
|
||||
<p><strong>&noStyleSheet.label;</strong></p>
|
||||
<p>&noStyleSheet-tip-start.label;
|
||||
<a href="#"
|
||||
class="style-editor-newButton">&noStyleSheet-tip-action.label;</a>
|
||||
&noStyleSheet-tip-end.label;</p>
|
||||
</div>
|
||||
</xul:box> <!-- .splitview-nav-container -->
|
||||
</xul:box> <!-- .splitview-controller -->
|
||||
<xul:splitter class="devtools-side-splitter devtools-invisible-splitter"/>
|
||||
<xul:box class="splitview-side-details devtools-main-content"/>
|
||||
<html:ol class="splitview-nav" tabindex="0"></html:ol>
|
||||
<html:div class="splitview-nav placeholder empty">
|
||||
<html:p><html:strong>&noStyleSheet.label;</html:strong></html:p>
|
||||
<html:p>&noStyleSheet-tip-start.label;
|
||||
<html:a href="#"
|
||||
class="style-editor-newButton">&noStyleSheet-tip-action.label;</html:a>
|
||||
&noStyleSheet-tip-end.label;</html:p>
|
||||
</html:div>
|
||||
</box> <!-- .splitview-nav-container -->
|
||||
</box> <!-- .splitview-controller -->
|
||||
<splitter class="devtools-side-splitter devtools-invisible-splitter"/>
|
||||
<box class="splitview-side-details devtools-main-content"/>
|
||||
|
||||
<div id="splitview-templates" hidden="true">
|
||||
<li id="splitview-tpl-summary-stylesheet" tabindex="0">
|
||||
<xul:label class="stylesheet-enabled" tabindex="0"
|
||||
<html:div id="splitview-templates" hidden="true">
|
||||
<html:li id="splitview-tpl-summary-stylesheet" tabindex="0">
|
||||
<label class="stylesheet-enabled" tabindex="0"
|
||||
tooltiptext="&visibilityToggle.tooltip;"
|
||||
accesskey="&saveButton.accesskey;"></xul:label>
|
||||
<hgroup class="stylesheet-info">
|
||||
<h1><a class="stylesheet-name" tabindex="0"><xul:label crop="center"/></a></h1>
|
||||
<div class="stylesheet-more">
|
||||
<h3 class="stylesheet-title"></h3>
|
||||
<h3 class="stylesheet-linked-file"></h3>
|
||||
<h3 class="stylesheet-rule-count"></h3>
|
||||
<xul:spacer/>
|
||||
<h3><xul:label class="stylesheet-saveButton"
|
||||
accesskey="&saveButton.accesskey;"></label>
|
||||
<html:hgroup class="stylesheet-info">
|
||||
<html:h1><html:a class="stylesheet-name" tabindex="0"><label crop="center"/></html:a></html:h1>
|
||||
<html:div class="stylesheet-more">
|
||||
<html:h3 class="stylesheet-title"></html:h3>
|
||||
<html:h3 class="stylesheet-linked-file"></html:h3>
|
||||
<html:h3 class="stylesheet-rule-count"></html:h3>
|
||||
<spacer/>
|
||||
<html:h3><label class="stylesheet-saveButton"
|
||||
tooltiptext="&saveButton.tooltip;"
|
||||
accesskey="&saveButton.accesskey;">&saveButton.label;</xul:label></h3>
|
||||
</div>
|
||||
</hgroup>
|
||||
</li>
|
||||
accesskey="&saveButton.accesskey;">&saveButton.label;</label></html:h3>
|
||||
</html:div>
|
||||
</html:hgroup>
|
||||
</html:li>
|
||||
|
||||
<xul:box id="splitview-tpl-details-stylesheet" class="splitview-details">
|
||||
<xul:hbox class="stylesheet-details-container">
|
||||
<xul:box class="stylesheet-editor-input textbox"
|
||||
data-placeholder="&editorTextbox.placeholder;"/>
|
||||
<xul:splitter class="devtools-side-splitter"/>
|
||||
<xul:vbox class="stylesheet-sidebar theme-sidebar" hidden="true">
|
||||
<xul:toolbar class="devtools-toolbar">
|
||||
<box id="splitview-tpl-details-stylesheet" class="splitview-details">
|
||||
<hbox class="stylesheet-details-container">
|
||||
<box class="stylesheet-editor-input textbox"
|
||||
data-placeholder="&editorTextbox.placeholder;"/>
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
<vbox class="stylesheet-sidebar theme-sidebar" hidden="true">
|
||||
<toolbar class="devtools-toolbar">
|
||||
&mediaRules.label;
|
||||
</xul:toolbar>
|
||||
<xul:vbox class="stylesheet-media-container" flex="1">
|
||||
<div class="stylesheet-media-list" />
|
||||
</xul:vbox>
|
||||
</xul:vbox>
|
||||
</xul:hbox>
|
||||
</xul:box>
|
||||
</div> <!-- #splitview-templates -->
|
||||
</xul:box> <!-- .splitview-root -->
|
||||
</toolbar>
|
||||
<vbox class="stylesheet-media-container" flex="1">
|
||||
<html:div class="stylesheet-media-list" />
|
||||
</vbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</box>
|
||||
</html:div> <!-- #splitview-templates -->
|
||||
</box> <!-- .splitview-root -->
|
||||
|
||||
<xul:box class="csscoverage-template" hidden="true">
|
||||
<xul:toolbar class="devtools-toolbar csscoverage-toolbar">
|
||||
<xul:button class="devtools-toolbarbutton csscoverage-toolbarbutton"
|
||||
<box class="csscoverage-template" hidden="true">
|
||||
<toolbar class="devtools-toolbar csscoverage-toolbar">
|
||||
<button class="devtools-toolbarbutton csscoverage-toolbarbutton"
|
||||
label="&csscoverage.backButton;"
|
||||
onclick="${onback}"/>
|
||||
</xul:toolbar>
|
||||
</toolbar>
|
||||
<!-- The data for this comes from CSSUsageActor.createPageReport -->
|
||||
<div class="csscoverage-report-container">
|
||||
<div class="csscoverage-report-content">
|
||||
<div class="csscoverage-report-summary">
|
||||
<div class="csscoverage-report-chart"/>
|
||||
</div>
|
||||
<div class="csscoverage-report-unused">
|
||||
<h2>&csscoverage.unused;</h2>
|
||||
<p>&csscoverage.noMatches;</p>
|
||||
<div foreach="page in ${unused}">
|
||||
<h3>${page.url}</h3>
|
||||
<code foreach="rule in ${page.rules}"
|
||||
href="${rule.url}"
|
||||
class="csscoverage-list">${rule.selectorText}</code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="csscoverage-report-optimize">
|
||||
<h2>&csscoverage.optimize.header;</h2>
|
||||
<p>
|
||||
<html:div class="csscoverage-report-container">
|
||||
<html:div class="csscoverage-report-content">
|
||||
<html:div class="csscoverage-report-summary">
|
||||
<html:div class="csscoverage-report-chart"/>
|
||||
</html:div>
|
||||
<html:div class="csscoverage-report-unused">
|
||||
<html:h2>&csscoverage.unused;</html:h2>
|
||||
<html:p>&csscoverage.noMatches;</html:p>
|
||||
<html:div foreach="page in ${unused}">
|
||||
<html:h3>${page.url}</html:h3>
|
||||
<html:code foreach="rule in ${page.rules}"
|
||||
href="${rule.url}"
|
||||
class="csscoverage-list">${rule.selectorText}</html:code>
|
||||
</html:div>
|
||||
</html:div>
|
||||
<html:div class="csscoverage-report-optimize">
|
||||
<html:h2>&csscoverage.optimize.header;</html:h2>
|
||||
<html:p>
|
||||
&csscoverage.optimize.body1;
|
||||
<code><link ...></code>
|
||||
<html:code><link ...></html:code>
|
||||
&csscoverage.optimize.body2;
|
||||
<code><style>...</code>
|
||||
<html:code><style>...</html:code>
|
||||
&csscoverage.optimize.body3;
|
||||
</p>
|
||||
<div if="${preload.length == 0}">&csscoverage.optimize.bodyX;</div>
|
||||
<div if="${preload.length > 0}">
|
||||
<div foreach="page in ${preload}">
|
||||
<h3>${page.url}</h3>
|
||||
<textarea><style>
|
||||
<loop foreach="rule in ${page.rules}"
|
||||
onclick="${rule.onclick}">${rule.formattedCssText}</loop></style></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
</html:p>
|
||||
<html:div if="${preload.length == 0}">&csscoverage.optimize.bodyX;</html:div>
|
||||
<html:div if="${preload.length > 0}">
|
||||
<html:div foreach="page in ${preload}">
|
||||
<html:h3>${page.url}</html:h3>
|
||||
<html:textarea><style>
|
||||
<html:loop foreach="rule in ${page.rules}"
|
||||
onclick="${rule.onclick}">${rule.formattedCssText}</html:loop></style></html:textarea>
|
||||
</html:div>
|
||||
</html:div>
|
||||
<html:p>
|
||||
&csscoverage.footer1;
|
||||
<a target="_blank" href="&csscoverage.footer2a;">&csscoverage.footer3;</a>
|
||||
<html:a target="_blank" href="&csscoverage.footer2a;">&csscoverage.footer3;</html:a>
|
||||
&csscoverage.footer4;
|
||||
</p>
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
</xul:box>
|
||||
</html:p>
|
||||
</html:div>
|
||||
<html:p> </html:p>
|
||||
</html:div>
|
||||
</html:div>
|
||||
</box>
|
||||
|
||||
<xul:box class="csscoverage-report" hidden="true">
|
||||
</xul:box>
|
||||
<box class="csscoverage-report" hidden="true">
|
||||
</box>
|
||||
|
||||
</xul:stack>
|
||||
</stack>
|
||||
|
||||
</xul:window>
|
||||
</window>
|
||||
|
|
|
@ -994,6 +994,11 @@ a.learn-more-link.webconsole-learn-more-link {
|
|||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* Prefix text that can be set by ConsoleAPI option */
|
||||
.webconsole-output-wrapper .console-message-prefix {
|
||||
color: var(--theme-comment);
|
||||
}
|
||||
|
||||
/* Network Messages */
|
||||
|
||||
.webconsole-output-wrapper .message.network .method {
|
||||
|
|
|
@ -51,6 +51,7 @@ function ConsoleApiCall(props) {
|
|||
timeStamp,
|
||||
parameters,
|
||||
messageText,
|
||||
prefix,
|
||||
userProvidedStyles,
|
||||
} = message;
|
||||
|
||||
|
@ -74,6 +75,11 @@ function ConsoleApiCall(props) {
|
|||
messageBody = dom.span({className: "cm-variable"}, "console.table()");
|
||||
} else if (parameters) {
|
||||
messageBody = formatReps(messageBodyConfig);
|
||||
if (prefix) {
|
||||
messageBody.unshift(dom.span({
|
||||
className: "console-message-prefix"
|
||||
}, `${prefix}: `));
|
||||
}
|
||||
} else {
|
||||
messageBody = messageText;
|
||||
}
|
||||
|
|
|
@ -703,6 +703,8 @@ function passSearchFilters(message, filters) {
|
|||
|| isTextInMessageText(text, message.messageText)
|
||||
// Look for a match in notes.
|
||||
|| isTextInNotes(text, message.notes)
|
||||
// Look for a match in prefix.
|
||||
|| isTextInPrefix(text, message.prefix)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -804,6 +806,17 @@ function isTextInNotes(text, notes) {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given text is included in prefix.
|
||||
*/
|
||||
function isTextInPrefix(text, prefix) {
|
||||
if (!prefix) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return `${prefix}: `.toLocaleLowerCase().includes(text.toLocaleLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a flat array of all the grips and their properties.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,7 @@ const {
|
|||
MESSAGE_CLOSE,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/MessageIndent");
|
||||
const {prepareMessage} = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
|
||||
// Test fakes.
|
||||
const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
@ -87,6 +88,37 @@ describe("ConsoleAPICall component:", () => {
|
|||
expect(thirdElementStyle.color).toBe("blue");
|
||||
});
|
||||
|
||||
it("renders prefixed messages", () => {
|
||||
const stub = {
|
||||
"level": "debug",
|
||||
"filename": "resource:///modules/CustomizableUI.jsm",
|
||||
"lineNumber": 181,
|
||||
"functionName": "initialize",
|
||||
"timeStamp": 1519311532912,
|
||||
"arguments": [
|
||||
"Initializing"
|
||||
],
|
||||
"prefix": "MyNicePrefix",
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
"category": "webdev",
|
||||
"_type": "ConsoleAPI"
|
||||
};
|
||||
const wrapper = render(ConsoleApiCall({
|
||||
message: prepareMessage(stub, {getNextId: () => "p"}),
|
||||
serviceContainer
|
||||
}));
|
||||
const prefix = wrapper.find(".console-message-prefix");
|
||||
expect(prefix.text()).toBe("MyNicePrefix: ");
|
||||
|
||||
expect(wrapper.find(".message-body").text()).toBe("MyNicePrefix: Initializing");
|
||||
|
||||
// There should be the location
|
||||
const locationLink = wrapper.find(`.message-location`);
|
||||
expect(locationLink.length).toBe(1);
|
||||
expect(locationLink.text()).toBe("CustomizableUI.jsm:181");
|
||||
});
|
||||
|
||||
it("renders repeat node", () => {
|
||||
const message = stubPreparedMessages.get("console.log('foobar', 'test')");
|
||||
const wrapper = render(ConsoleApiCall({
|
||||
|
|
|
@ -40,7 +40,7 @@ describe("Message - location element", () => {
|
|||
expect(onViewSource.notCalled).toBe(true);
|
||||
});
|
||||
|
||||
it.only("Calls onViewSource when clicked and onViewSourceInDebugger undefined", () => {
|
||||
it("Calls onViewSource when clicked and onViewSourceInDebugger undefined", () => {
|
||||
const onViewSource = sinon.spy();
|
||||
|
||||
const message = stubPreparedMessages.get("console.log('foobar', 'test')");
|
||||
|
|
|
@ -37,7 +37,8 @@ stubPreparedMessages.set(`console.log('foobar', 'test')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log(undefined)`, new ConsoleMessage({
|
||||
|
@ -65,7 +66,8 @@ stubPreparedMessages.set(`console.log(undefined)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.warn('danger, will robinson!')`, new ConsoleMessage({
|
||||
|
@ -91,7 +93,8 @@ stubPreparedMessages.set(`console.warn('danger, will robinson!')`, new ConsoleMe
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log(NaN)`, new ConsoleMessage({
|
||||
|
@ -119,7 +122,8 @@ stubPreparedMessages.set(`console.log(NaN)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log(null)`, new ConsoleMessage({
|
||||
|
@ -147,7 +151,8 @@ stubPreparedMessages.set(`console.log(null)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('鼬')`, new ConsoleMessage({
|
||||
|
@ -173,7 +178,8 @@ stubPreparedMessages.set(`console.log('鼬')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.clear()`, new ConsoleMessage({
|
||||
|
@ -199,7 +205,8 @@ stubPreparedMessages.set(`console.clear()`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count('bar')`, new ConsoleMessage({
|
||||
|
@ -223,7 +230,8 @@ stubPreparedMessages.set(`console.count('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.assert(false, {message: 'foobar'})`, new ConsoleMessage({
|
||||
|
@ -279,7 +287,8 @@ stubPreparedMessages.set(`console.assert(false, {message: 'foobar'})`, new Conso
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('hello \nfrom \rthe \"string world!')`, new ConsoleMessage({
|
||||
|
@ -305,7 +314,8 @@ stubPreparedMessages.set(`console.log('hello \nfrom \rthe \"string world!')`, ne
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('úṇĩçödê țĕșť')`, new ConsoleMessage({
|
||||
|
@ -331,7 +341,8 @@ stubPreparedMessages.set(`console.log('úṇĩçödê țĕșť')`, new ConsoleMe
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.dirxml(window)`, new ConsoleMessage({
|
||||
|
@ -369,7 +380,8 @@ stubPreparedMessages.set(`console.dirxml(window)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('myarray', ['red', 'green', 'blue'])`, new ConsoleMessage({
|
||||
|
@ -413,7 +425,8 @@ stubPreparedMessages.set(`console.log('myarray', ['red', 'green', 'blue'])`, new
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('myregex', /a.b.c/)`, new ConsoleMessage({
|
||||
|
@ -449,7 +462,8 @@ stubPreparedMessages.set(`console.log('myregex', /a.b.c/)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.table(['red', 'green', 'blue']);`, new ConsoleMessage({
|
||||
|
@ -492,7 +506,8 @@ stubPreparedMessages.set(`console.table(['red', 'green', 'blue']);`, new Console
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', blue: 'blueValue'});`, new ConsoleMessage({
|
||||
|
@ -554,7 +569,8 @@ stubPreparedMessages.set(`console.log('myobject', {red: 'redValue', green: 'gree
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.debug('debug message');`, new ConsoleMessage({
|
||||
|
@ -580,7 +596,8 @@ stubPreparedMessages.set(`console.debug('debug message');`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.info('info message');`, new ConsoleMessage({
|
||||
|
@ -606,7 +623,8 @@ stubPreparedMessages.set(`console.info('info message');`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.error('error message');`, new ConsoleMessage({
|
||||
|
@ -639,7 +657,8 @@ stubPreparedMessages.set(`console.error('error message');`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('mymap')`, new ConsoleMessage({
|
||||
|
@ -688,7 +707,8 @@ stubPreparedMessages.set(`console.log('mymap')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log('myset')`, new ConsoleMessage({
|
||||
|
@ -731,7 +751,8 @@ stubPreparedMessages.set(`console.log('myset')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.trace()`, new ConsoleMessage({
|
||||
|
@ -774,7 +795,8 @@ stubPreparedMessages.set(`console.trace()`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.time('bar')`, new ConsoleMessage({
|
||||
|
@ -798,7 +820,8 @@ stubPreparedMessages.set(`console.time('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`timerAlreadyExists`, new ConsoleMessage({
|
||||
|
@ -822,7 +845,8 @@ stubPreparedMessages.set(`timerAlreadyExists`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.timeEnd('bar')`, new ConsoleMessage({
|
||||
|
@ -846,7 +870,8 @@ stubPreparedMessages.set(`console.timeEnd('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`timerDoesntExist`, new ConsoleMessage({
|
||||
|
@ -870,7 +895,8 @@ stubPreparedMessages.set(`timerDoesntExist`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.table('bar')`, new ConsoleMessage({
|
||||
|
@ -896,7 +922,8 @@ stubPreparedMessages.set(`console.table('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.table(['a', 'b', 'c'])`, new ConsoleMessage({
|
||||
|
@ -939,7 +966,8 @@ stubPreparedMessages.set(`console.table(['a', 'b', 'c'])`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.group('bar')`, new ConsoleMessage({
|
||||
|
@ -965,7 +993,8 @@ stubPreparedMessages.set(`console.group('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupEnd('bar')`, new ConsoleMessage({
|
||||
|
@ -989,7 +1018,8 @@ stubPreparedMessages.set(`console.groupEnd('bar')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupCollapsed('foo')`, new ConsoleMessage({
|
||||
|
@ -1015,7 +1045,8 @@ stubPreparedMessages.set(`console.groupCollapsed('foo')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupEnd('foo')`, new ConsoleMessage({
|
||||
|
@ -1039,7 +1070,8 @@ stubPreparedMessages.set(`console.groupEnd('foo')`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.group()`, new ConsoleMessage({
|
||||
|
@ -1065,7 +1097,8 @@ stubPreparedMessages.set(`console.group()`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupEnd()`, new ConsoleMessage({
|
||||
|
@ -1089,7 +1122,8 @@ stubPreparedMessages.set(`console.groupEnd()`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log(%cfoobar)`, new ConsoleMessage({
|
||||
|
@ -1119,7 +1153,8 @@ stubPreparedMessages.set(`console.log(%cfoobar)`, new ConsoleMessage({
|
|||
"color:red; line-height: 1.5; background:url('http://example.com/test')"
|
||||
],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.log("%cHello%c|%cWorld")`, new ConsoleMessage({
|
||||
|
@ -1151,7 +1186,8 @@ stubPreparedMessages.set(`console.log("%cHello%c|%cWorld")`, new ConsoleMessage(
|
|||
"color: blue"
|
||||
],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.group(%cfoo%cbar)`, new ConsoleMessage({
|
||||
|
@ -1181,7 +1217,8 @@ stubPreparedMessages.set(`console.group(%cfoo%cbar)`, new ConsoleMessage({
|
|||
"color:red;background:url('http://example.com/test')"
|
||||
],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupEnd(%cfoo%cbar)`, new ConsoleMessage({
|
||||
|
@ -1205,7 +1242,8 @@ stubPreparedMessages.set(`console.groupEnd(%cfoo%cbar)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupCollapsed(%cfoo%cbaz)`, new ConsoleMessage({
|
||||
|
@ -1235,7 +1273,8 @@ stubPreparedMessages.set(`console.groupCollapsed(%cfoo%cbaz)`, new ConsoleMessag
|
|||
"color:red;background:url('http://example.com/test')"
|
||||
],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.groupEnd(%cfoo%cbaz)`, new ConsoleMessage({
|
||||
|
@ -1259,7 +1298,8 @@ stubPreparedMessages.set(`console.groupEnd(%cfoo%cbaz)`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.dir({C, M, Y, K})`, new ConsoleMessage({
|
||||
|
@ -1326,7 +1366,8 @@ stubPreparedMessages.set(`console.dir({C, M, Y, K})`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | default: 1`, new ConsoleMessage({
|
||||
|
@ -1350,7 +1391,8 @@ stubPreparedMessages.set(`console.count | default: 1`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | default: 2`, new ConsoleMessage({
|
||||
|
@ -1374,7 +1416,8 @@ stubPreparedMessages.set(`console.count | default: 2`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | test counter: 1`, new ConsoleMessage({
|
||||
|
@ -1398,7 +1441,8 @@ stubPreparedMessages.set(`console.count | test counter: 1`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | test counter: 2`, new ConsoleMessage({
|
||||
|
@ -1422,7 +1466,8 @@ stubPreparedMessages.set(`console.count | test counter: 2`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | default: 3`, new ConsoleMessage({
|
||||
|
@ -1446,7 +1491,8 @@ stubPreparedMessages.set(`console.count | default: 3`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | clear`, new ConsoleMessage({
|
||||
|
@ -1472,7 +1518,8 @@ stubPreparedMessages.set(`console.count | clear`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | default: 4`, new ConsoleMessage({
|
||||
|
@ -1496,7 +1543,8 @@ stubPreparedMessages.set(`console.count | default: 4`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`console.count | test counter: 3`, new ConsoleMessage({
|
||||
|
@ -1520,7 +1568,8 @@ stubPreparedMessages.set(`console.count | test counter: 3`, new ConsoleMessage({
|
|||
"exceptionDocURL": null,
|
||||
"userProvidedStyles": [],
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPackets.set(`console.log('foobar', 'test')`, {
|
||||
|
|
|
@ -33,7 +33,8 @@ stubPreparedMessages.set(`Unknown property ‘such-unknown-property’. Declara
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`Error in parsing value for ‘padding-top’. Declaration dropped.`, new ConsoleMessage({
|
||||
|
@ -56,7 +57,8 @@ stubPreparedMessages.set(`Error in parsing value for ‘padding-top’. Declara
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPackets.set(`Unknown property ‘such-unknown-property’. Declaration dropped.`, {
|
||||
|
|
|
@ -41,7 +41,8 @@ stubPreparedMessages.set(`new Date(0)`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`asdf()`, new ConsoleMessage({
|
||||
|
@ -69,7 +70,8 @@ stubPreparedMessages.set(`asdf()`, new ConsoleMessage({
|
|||
"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`1 + @`, new ConsoleMessage({
|
||||
|
@ -97,7 +99,8 @@ stubPreparedMessages.set(`1 + @`, new ConsoleMessage({
|
|||
"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Illegal_character?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`inspect({a: 1})`, new ConsoleMessage({
|
||||
|
@ -140,7 +143,8 @@ stubPreparedMessages.set(`inspect({a: 1})`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`cd(document)`, new ConsoleMessage({
|
||||
|
@ -163,7 +167,8 @@ stubPreparedMessages.set(`cd(document)`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`undefined`, new ConsoleMessage({
|
||||
|
@ -185,7 +190,8 @@ stubPreparedMessages.set(`undefined`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`longString message Error`, new ConsoleMessage({
|
||||
|
@ -213,7 +219,8 @@ stubPreparedMessages.set(`longString message Error`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`eval throw ""`, new ConsoleMessage({
|
||||
|
@ -236,7 +243,8 @@ stubPreparedMessages.set(`eval throw ""`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`eval throw "tomato"`, new ConsoleMessage({
|
||||
|
@ -259,7 +267,8 @@ stubPreparedMessages.set(`eval throw "tomato"`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPackets.set(`new Date(0)`, {
|
||||
|
|
|
@ -65,7 +65,8 @@ stubPreparedMessages.set(`ReferenceError: asdf is not defined`, new ConsoleMessa
|
|||
"exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`SyntaxError: redeclaration of let a`, new ConsoleMessage({
|
||||
|
@ -110,7 +111,8 @@ stubPreparedMessages.set(`SyntaxError: redeclaration of let a`, new ConsoleMessa
|
|||
}
|
||||
}
|
||||
],
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`TypeError longString message`, new ConsoleMessage({
|
||||
|
@ -157,7 +159,8 @@ stubPreparedMessages.set(`TypeError longString message`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`throw ""`, new ConsoleMessage({
|
||||
|
@ -176,7 +179,8 @@ stubPreparedMessages.set(`throw ""`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPreparedMessages.set(`throw "tomato"`, new ConsoleMessage({
|
||||
|
@ -195,7 +199,8 @@ stubPreparedMessages.set(`throw "tomato"`, new ConsoleMessage({
|
|||
"groupId": null,
|
||||
"userProvidedStyles": null,
|
||||
"notes": null,
|
||||
"indent": 0
|
||||
"indent": 0,
|
||||
"prefix": ""
|
||||
}));
|
||||
|
||||
stubPackets.set(`ReferenceError: asdf is not defined`, {
|
||||
|
|
|
@ -186,6 +186,37 @@ describe("Filtering", () => {
|
|||
expect(messages.length - numUnfilterableMessages).toEqual(1);
|
||||
});
|
||||
|
||||
it("matches prefixed log message", () => {
|
||||
const stub = {
|
||||
"level": "debug",
|
||||
"filename": "resource:///modules/CustomizableUI.jsm",
|
||||
"lineNumber": 181,
|
||||
"functionName": "initialize",
|
||||
"timeStamp": 1519311532912,
|
||||
"arguments": [
|
||||
"Initializing"
|
||||
],
|
||||
"prefix": "MyNicePrefix",
|
||||
"workerType": "none",
|
||||
"styles": [],
|
||||
"category": "webdev",
|
||||
"_type": "ConsoleAPI"
|
||||
};
|
||||
store.dispatch(messagesAdd([stub]));
|
||||
|
||||
store.dispatch(actions.filterTextSet("MyNice"));
|
||||
let messages = getVisibleMessages(store.getState());
|
||||
expect(messages.length - numUnfilterableMessages).toEqual(1);
|
||||
|
||||
store.dispatch(actions.filterTextSet("MyNicePrefix"));
|
||||
messages = getVisibleMessages(store.getState());
|
||||
expect(messages.length - numUnfilterableMessages).toEqual(1);
|
||||
|
||||
store.dispatch(actions.filterTextSet("MyNicePrefix:"));
|
||||
messages = getVisibleMessages(store.getState());
|
||||
expect(messages.length - numUnfilterableMessages).toEqual(1);
|
||||
});
|
||||
|
||||
it("restores all messages once text is cleared", () => {
|
||||
store.dispatch(actions.filterTextSet("danger"));
|
||||
store.dispatch(actions.filterTextSet(""));
|
||||
|
|
|
@ -43,6 +43,7 @@ exports.ConsoleMessage = function (props) {
|
|||
userProvidedStyles: null,
|
||||
notes: null,
|
||||
indent: 0,
|
||||
prefix: "",
|
||||
}, props);
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ const {
|
|||
} = require("../types");
|
||||
|
||||
function prepareMessage(packet, idGenerator) {
|
||||
// This packet is already in the expected packet structure. Simply return.
|
||||
if (!packet.source) {
|
||||
packet = transformPacket(packet);
|
||||
}
|
||||
|
@ -167,6 +166,7 @@ function transformConsoleAPICallPacket(packet) {
|
|||
frame,
|
||||
timeStamp: message.timeStamp,
|
||||
userProvidedStyles: message.styles,
|
||||
prefix: message.prefix,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -180,38 +180,6 @@ nsIContent::GetAssignedSlotByMode() const
|
|||
return slot;
|
||||
}
|
||||
|
||||
nsINode*
|
||||
nsIContent::GetFlattenedTreeParentForDocumentElementNAC() const
|
||||
{
|
||||
MOZ_ASSERT(IsRootOfNativeAnonymousSubtree());
|
||||
MOZ_ASSERT(GetParent());
|
||||
MOZ_ASSERT(GetParent() == OwnerDoc()->GetRootElement());
|
||||
MOZ_ASSERT(!IsGeneratedContentContainerForAfter());
|
||||
MOZ_ASSERT(!IsGeneratedContentContainerForBefore());
|
||||
|
||||
nsIContent* parent = GetParent();
|
||||
AutoTArray<nsIContent*, 8> rootElementNAC;
|
||||
nsContentUtils::AppendNativeAnonymousChildren(
|
||||
parent, rootElementNAC, nsIContent::eSkipDocumentLevelNativeAnonymousContent);
|
||||
const bool isDocLevelNAC = !rootElementNAC.Contains(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// The code below would be slightly more direct, but it gets the wrong
|
||||
// answer when the root scrollframe is being bootstrapped and we're
|
||||
// trying to style the scrollbars (since GetRootScrollFrame() still returns
|
||||
// null at that point). Verify that the results match otherwise.
|
||||
AutoTArray<nsIContent*, 8> docLevelNAC;
|
||||
nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(OwnerDoc(), docLevelNAC);
|
||||
nsIPresShell* shell = OwnerDoc()->GetShell();
|
||||
MOZ_ASSERT_IF(shell && shell->GetRootScrollFrame(),
|
||||
isDocLevelNAC == docLevelNAC.Contains(this));
|
||||
}
|
||||
#endif
|
||||
|
||||
return isDocLevelNAC ? OwnerDocAsNode() : parent;
|
||||
}
|
||||
|
||||
nsIContent::IMEState
|
||||
nsIContent::GetDesiredIMEState()
|
||||
{
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
#include <algorithm>
|
||||
#include "mozilla/dom/NodeInfoInlines.h"
|
||||
|
||||
// Form related includes
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
|
||||
#include "PLDHashTable.h"
|
||||
|
||||
#ifdef DEBUG_CONTENT_LIST
|
||||
|
|
|
@ -134,7 +134,6 @@
|
|||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
|
@ -10490,6 +10489,9 @@ nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
|||
nsTArray<nsIContent*>& aElements)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
#ifdef DEBUG
|
||||
size_t oldLength = aElements.Length();
|
||||
#endif
|
||||
|
||||
if (nsIPresShell* presShell = aDocument->GetShell()) {
|
||||
if (nsIFrame* scrollFrame = presShell->GetRootScrollFrame()) {
|
||||
|
@ -10505,6 +10507,14 @@ nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (size_t i = oldLength; i < aElements.Length(); i++) {
|
||||
MOZ_ASSERT(
|
||||
aElements[i]->GetProperty(nsGkAtoms::docLevelNativeAnonymousContent),
|
||||
"Someone here has lied, or missed to flag the node");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -125,7 +125,6 @@
|
|||
#include "nsIScriptContext.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsHTMLDocument.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
|
||||
|
@ -160,6 +159,7 @@
|
|||
#include "nsEscape.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "mozilla/dom/HTMLFormElement.h"
|
||||
#include "mozilla/dom/HTMLLinkElement.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
|
@ -8026,12 +8026,11 @@ nsDocument::Sanitize()
|
|||
for (uint32_t i = 0; i < length; ++i) {
|
||||
NS_ASSERTION(nodes->Item(i), "null item in nodelist");
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form = do_QueryInterface(nodes->Item(i));
|
||||
HTMLFormElement* form = HTMLFormElement::FromContent(nodes->Item(i));
|
||||
if (!form)
|
||||
continue;
|
||||
|
||||
nodes->Item(i)->AsElement()->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::autocomplete, value);
|
||||
form->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete, value);
|
||||
if (value.LowerCaseEqualsLiteral("off"))
|
||||
form->Reset();
|
||||
}
|
||||
|
|
|
@ -2182,7 +2182,8 @@ GK_ATOM(genConInitializerProperty, "QuoteNodeProperty")
|
|||
GK_ATOM(labelMouseDownPtProperty, "LabelMouseDownPtProperty")
|
||||
GK_ATOM(lockedStyleStates, "lockedStyleStates")
|
||||
GK_ATOM(apzCallbackTransform, "apzCallbackTransform")
|
||||
GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode")
|
||||
GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode") // bool
|
||||
GK_ATOM(docLevelNativeAnonymousContent, "docLevelNativeAnonymousContent") // bool
|
||||
GK_ATOM(paintRequestTime, "PaintRequestTime")
|
||||
GK_ATOM(pseudoProperty, "PseudoProperty") // CSSPseudoElementType
|
||||
GK_ATOM(manualNACProperty, "ManualNACProperty") // ManualNAC*
|
||||
|
|
|
@ -616,16 +616,6 @@ public:
|
|||
*/
|
||||
inline nsIContent* GetFlattenedTreeParent() const;
|
||||
|
||||
/**
|
||||
* Get the flattened tree parent for NAC holding from the document element,
|
||||
* from the point of view of the style system.
|
||||
*
|
||||
* Document-level anonymous content holds from the document element, even
|
||||
* though they should not be treated as such (they should be parented to the
|
||||
* document instead, and shouldn't inherit from the document element).
|
||||
*/
|
||||
nsINode* GetFlattenedTreeParentForDocumentElementNAC() const;
|
||||
|
||||
/**
|
||||
* API to check if this is a link that's traversed in response to user input
|
||||
* (e.g. a click event). Specializations for HTML/SVG/generic XML allow for
|
||||
|
|
|
@ -78,10 +78,10 @@ GetFlattenedTreeParentNode(const nsINode* aNode)
|
|||
|
||||
if (aType == nsINode::eForStyle &&
|
||||
content->IsRootOfNativeAnonymousSubtree() &&
|
||||
parentAsContent == content->OwnerDoc()->GetRootElement() &&
|
||||
!content->IsGeneratedContentContainerForAfter() &&
|
||||
!content->IsGeneratedContentContainerForBefore()) {
|
||||
return content->GetFlattenedTreeParentForDocumentElementNAC();
|
||||
parentAsContent == content->OwnerDoc()->GetRootElement()) {
|
||||
const bool docLevel =
|
||||
content->GetProperty(nsGkAtoms::docLevelNativeAnonymousContent);
|
||||
return docLevel ? content->OwnerDocAsNode() : parent;
|
||||
}
|
||||
|
||||
if (content->IsRootOfAnonymousSubtree()) {
|
||||
|
|
|
@ -557,7 +557,7 @@ public:
|
|||
*
|
||||
* For all other cases OwnerDoc and GetOwnerDocument behave identically.
|
||||
*/
|
||||
nsIDocument *OwnerDoc() const
|
||||
nsIDocument* OwnerDoc() const
|
||||
{
|
||||
return mNodeInfo->GetDocument();
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ public:
|
|||
* Return the "owner document" of this node as an nsINode*. Implemented
|
||||
* in nsIDocument.h.
|
||||
*/
|
||||
nsINode *OwnerDocAsNode() const;
|
||||
inline nsINode* OwnerDocAsNode() const;
|
||||
|
||||
/**
|
||||
* Returns true if the content has an ancestor that is a document.
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "HTMLFormSubmissionConstants.h"
|
||||
#include "mozilla/dom/HTMLButtonElementBinding.h"
|
||||
#include "mozilla/dom/HTMLFormSubmission.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
|
|
@ -165,8 +165,6 @@ HTMLFormElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
|
|||
}
|
||||
}
|
||||
|
||||
// nsIDOMHTMLFormElement
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLFormElement)
|
||||
|
||||
nsIHTMLCollection*
|
||||
|
@ -225,17 +223,20 @@ HTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||
aOldValue, aSubjectPrincipal, aNotify);
|
||||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(HTMLFormElement, AcceptCharset, acceptcharset)
|
||||
NS_IMPL_ACTION_ATTR(HTMLFormElement, Action, action)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLFormElement, Autocomplete, autocomplete,
|
||||
kFormDefaultAutocomplete->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLFormElement, Enctype, enctype,
|
||||
kFormDefaultEnctype->tag)
|
||||
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLFormElement, Method, method,
|
||||
kFormDefaultMethod->tag)
|
||||
NS_IMPL_BOOL_ATTR(HTMLFormElement, NoValidate, novalidate)
|
||||
NS_IMPL_STRING_ATTR(HTMLFormElement, Name, name)
|
||||
NS_IMPL_STRING_ATTR(HTMLFormElement, Target, target)
|
||||
void HTMLFormElement::GetAutocomplete(nsAString& aValue)
|
||||
{
|
||||
GetEnumAttr(nsGkAtoms::autocomplete, kFormDefaultAutocomplete->tag, aValue);
|
||||
}
|
||||
|
||||
void HTMLFormElement::GetEnctype(nsAString& aValue)
|
||||
{
|
||||
GetEnumAttr(nsGkAtoms::enctype, kFormDefaultEnctype->tag, aValue);
|
||||
}
|
||||
|
||||
void HTMLFormElement::GetMethod(nsAString& aValue)
|
||||
{
|
||||
GetEnumAttr(nsGkAtoms::method, kFormDefaultMethod->tag, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLFormElement::Submit(ErrorResult& aRv)
|
||||
|
@ -252,27 +253,11 @@ HTMLFormElement::Submit(ErrorResult& aRv)
|
|||
aRv = DoSubmitOrReset(nullptr, eFormSubmit);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::Submit()
|
||||
{
|
||||
ErrorResult rv;
|
||||
Submit(rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
HTMLFormElement::Reset()
|
||||
{
|
||||
InternalFormEvent event(true, eFormReset);
|
||||
EventDispatcher::Dispatch(static_cast<nsIContent*>(this), nullptr, &event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::CheckValidity(bool* retVal)
|
||||
{
|
||||
*retVal = CheckValidity();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1844,31 +1829,12 @@ HTMLFormElement::IsLastActiveElement(const nsIFormControl* aControl) const
|
|||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::GetEncoding(nsAString& aEncoding)
|
||||
{
|
||||
return GetEnctype(aEncoding);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::SetEncoding(const nsAString& aEncoding)
|
||||
{
|
||||
return SetEnctype(aEncoding);
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTMLFormElement::Length()
|
||||
{
|
||||
return mControls->Length();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::GetLength(int32_t* aLength)
|
||||
{
|
||||
*aLength = Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLFormElement::ForgetCurrentSubmission()
|
||||
{
|
||||
|
|
|
@ -44,6 +44,8 @@ class HTMLFormElement final : public nsGenericHTMLElement,
|
|||
friend class HTMLFormControlsCollection;
|
||||
|
||||
public:
|
||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFormElement, form)
|
||||
|
||||
explicit HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
|
||||
|
||||
enum {
|
||||
|
@ -325,31 +327,33 @@ public:
|
|||
}
|
||||
|
||||
void GetAction(nsString& aValue);
|
||||
|
||||
void SetAction(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::action, aValue, aRv);
|
||||
}
|
||||
|
||||
// XPCOM GetAutocomplete() is OK
|
||||
void GetAutocomplete(nsAString& aValue);
|
||||
void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
|
||||
}
|
||||
|
||||
// XPCOM GetEnctype() is OK
|
||||
void GetEnctype(nsAString& aValue);
|
||||
void SetEnctype(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::enctype, aValue, aRv);
|
||||
}
|
||||
|
||||
// XPCOM GetEncoding() is OK
|
||||
void GetEncoding(nsAString& aValue)
|
||||
{
|
||||
GetEnctype(aValue);
|
||||
}
|
||||
void SetEncoding(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetEnctype(aValue, aRv);
|
||||
}
|
||||
|
||||
// XPCOM GetMethod() is OK
|
||||
void GetMethod(nsAString& aValue);
|
||||
void SetMethod(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::method, aValue, aRv);
|
||||
|
@ -392,8 +396,7 @@ public:
|
|||
int32_t Length();
|
||||
|
||||
void Submit(ErrorResult& aRv);
|
||||
|
||||
// XPCOM Reset() is OK
|
||||
void Reset();
|
||||
|
||||
bool CheckValidity()
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsError.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "nsRepeatService.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "mozilla/dom/HTMLLegendElement.h"
|
||||
#include "mozilla/dom/HTMLLegendElementBinding.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "mozilla/dom/HTMLOptionElement.h"
|
||||
#include "mozilla/dom/HTMLOptionElementBinding.h"
|
||||
#include "mozilla/dom/HTMLSelectElement.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "nsIConstraintValidation.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIForm.h"
|
||||
|
|
|
@ -19,19 +19,4 @@
|
|||
[uuid(ad9b2ad0-9d29-43f6-b1a2-a1fd24627e6b)]
|
||||
interface nsIDOMHTMLFormElement : nsISupports
|
||||
{
|
||||
attribute DOMString acceptCharset;
|
||||
attribute DOMString action;
|
||||
attribute DOMString autocomplete;
|
||||
attribute DOMString enctype;
|
||||
attribute DOMString encoding;
|
||||
attribute DOMString method;
|
||||
attribute DOMString name;
|
||||
attribute boolean noValidate;
|
||||
attribute DOMString target;
|
||||
|
||||
readonly attribute long length;
|
||||
|
||||
void submit();
|
||||
void reset();
|
||||
boolean checkValidity();
|
||||
};
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "nsIContentSink.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "mozilla/dom/NodeInfo.h"
|
||||
#include "nsIScriptContext.h"
|
||||
|
|
|
@ -37,8 +37,11 @@ ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
|
|||
|
||||
if (length >= mChunkSize * 4) {
|
||||
auto range = AllocLargeChunk(length);
|
||||
uint8_t* dstPtr = mLargeAllocs.LastElement().get<uint8_t>();
|
||||
memcpy(dstPtr, aBytes.begin().get(), length);
|
||||
if (range.length()) {
|
||||
// Allocation was successful
|
||||
uint8_t* dstPtr = mLargeAllocs.LastElement().get<uint8_t>();
|
||||
memcpy(dstPtr, aBytes.begin().get(), length);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
|
@ -51,14 +54,20 @@ ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
|
|||
while (remainingBytesToCopy > 0) {
|
||||
if (dstCursor >= mSmallAllocs.Length() * mChunkSize) {
|
||||
if (!AllocChunk()) {
|
||||
// Allocation failed, so roll back to the state at the start of this
|
||||
// Write() call and abort.
|
||||
for (size_t i = mSmallAllocs.Length() ; currAllocLen < i ; i--) {
|
||||
RefCountedShmem& shm = mSmallAllocs.ElementAt(i);
|
||||
MOZ_ASSERT(i > 0);
|
||||
RefCountedShmem& shm = mSmallAllocs.ElementAt(i - 1);
|
||||
RefCountedShm::Dealloc(mShmAllocator, shm);
|
||||
mSmallAllocs.RemoveElementAt(i);
|
||||
mSmallAllocs.RemoveElementAt(i - 1);
|
||||
}
|
||||
MOZ_ASSERT(mSmallAllocs.Length() == currAllocLen);
|
||||
return layers::OffsetRange(0, start, 0);
|
||||
}
|
||||
continue;
|
||||
// Allocation succeeded, so dstCursor should now be pointing to
|
||||
// something inside the allocation buffer
|
||||
MOZ_ASSERT(dstCursor < (mSmallAllocs.Length() * mChunkSize));
|
||||
}
|
||||
|
||||
const size_t dstMaxOffset = mChunkSize * mSmallAllocs.Length();
|
||||
|
@ -124,6 +133,13 @@ ShmSegmentsWriter::Flush(nsTArray<RefCountedShmem>& aSmallAllocs, nsTArray<ipc::
|
|||
MOZ_ASSERT(aLargeAllocs.IsEmpty());
|
||||
mSmallAllocs.SwapElements(aSmallAllocs);
|
||||
mLargeAllocs.SwapElements(aLargeAllocs);
|
||||
mCursor = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
ShmSegmentsWriter::IsEmpty() const
|
||||
{
|
||||
return mCursor == 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -357,6 +373,16 @@ IpcResourceUpdateQueue::Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
|
|||
mWriter.Flush(aSmallAllocs, aLargeAllocs);
|
||||
}
|
||||
|
||||
bool
|
||||
IpcResourceUpdateQueue::IsEmpty() const
|
||||
{
|
||||
if (mUpdates.Length() == 0) {
|
||||
MOZ_ASSERT(mWriter.IsEmpty());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
IpcResourceUpdateQueue::Clear()
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
|
||||
|
||||
void Clear();
|
||||
bool IsEmpty() const;
|
||||
|
||||
protected:
|
||||
bool AllocChunk();
|
||||
|
@ -120,6 +121,8 @@ public:
|
|||
nsTArray<layers::RefCountedShmem>& aSmallAllocs,
|
||||
nsTArray<ipc::Shmem>& aLargeAllocs);
|
||||
|
||||
bool IsEmpty() const;
|
||||
|
||||
static void ReleaseShmems(ipc::IProtocol*, nsTArray<layers::RefCountedShmem>& aShmems);
|
||||
static void ReleaseShmems(ipc::IProtocol*, nsTArray<ipc::Shmem>& aShmems);
|
||||
protected:
|
||||
|
|
|
@ -129,6 +129,10 @@ WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
|
|||
return;
|
||||
}
|
||||
|
||||
if (aResources.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<OpUpdateResource> resourceUpdates;
|
||||
nsTArray<RefCountedShmem> smallShmems;
|
||||
nsTArray<ipc::Shmem> largeShmems;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 5
|
||||
#define VECS_PER_SPECIFIC_BRUSH 1
|
||||
#define FORCE_NO_PERSPECTIVE
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
@ -83,9 +83,10 @@ void brush_vs(
|
|||
}
|
||||
case 10: {
|
||||
// Color Matrix
|
||||
vec4 data[4] = fetch_from_resource_cache_4(prim_address + 1);
|
||||
vColorMat = mat4(amount, data[0], data[1], data[2]);
|
||||
vColorOffset = data[3];
|
||||
vec4 mat_data[4] = fetch_from_resource_cache_4(user_data.z);
|
||||
vec4 offset_data = fetch_from_resource_cache_1(user_data.z + 4);
|
||||
vColorMat = mat4(mat_data[0], mat_data[1], mat_data[2], mat_data[3]);
|
||||
vColorOffset = offset_data;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
|
|
|
@ -40,7 +40,12 @@ void brush_vs(
|
|||
vUv.xy = mix(uv0, uv1, f);
|
||||
vUv.xy /= texture_size;
|
||||
|
||||
vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
|
||||
// Handle case where the UV coords are inverted (e.g. from an
|
||||
// external image).
|
||||
vUvBounds = vec4(
|
||||
min(uv0, uv1) + vec2(0.5),
|
||||
max(uv0, uv1) - vec2(0.5)
|
||||
) / texture_size.xyxy;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vLocalPos = vi.local_pos;
|
||||
|
|
|
@ -119,38 +119,7 @@ void brush_vs(
|
|||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
#define MAGIC_WAVY_LINE_AA_SNAP 0.7
|
||||
|
||||
float det(vec2 a, vec2 b) {
|
||||
return a.x * b.y - b.x * a.y;
|
||||
}
|
||||
|
||||
// From: http://research.microsoft.com/en-us/um/people/hoppe/ravg.pdf
|
||||
vec2 get_distance_vector(vec2 b0, vec2 b1, vec2 b2) {
|
||||
float a = det(b0, b2);
|
||||
float b = 2.0 * det(b1, b0);
|
||||
float d = 2.0 * det(b2, b1);
|
||||
|
||||
float f = b * d - a * a;
|
||||
vec2 d21 = b2 - b1;
|
||||
vec2 d10 = b1 - b0;
|
||||
vec2 d20 = b2 - b0;
|
||||
|
||||
vec2 gf = 2.0 * (b *d21 + d * d10 + a * d20);
|
||||
gf = vec2(gf.y,-gf.x);
|
||||
vec2 pp = -f * gf / dot(gf, gf);
|
||||
vec2 d0p = b0 - pp;
|
||||
float ap = det(d0p, d20);
|
||||
float bp = 2.0 * det(d10, d0p);
|
||||
|
||||
float t = clamp((ap + bp) / (2.0 * a + b + d), 0.0, 1.0);
|
||||
return mix(mix(b0, b1, t), mix(b1,b2,t), t);
|
||||
}
|
||||
|
||||
// Approximate distance from point to quadratic bezier.
|
||||
float approx_distance(vec2 p, vec2 b0, vec2 b1, vec2 b2) {
|
||||
return length(get_distance_vector(b0 - p, b1 - p, b2 - p));
|
||||
}
|
||||
#define MAGIC_WAVY_LINE_AA_SNAP 0.5
|
||||
|
||||
vec4 brush_fs() {
|
||||
// Find the appropriate distance to apply the step over.
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 2
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
||||
flat varying int vGradientAddress;
|
||||
flat varying float vGradientRepeat;
|
||||
|
||||
flat varying vec2 vScaledDir;
|
||||
flat varying vec2 vStartPoint;
|
||||
|
||||
varying vec2 vPos;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
varying vec2 vLocalPos;
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
struct Gradient {
|
||||
vec4 start_end_point;
|
||||
vec4 extend_mode;
|
||||
};
|
||||
|
||||
Gradient fetch_gradient(int address) {
|
||||
vec4 data[2] = fetch_from_resource_cache_2(address);
|
||||
return Gradient(data[0], data[1]);
|
||||
}
|
||||
|
||||
void brush_vs(
|
||||
VertexInfo vi,
|
||||
int prim_address,
|
||||
RectWithSize local_rect,
|
||||
ivec3 user_data,
|
||||
PictureTask pic_task
|
||||
) {
|
||||
Gradient gradient = fetch_gradient(prim_address);
|
||||
|
||||
vPos = vi.local_pos - local_rect.p0;
|
||||
|
||||
vec2 start_point = gradient.start_end_point.xy;
|
||||
vec2 end_point = gradient.start_end_point.zw;
|
||||
vec2 dir = end_point - start_point;
|
||||
|
||||
vStartPoint = start_point;
|
||||
vScaledDir = dir / dot(dir, dir);
|
||||
|
||||
vGradientAddress = user_data.x;
|
||||
|
||||
// Whether to repeat the gradient instead of clamping.
|
||||
vGradientRepeat = float(int(gradient.extend_mode.x) != EXTEND_MODE_CLAMP);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vLocalPos = vi.local_pos;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
vec4 brush_fs() {
|
||||
float offset = dot(vPos - vStartPoint, vScaledDir);
|
||||
|
||||
vec4 color = sample_gradient(vGradientAddress,
|
||||
offset,
|
||||
vGradientRepeat);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
color *= init_transform_fs(vLocalPos);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 5
|
||||
#define VECS_PER_SPECIFIC_BRUSH 1
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define VECS_PER_SPECIFIC_BRUSH 5
|
||||
#define VECS_PER_SPECIFIC_BRUSH 1
|
||||
|
||||
#include shared,prim_shared,brush
|
||||
|
||||
|
|
|
@ -41,6 +41,12 @@ varying vec2 vLocalPos;
|
|||
flat varying vec4 vUvBounds_YUV;
|
||||
#endif
|
||||
|
||||
#ifdef WR_FEATURE_TEXTURE_RECT
|
||||
#define TEX_SIZE(sampler) vec2(1.0)
|
||||
#else
|
||||
#define TEX_SIZE(sampler) vec2(textureSize(sampler, 0).xy)
|
||||
#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
void write_uv_rect(
|
||||
int resource_id,
|
||||
|
@ -78,14 +84,14 @@ void brush_vs(
|
|||
#endif
|
||||
|
||||
#if defined (WR_FEATURE_YUV_PLANAR)
|
||||
write_uv_rect(user_data.x, f, vec2(textureSize(sColor0, 0).xy), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, vec2(textureSize(sColor1, 0).xy), vUv_U, vUvBounds_U);
|
||||
write_uv_rect(user_data.z, f, vec2(textureSize(sColor2, 0).xy), vUv_V, vUvBounds_V);
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
|
||||
write_uv_rect(user_data.z, f, TEX_SIZE(sColor2), vUv_V, vUvBounds_V);
|
||||
#elif defined (WR_FEATURE_YUV_NV12)
|
||||
write_uv_rect(user_data.x, f, vec2(textureSize(sColor0, 0).xy), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, vec2(textureSize(sColor1, 0).xy), vUv_UV, vUvBounds_UV);
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_UV, vUvBounds_UV);
|
||||
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
|
||||
write_uv_rect(user_data.x, f, vec2(textureSize(sColor0, 0).xy), vUv_YUV, vUvBounds_YUV);
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_YUV, vUvBounds_YUV);
|
||||
#endif //WR_FEATURE_YUV_*
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define SUBPX_DIR_HORIZONTAL 1
|
||||
#define SUBPX_DIR_VERTICAL 2
|
||||
|
||||
#define EPSILON 0.0001
|
||||
|
||||
uniform sampler2DArray sCacheA8;
|
||||
uniform sampler2DArray sCacheRGBA8;
|
||||
|
||||
|
@ -74,7 +76,6 @@ vec4[2] fetch_from_resource_cache_2(int address) {
|
|||
#define VECS_PER_RENDER_TASK 3
|
||||
#define VECS_PER_PRIM_HEADER 2
|
||||
#define VECS_PER_TEXT_RUN 3
|
||||
#define VECS_PER_GRADIENT 3
|
||||
#define VECS_PER_GRADIENT_STOP 2
|
||||
|
||||
uniform HIGHP_SAMPLER_FLOAT sampler2D sClipScrollNodes;
|
||||
|
@ -304,17 +305,6 @@ ClipArea fetch_clip_area(int index) {
|
|||
return area;
|
||||
}
|
||||
|
||||
struct Gradient {
|
||||
vec4 start_end_point;
|
||||
vec4 tile_size_repeat;
|
||||
vec4 extend_mode;
|
||||
};
|
||||
|
||||
Gradient fetch_gradient(int address) {
|
||||
vec4 data[3] = fetch_from_resource_cache_3(address);
|
||||
return Gradient(data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
struct Glyph {
|
||||
vec2 offset;
|
||||
};
|
||||
|
@ -748,7 +738,7 @@ void write_clip(vec2 global_pos, ClipArea area) {
|
|||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
/// Find the appropriate half range to apply the AA smoothstep over.
|
||||
/// Find the appropriate half range to apply the AA approximation over.
|
||||
/// This range represents a coefficient to go from one CSS pixel to half a device pixel.
|
||||
float compute_aa_range(vec2 position) {
|
||||
// The constant factor is chosen to compensate for the fact that length(fw) is equal
|
||||
|
@ -759,22 +749,41 @@ float compute_aa_range(vec2 position) {
|
|||
// such a pixel (axis aligned) is fully inside the border). We need this so that antialiased
|
||||
// curves properly connect with non-antialiased vertical or horizontal lines, among other things.
|
||||
//
|
||||
// Using larger aa steps is quite common when rendering shapes with distance fields.
|
||||
// It gives a smoother (although blurrier look) by extending the range that is smoothed
|
||||
// to produce the anti aliasing. In our case, however, extending the range inside of
|
||||
// the shape causes noticeable artifacts at the junction between an antialiased corner
|
||||
// and a straight edge.
|
||||
// Lines over a half-pixel away from the pixel center *can* intersect with the pixel square;
|
||||
// indeed, unless they are horizontal or vertical, they are guaranteed to. However, choosing
|
||||
// a nonzero area for such pixels causes noticeable artifacts at the junction between an anti-
|
||||
// aliased corner and a straight edge.
|
||||
//
|
||||
// We may want to adjust this constant in specific scenarios (for example keep the principled
|
||||
// value for straight edges where we want pixel-perfect equivalence with non antialiased lines
|
||||
// when axis aligned, while selecting a larger and smoother aa range on curves).
|
||||
return 0.35355 * length(fwidth(position));
|
||||
}
|
||||
|
||||
/// Return the blending coefficient to for distance antialiasing.
|
||||
/// Return the blending coefficient for distance antialiasing.
|
||||
///
|
||||
/// 0.0 means inside the shape, 1.0 means outside.
|
||||
///
|
||||
/// This cubic polynomial approximates the area of a 1x1 pixel square under a
|
||||
/// line, given the signed Euclidean distance from the center of the square to
|
||||
/// that line. Calculating the *exact* area would require taking into account
|
||||
/// not only this distance but also the angle of the line. However, in
|
||||
/// practice, this complexity is not required, as the area is roughly the same
|
||||
/// regardless of the angle.
|
||||
///
|
||||
/// The coefficients of this polynomial were determined through least-squares
|
||||
/// regression and are accurate to within 2.16% of the total area of the pixel
|
||||
/// square 95% of the time, with a maximum error of 3.53%.
|
||||
///
|
||||
/// See the comments in `compute_aa_range()` for more information on the
|
||||
/// cutoff values of -0.5 and 0.5.
|
||||
float distance_aa(float aa_range, float signed_distance) {
|
||||
return 1.0 - smoothstep(-aa_range, aa_range, signed_distance);
|
||||
float dist = 0.5 * signed_distance / aa_range;
|
||||
if (dist <= -0.5 + EPSILON)
|
||||
return 1.0;
|
||||
if (dist >= 0.5 - EPSILON)
|
||||
return 0.0;
|
||||
return 0.5 + dist * (0.8431027 * dist * dist - 1.14453603);
|
||||
}
|
||||
|
||||
float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include shared,prim_shared
|
||||
|
||||
flat varying int vGradientAddress;
|
||||
flat varying float vGradientRepeat;
|
||||
|
||||
flat varying vec2 vScaledDir;
|
||||
flat varying vec2 vStartPoint;
|
||||
|
||||
flat varying vec2 vTileSize;
|
||||
flat varying vec2 vTileRepeat;
|
||||
|
||||
varying vec2 vPos;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
Gradient gradient = fetch_gradient(prim.specific_prim_address);
|
||||
|
||||
VertexInfo vi = write_vertex(prim.local_rect,
|
||||
prim.local_clip_rect,
|
||||
prim.z,
|
||||
prim.scroll_node,
|
||||
prim.task,
|
||||
prim.local_rect);
|
||||
|
||||
vPos = vi.local_pos - prim.local_rect.p0;
|
||||
|
||||
vec2 start_point = gradient.start_end_point.xy;
|
||||
vec2 end_point = gradient.start_end_point.zw;
|
||||
vec2 dir = end_point - start_point;
|
||||
|
||||
vStartPoint = start_point;
|
||||
vScaledDir = dir / dot(dir, dir);
|
||||
|
||||
vTileSize = gradient.tile_size_repeat.xy;
|
||||
vTileRepeat = gradient.tile_size_repeat.zw;
|
||||
|
||||
vGradientAddress = prim.specific_prim_address + VECS_PER_GRADIENT;
|
||||
|
||||
// Whether to repeat the gradient instead of clamping.
|
||||
vGradientRepeat = float(int(gradient.extend_mode.x) != EXTEND_MODE_CLAMP);
|
||||
|
||||
write_clip(vi.screen_pos, prim.clip_area);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
void main(void) {
|
||||
vec2 pos = mod(vPos, vTileRepeat);
|
||||
|
||||
if (pos.x >= vTileSize.x ||
|
||||
pos.y >= vTileSize.y) {
|
||||
discard;
|
||||
}
|
||||
|
||||
float offset = dot(pos - vStartPoint, vScaledDir);
|
||||
|
||||
vec4 color = sample_gradient(vGradientAddress,
|
||||
offset,
|
||||
vGradientRepeat);
|
||||
|
||||
oFragColor = color * do_clip();
|
||||
}
|
||||
#endif
|
|
@ -1,119 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include shared,prim_shared
|
||||
|
||||
varying vec4 vColor;
|
||||
|
||||
varying vec2 vLocalPos;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
struct GradientStop {
|
||||
vec4 color;
|
||||
vec4 offset;
|
||||
};
|
||||
|
||||
GradientStop fetch_gradient_stop(int address) {
|
||||
vec4 data[2] = fetch_from_resource_cache_2(address);
|
||||
return GradientStop(data[0], data[1]);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
Gradient gradient = fetch_gradient(prim.specific_prim_address);
|
||||
|
||||
vec4 abs_start_end_point = gradient.start_end_point + prim.local_rect.p0.xyxy;
|
||||
|
||||
int stop_address = prim.specific_prim_address +
|
||||
VECS_PER_GRADIENT +
|
||||
VECS_PER_GRADIENT_STOP * prim.user_data0;
|
||||
|
||||
GradientStop g0 = fetch_gradient_stop(stop_address);
|
||||
GradientStop g1 = fetch_gradient_stop(stop_address + VECS_PER_GRADIENT_STOP);
|
||||
|
||||
RectWithSize segment_rect;
|
||||
vec2 axis;
|
||||
vec4 adjusted_color_g0 = g0.color;
|
||||
vec4 adjusted_color_g1 = g1.color;
|
||||
if (abs_start_end_point.y == abs_start_end_point.w) {
|
||||
// Calculate the x coord of the gradient stops
|
||||
vec2 g01_x = mix(abs_start_end_point.xx, abs_start_end_point.zz,
|
||||
vec2(g0.offset.x, g1.offset.x));
|
||||
|
||||
// The gradient stops might exceed the geometry rect so clamp them
|
||||
vec2 g01_x_clamped = clamp(g01_x,
|
||||
prim.local_rect.p0.xx,
|
||||
prim.local_rect.p0.xx + prim.local_rect.size.xx);
|
||||
|
||||
// Calculate the segment rect using the clamped coords
|
||||
segment_rect.p0 = vec2(g01_x_clamped.x, prim.local_rect.p0.y);
|
||||
segment_rect.size = vec2(g01_x_clamped.y - g01_x_clamped.x, prim.local_rect.size.y);
|
||||
axis = vec2(1.0, 0.0);
|
||||
|
||||
// Adjust the stop colors by how much they were clamped
|
||||
vec2 adjusted_offset = (g01_x_clamped - g01_x.xx) / (g01_x.y - g01_x.x);
|
||||
adjusted_color_g0 = mix(g0.color, g1.color, adjusted_offset.x);
|
||||
adjusted_color_g1 = mix(g0.color, g1.color, adjusted_offset.y);
|
||||
} else {
|
||||
// Calculate the y coord of the gradient stops
|
||||
vec2 g01_y = mix(abs_start_end_point.yy, abs_start_end_point.ww,
|
||||
vec2(g0.offset.x, g1.offset.x));
|
||||
|
||||
// The gradient stops might exceed the geometry rect so clamp them
|
||||
vec2 g01_y_clamped = clamp(g01_y,
|
||||
prim.local_rect.p0.yy,
|
||||
prim.local_rect.p0.yy + prim.local_rect.size.yy);
|
||||
|
||||
// Calculate the segment rect using the clamped coords
|
||||
segment_rect.p0 = vec2(prim.local_rect.p0.x, g01_y_clamped.x);
|
||||
segment_rect.size = vec2(prim.local_rect.size.x, g01_y_clamped.y - g01_y_clamped.x);
|
||||
axis = vec2(0.0, 1.0);
|
||||
|
||||
// Adjust the stop colors by how much they were clamped
|
||||
vec2 adjusted_offset = (g01_y_clamped - g01_y.xx) / (g01_y.y - g01_y.x);
|
||||
adjusted_color_g0 = mix(g0.color, g1.color, adjusted_offset.x);
|
||||
adjusted_color_g1 = mix(g0.color, g1.color, adjusted_offset.y);
|
||||
}
|
||||
|
||||
#ifdef WR_FEATURE_TRANSFORM
|
||||
VertexInfo vi = write_transform_vertex(segment_rect,
|
||||
prim.local_rect,
|
||||
prim.local_clip_rect,
|
||||
vec4(1.0),
|
||||
prim.z,
|
||||
prim.scroll_node,
|
||||
prim.task,
|
||||
true);
|
||||
vLocalPos = vi.local_pos;
|
||||
vec2 f = (vi.local_pos.xy - prim.local_rect.p0) / prim.local_rect.size;
|
||||
#else
|
||||
VertexInfo vi = write_vertex(segment_rect,
|
||||
prim.local_clip_rect,
|
||||
prim.z,
|
||||
prim.scroll_node,
|
||||
prim.task,
|
||||
prim.local_rect);
|
||||
|
||||
vec2 f = (vi.local_pos - segment_rect.p0) / segment_rect.size;
|
||||
vLocalPos = vi.local_pos;
|
||||
#endif
|
||||
|
||||
write_clip(vi.screen_pos, prim.clip_area);
|
||||
|
||||
vColor = mix(adjusted_color_g0, adjusted_color_g1, dot(f, axis));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
void main(void) {
|
||||
#ifdef WR_FEATURE_TRANSFORM
|
||||
float alpha = init_transform_fs(vLocalPos);
|
||||
#else
|
||||
float alpha = 1.0;
|
||||
#endif
|
||||
|
||||
alpha *= do_clip();
|
||||
oFragColor = dither(vColor * alpha);
|
||||
}
|
||||
#endif
|
|
@ -14,16 +14,9 @@
|
|||
|
||||
#include base
|
||||
|
||||
// The textureLod() doesn't support samplerExternalOES for WR_FEATURE_TEXTURE_EXTERNAL.
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt
|
||||
//
|
||||
// The textureLod() doesn't support sampler2DRect for WR_FEATURE_TEXTURE_RECT, too.
|
||||
//
|
||||
// Use texture() instead.
|
||||
#if defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_RECT) || defined(WR_FEATURE_TEXTURE_2D)
|
||||
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
|
||||
#else
|
||||
// In normal case, we use textureLod(). We haven't used the lod yet. So, we always pass 0.0 now.
|
||||
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveIn
|
|||
use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture};
|
||||
use picture::{ContentOrigin, PictureCompositeMode, PictureKind, PicturePrimitive, PictureSurface};
|
||||
use plane_split::{BspSplitter, Polygon, Splitter};
|
||||
use prim_store::{ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore};
|
||||
use prim_store::{CachedGradient, ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore};
|
||||
use prim_store::{BrushPrimitive, BrushKind, DeferredResolve, EdgeAaSegmentMask, PrimitiveRun};
|
||||
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKind, RenderTaskTree};
|
||||
use renderer::{BlendMode, ImageBufferKind};
|
||||
|
@ -38,8 +38,6 @@ const OPAQUE_TASK_ADDRESS: RenderTaskAddress = RenderTaskAddress(0x7fff);
|
|||
pub enum TransformBatchKind {
|
||||
TextRun(GlyphFormat),
|
||||
Image(ImageBufferKind),
|
||||
AlignedGradient,
|
||||
AngleGradient,
|
||||
BorderCorner,
|
||||
BorderEdge,
|
||||
}
|
||||
|
@ -78,6 +76,7 @@ pub enum BrushBatchKind {
|
|||
},
|
||||
YuvImage(ImageBufferKind, YuvFormat, YuvColorSpace),
|
||||
RadialGradient,
|
||||
LinearGradient,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
|
@ -682,6 +681,7 @@ impl AlphaBatchBuilder {
|
|||
ctx.resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
&ctx.cached_gradients,
|
||||
) {
|
||||
self.add_brush_to_batch(
|
||||
brush,
|
||||
|
@ -811,7 +811,7 @@ impl AlphaBatchBuilder {
|
|||
let font_transform = if is_shadow {
|
||||
None
|
||||
} else {
|
||||
Some(&scroll_node.transform)
|
||||
Some(scroll_node.transform)
|
||||
};
|
||||
|
||||
let font = text_cpu.get_font(
|
||||
|
@ -969,6 +969,7 @@ impl AlphaBatchBuilder {
|
|||
is_in_3d_context,
|
||||
reference_frame_id,
|
||||
real_local_rect,
|
||||
ref extra_gpu_data_handle,
|
||||
..
|
||||
} => {
|
||||
// If this picture is participating in a 3D rendering context,
|
||||
|
@ -977,8 +978,10 @@ impl AlphaBatchBuilder {
|
|||
if is_in_3d_context {
|
||||
// Push into parent plane splitter.
|
||||
|
||||
let real_xf = &ctx.clip_scroll_tree.nodes[&reference_frame_id].world_content_transform;
|
||||
|
||||
let real_xf = &ctx.clip_scroll_tree
|
||||
.nodes[&reference_frame_id]
|
||||
.world_content_transform
|
||||
.into();
|
||||
let polygon = make_polygon(
|
||||
real_local_rect,
|
||||
&real_xf,
|
||||
|
@ -1093,18 +1096,20 @@ impl AlphaBatchBuilder {
|
|||
BatchTextures::render_target_cache(),
|
||||
);
|
||||
|
||||
let filter_mode = match filter {
|
||||
FilterOp::Blur(..) => 0,
|
||||
FilterOp::Contrast(..) => 1,
|
||||
FilterOp::Grayscale(..) => 2,
|
||||
FilterOp::HueRotate(..) => 3,
|
||||
FilterOp::Invert(..) => 4,
|
||||
FilterOp::Saturate(..) => 5,
|
||||
FilterOp::Sepia(..) => 6,
|
||||
FilterOp::Brightness(..) => 7,
|
||||
FilterOp::Opacity(..) => 8,
|
||||
FilterOp::DropShadow(..) => 9,
|
||||
FilterOp::ColorMatrix(..) => 10,
|
||||
let (filter_mode, extra_cache_address) = match filter {
|
||||
FilterOp::Blur(..) => (0, 0),
|
||||
FilterOp::Contrast(..) => (1, 0),
|
||||
FilterOp::Grayscale(..) => (2, 0),
|
||||
FilterOp::HueRotate(..) => (3, 0),
|
||||
FilterOp::Invert(..) => (4, 0),
|
||||
FilterOp::Saturate(..) => (5, 0),
|
||||
FilterOp::Sepia(..) => (6, 0),
|
||||
FilterOp::Brightness(..) => (7, 0),
|
||||
FilterOp::Opacity(..) => (8, 0),
|
||||
FilterOp::DropShadow(..) => (9, 0),
|
||||
FilterOp::ColorMatrix(..) => {
|
||||
(10, extra_gpu_data_handle.as_int(gpu_cache))
|
||||
}
|
||||
};
|
||||
|
||||
let instance = BrushInstance {
|
||||
|
@ -1120,7 +1125,7 @@ impl AlphaBatchBuilder {
|
|||
user_data: [
|
||||
cache_task_address.0 as i32,
|
||||
filter_mode,
|
||||
0,
|
||||
extra_cache_address,
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -1206,28 +1211,6 @@ impl AlphaBatchBuilder {
|
|||
}
|
||||
}
|
||||
}
|
||||
PrimitiveKind::AlignedGradient => {
|
||||
let gradient_cpu =
|
||||
&ctx.prim_store.cpu_gradients[prim_metadata.cpu_prim_index.0];
|
||||
let kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::AlignedGradient,
|
||||
);
|
||||
let key = BatchKey::new(kind, non_segmented_blend_mode, no_textures);
|
||||
let batch = self.batch_list.get_suitable_batch(key, &task_relative_bounding_rect);
|
||||
for part_index in 0 .. (gradient_cpu.stops_count - 1) {
|
||||
batch.push(base_instance.build(part_index as i32, 0, 0));
|
||||
}
|
||||
}
|
||||
PrimitiveKind::AngleGradient => {
|
||||
let kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::AngleGradient,
|
||||
);
|
||||
let key = BatchKey::new(kind, non_segmented_blend_mode, no_textures);
|
||||
let batch = self.batch_list.get_suitable_batch(key, &task_relative_bounding_rect);
|
||||
batch.push(base_instance.build(0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1330,6 +1313,7 @@ impl BrushPrimitive {
|
|||
resource_cache: &ResourceCache,
|
||||
gpu_cache: &mut GpuCache,
|
||||
deferred_resolves: &mut Vec<DeferredResolve>,
|
||||
cached_gradients: &[CachedGradient],
|
||||
) -> Option<(BrushBatchKind, BatchTextures, [i32; 3])> {
|
||||
match self.kind {
|
||||
BrushKind::Line { .. } => {
|
||||
|
@ -1376,7 +1360,8 @@ impl BrushPrimitive {
|
|||
[0; 3],
|
||||
))
|
||||
}
|
||||
BrushKind::RadialGradient { ref stops_handle, .. } => {
|
||||
BrushKind::RadialGradient { gradient_index, .. } => {
|
||||
let stops_handle = &cached_gradients[gradient_index.0].handle;
|
||||
Some((
|
||||
BrushBatchKind::RadialGradient,
|
||||
BatchTextures::no_texture(),
|
||||
|
@ -1387,6 +1372,18 @@ impl BrushPrimitive {
|
|||
],
|
||||
))
|
||||
}
|
||||
BrushKind::LinearGradient { gradient_index, .. } => {
|
||||
let stops_handle = &cached_gradients[gradient_index.0].handle;
|
||||
Some((
|
||||
BrushBatchKind::LinearGradient,
|
||||
BatchTextures::no_texture(),
|
||||
[
|
||||
stops_handle.as_int(gpu_cache),
|
||||
0,
|
||||
0,
|
||||
],
|
||||
))
|
||||
}
|
||||
BrushKind::YuvImage { format, yuv_key, image_rendering, color_space } => {
|
||||
let mut textures = BatchTextures::no_texture();
|
||||
let mut uv_rect_addresses = [0; 3];
|
||||
|
@ -1464,8 +1461,6 @@ impl AlphaBatchHelpers for PrimitiveStore {
|
|||
}
|
||||
|
||||
PrimitiveKind::Border |
|
||||
PrimitiveKind::AlignedGradient |
|
||||
PrimitiveKind::AngleGradient |
|
||||
PrimitiveKind::Picture => {
|
||||
BlendMode::PremultipliedAlpha
|
||||
}
|
||||
|
@ -1487,6 +1482,7 @@ impl AlphaBatchHelpers for PrimitiveStore {
|
|||
BrushKind::Line { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } |
|
||||
BrushKind::LinearGradient { .. } |
|
||||
BrushKind::Picture => {
|
||||
BlendMode::PremultipliedAlpha
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelScale, ImageMask};
|
||||
use api::{ImageRendering, LayerRect, LayerToWorldTransform, LayoutPoint, LayoutVector2D};
|
||||
use api::LocalClip;
|
||||
use api::{ImageRendering, LayerRect, LayoutPoint, LayoutVector2D, LocalClip};
|
||||
use border::{BorderCornerClipSource, ensure_no_corner_overlap};
|
||||
use clip_scroll_tree::{ClipChainIndex, CoordinateSystemId};
|
||||
use ellipse::Ellipse;
|
||||
|
@ -13,7 +12,8 @@ use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
|
|||
use gpu_types::ClipScrollNodeIndex;
|
||||
use prim_store::{ClipData, ImageMaskData};
|
||||
use resource_cache::{ImageRequest, ResourceCache};
|
||||
use util::{MaxRect, MatrixHelpers, calculate_screen_bounding_rect, extract_inner_rect_safe};
|
||||
use util::{LayerToWorldFastTransform, MaxRect, calculate_screen_bounding_rect};
|
||||
use util::extract_inner_rect_safe;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub type ClipStore = FreeList<ClipSources>;
|
||||
|
@ -252,7 +252,7 @@ impl ClipSources {
|
|||
|
||||
pub fn get_screen_bounds(
|
||||
&self,
|
||||
transform: &LayerToWorldTransform,
|
||||
transform: &LayerToWorldFastTransform,
|
||||
device_pixel_scale: DevicePixelScale,
|
||||
) -> (DeviceIntRect, Option<DeviceIntRect>) {
|
||||
// If this translation isn't axis aligned or has a perspective component, don't try to
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ClipId, DevicePixelScale, ExternalScrollId, LayerPixel, LayerPoint, LayerRect};
|
||||
use api::{LayerSize, LayerToWorldTransform, LayerTransform, LayerVector2D, LayoutTransform};
|
||||
use api::{LayoutVector2D, PipelineId, PropertyBinding, ScrollClamping, ScrollEventPhase};
|
||||
use api::{ScrollLocation, ScrollSensitivity, StickyOffsetBounds, WorldPoint};
|
||||
use api::{LayerSize, LayerVector2D, LayoutTransform, LayoutVector2D, PipelineId, PropertyBinding};
|
||||
use api::{ScrollClamping, ScrollEventPhase, ScrollLocation, ScrollSensitivity, StickyOffsetBounds};
|
||||
use api::WorldPoint;
|
||||
use clip::{ClipChain, ClipSourcesHandle, ClipStore, ClipWorkItem};
|
||||
use clip_scroll_tree::{ClipChainIndex, CoordinateSystemId, TransformUpdateState};
|
||||
use euclid::SideOffsets2D;
|
||||
|
@ -15,7 +15,8 @@ use gpu_types::{ClipScrollNodeIndex, ClipScrollNodeData};
|
|||
use resource_cache::ResourceCache;
|
||||
use scene::SceneProperties;
|
||||
use spring::{DAMPING, STIFFNESS, Spring};
|
||||
use util::{MatrixHelpers, TransformOrOffset, TransformedRectKind};
|
||||
use util::{LayerToWorldFastTransform, LayerFastTransform, LayoutFastTransform};
|
||||
use util::{TransformedRectKind};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const CAN_OVERSCROLL: bool = true;
|
||||
|
@ -91,10 +92,10 @@ pub struct ClipScrollNode {
|
|||
/// between our reference frame and this node. For reference frames, we also include
|
||||
/// whatever local transformation this reference frame provides. This can be combined
|
||||
/// with the local_viewport_rect to get its position in world space.
|
||||
pub world_viewport_transform: LayerToWorldTransform,
|
||||
pub world_viewport_transform: LayerToWorldFastTransform,
|
||||
|
||||
/// World transform for content transformed by this node.
|
||||
pub world_content_transform: LayerToWorldTransform,
|
||||
pub world_content_transform: LayerToWorldFastTransform,
|
||||
|
||||
/// Pipeline that this layer belongs to
|
||||
pub pipeline_id: PipelineId,
|
||||
|
@ -119,7 +120,7 @@ pub struct ClipScrollNode {
|
|||
/// The transformation from the coordinate system which established our compatible coordinate
|
||||
/// system (same coordinate system id) and us. This can change via scroll offsets and via new
|
||||
/// reference frame transforms.
|
||||
pub coordinate_system_relative_transform: TransformOrOffset,
|
||||
pub coordinate_system_relative_transform: LayerFastTransform,
|
||||
|
||||
/// A linear ID / index of this clip-scroll node. Used as a reference to
|
||||
/// pass to shaders, to allow them to fetch a given clip-scroll node.
|
||||
|
@ -135,15 +136,15 @@ impl ClipScrollNode {
|
|||
) -> Self {
|
||||
ClipScrollNode {
|
||||
local_viewport_rect: *rect,
|
||||
world_viewport_transform: LayerToWorldTransform::identity(),
|
||||
world_content_transform: LayerToWorldTransform::identity(),
|
||||
world_viewport_transform: LayerToWorldFastTransform::identity(),
|
||||
world_content_transform: LayerToWorldFastTransform::identity(),
|
||||
parent: parent_id,
|
||||
children: Vec::new(),
|
||||
pipeline_id,
|
||||
node_type: node_type,
|
||||
invertible: true,
|
||||
coordinate_system_id: CoordinateSystemId(0),
|
||||
coordinate_system_relative_transform: TransformOrOffset::zero(),
|
||||
coordinate_system_relative_transform: LayerFastTransform::identity(),
|
||||
node_data_index: ClipScrollNodeIndex(0),
|
||||
}
|
||||
}
|
||||
|
@ -177,10 +178,12 @@ impl ClipScrollNode {
|
|||
pipeline_id: PipelineId,
|
||||
) -> Self {
|
||||
let identity = LayoutTransform::identity();
|
||||
let source_perspective = source_perspective.map_or_else(
|
||||
LayoutFastTransform::identity, |perspective| perspective.into());
|
||||
let info = ReferenceFrameInfo {
|
||||
resolved_transform: LayerTransform::identity(),
|
||||
resolved_transform: LayerFastTransform::identity(),
|
||||
source_transform: source_transform.unwrap_or(PropertyBinding::Value(identity)),
|
||||
source_perspective: source_perspective.unwrap_or(identity),
|
||||
source_perspective: source_perspective,
|
||||
origin_in_parent_reference_frame,
|
||||
invertible: true,
|
||||
};
|
||||
|
@ -258,8 +261,8 @@ impl ClipScrollNode {
|
|||
|
||||
pub fn mark_uninvertible(&mut self) {
|
||||
self.invertible = false;
|
||||
self.world_content_transform = LayerToWorldTransform::identity();
|
||||
self.world_viewport_transform = LayerToWorldTransform::identity();
|
||||
self.world_content_transform = LayerToWorldFastTransform::identity();
|
||||
self.world_viewport_transform = LayerToWorldFastTransform::identity();
|
||||
}
|
||||
|
||||
pub fn push_gpu_node_data(&mut self, node_data: &mut Vec<ClipScrollNodeData>) {
|
||||
|
@ -274,7 +277,7 @@ impl ClipScrollNode {
|
|||
TransformedRectKind::Complex
|
||||
};
|
||||
let data = ClipScrollNodeData {
|
||||
transform: self.world_content_transform,
|
||||
transform: self.world_content_transform.into(),
|
||||
transform_kind: transform_kind as u32 as f32,
|
||||
padding: [0.0; 3],
|
||||
};
|
||||
|
@ -303,9 +306,9 @@ impl ClipScrollNode {
|
|||
|
||||
self.update_transform(state, next_coordinate_system_id, scene_properties);
|
||||
|
||||
// If this node is a reference frame, we check if the determinant is 0, which means it
|
||||
// has a non-invertible matrix. For non-reference-frames we assume that they will
|
||||
// produce only additional translations which should be invertible.
|
||||
// If this node is a reference frame, we check if it has a non-invertible matrix.
|
||||
// For non-reference-frames we assume that they will produce only additional
|
||||
// translations which should be invertible.
|
||||
match self.node_type {
|
||||
NodeType::ReferenceFrame(info) if !info.invertible => {
|
||||
self.mark_uninvertible();
|
||||
|
@ -362,7 +365,7 @@ impl ClipScrollNode {
|
|||
|
||||
let mut clip_chain = clip_chains[state.parent_clip_chain_index.0].new_with_added_node(
|
||||
work_item,
|
||||
self.coordinate_system_relative_transform.apply(&local_outer_rect),
|
||||
self.coordinate_system_relative_transform.transform_rect(&local_outer_rect),
|
||||
screen_outer_rect,
|
||||
screen_inner_rect,
|
||||
);
|
||||
|
@ -398,7 +401,7 @@ impl ClipScrollNode {
|
|||
// provided by our own sticky positioning.
|
||||
let accumulated_offset = state.parent_accumulated_scroll_offset + sticky_offset;
|
||||
self.world_viewport_transform = if accumulated_offset != LayerVector2D::zero() {
|
||||
state.parent_reference_frame_transform.pre_translate(accumulated_offset.to_3d())
|
||||
state.parent_reference_frame_transform.pre_translate(&accumulated_offset)
|
||||
} else {
|
||||
state.parent_reference_frame_transform
|
||||
};
|
||||
|
@ -407,7 +410,7 @@ impl ClipScrollNode {
|
|||
// whatever scrolling offset we supply as well.
|
||||
let scroll_offset = self.scroll_offset();
|
||||
self.world_content_transform = if scroll_offset != LayerVector2D::zero() {
|
||||
self.world_viewport_transform.pre_translate(scroll_offset.to_3d())
|
||||
self.world_viewport_transform.pre_translate(&scroll_offset)
|
||||
} else {
|
||||
self.world_viewport_transform
|
||||
};
|
||||
|
@ -437,12 +440,10 @@ impl ClipScrollNode {
|
|||
|
||||
// Resolve the transform against any property bindings.
|
||||
let source_transform = scene_properties.resolve_layout_transform(&info.source_transform);
|
||||
info.resolved_transform = LayerTransform::create_translation(
|
||||
info.origin_in_parent_reference_frame.x,
|
||||
info.origin_in_parent_reference_frame.y,
|
||||
0.0
|
||||
).pre_mul(&source_transform)
|
||||
.pre_mul(&info.source_perspective);
|
||||
info.resolved_transform =
|
||||
LayerFastTransform::with_vector(info.origin_in_parent_reference_frame)
|
||||
.pre_mul(&source_transform.into())
|
||||
.pre_mul(&info.source_perspective);
|
||||
|
||||
// The transformation for this viewport in world coordinates is the transformation for
|
||||
// our parent reference frame, plus any accumulated scrolling offsets from nodes
|
||||
|
@ -450,12 +451,14 @@ impl ClipScrollNode {
|
|||
// whatever local transformation this reference frame provides. This can be combined
|
||||
// with the local_viewport_rect to get its position in world space.
|
||||
let relative_transform = info.resolved_transform
|
||||
.post_translate(state.parent_accumulated_scroll_offset.to_3d());
|
||||
self.world_viewport_transform = state.parent_reference_frame_transform
|
||||
.pre_mul(&relative_transform.with_destination::<LayerPixel>());
|
||||
.post_translate(state.parent_accumulated_scroll_offset)
|
||||
.to_transform()
|
||||
.with_destination::<LayerPixel>();
|
||||
self.world_viewport_transform =
|
||||
state.parent_reference_frame_transform.pre_mul(&relative_transform.into());
|
||||
self.world_content_transform = self.world_viewport_transform;
|
||||
|
||||
info.invertible = relative_transform.determinant() != 0.0;
|
||||
info.invertible = self.world_viewport_transform.is_invertible();
|
||||
if !info.invertible {
|
||||
return;
|
||||
}
|
||||
|
@ -465,7 +468,7 @@ impl ClipScrollNode {
|
|||
match state.coordinate_system_relative_transform.update(relative_transform) {
|
||||
Some(offset) => self.coordinate_system_relative_transform = offset,
|
||||
None => {
|
||||
self.coordinate_system_relative_transform = TransformOrOffset::zero();
|
||||
self.coordinate_system_relative_transform = LayerFastTransform::identity();
|
||||
state.current_coordinate_system_id = *next_coordinate_system_id;
|
||||
next_coordinate_system_id.advance();
|
||||
}
|
||||
|
@ -844,14 +847,14 @@ impl ScrollFrameInfo {
|
|||
pub struct ReferenceFrameInfo {
|
||||
/// The transformation that establishes this reference frame, relative to the parent
|
||||
/// reference frame. The origin of the reference frame is included in the transformation.
|
||||
pub resolved_transform: LayerTransform,
|
||||
pub resolved_transform: LayerFastTransform,
|
||||
|
||||
/// The source transform and perspective matrices provided by the stacking context
|
||||
/// that forms this reference frame. We maintain the property binding information
|
||||
/// here so that we can resolve the animated transform and update the tree each
|
||||
/// frame.
|
||||
pub source_transform: PropertyBinding<LayoutTransform>,
|
||||
pub source_perspective: LayoutTransform,
|
||||
pub source_perspective: LayoutFastTransform,
|
||||
|
||||
/// The original, not including the transform and relative to the parent reference frame,
|
||||
/// origin of this reference frame. This is already rolled into the `transform' property, but
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ClipId, DeviceIntRect, DevicePixelScale, ExternalScrollId, LayerPoint, LayerRect};
|
||||
use api::{LayerToWorldTransform, LayerVector2D, PipelineId, ScrollClamping, ScrollEventPhase};
|
||||
use api::{ScrollLocation, ScrollNodeState, WorldPoint};
|
||||
use api::{LayerVector2D, PipelineId, ScrollClamping, ScrollEventPhase, ScrollLocation};
|
||||
use api::{ScrollNodeState, WorldPoint};
|
||||
use clip::{ClipChain, ClipSourcesHandle, ClipStore};
|
||||
use clip_scroll_node::{ClipScrollNode, NodeType, ScrollFrameInfo, StickyFrameInfo};
|
||||
use gpu_cache::GpuCache;
|
||||
|
@ -13,7 +13,7 @@ use internal_types::{FastHashMap, FastHashSet};
|
|||
use print_tree::{PrintTree, PrintTreePrinter};
|
||||
use resource_cache::ResourceCache;
|
||||
use scene::SceneProperties;
|
||||
use util::TransformOrOffset;
|
||||
use util::{LayerFastTransform, LayerToWorldFastTransform};
|
||||
|
||||
pub type ScrollStates = FastHashMap<ExternalScrollId, ScrollFrameInfo>;
|
||||
|
||||
|
@ -88,7 +88,7 @@ pub struct ClipScrollTree {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct TransformUpdateState {
|
||||
pub parent_reference_frame_transform: LayerToWorldTransform,
|
||||
pub parent_reference_frame_transform: LayerToWorldFastTransform,
|
||||
pub parent_accumulated_scroll_offset: LayerVector2D,
|
||||
pub nearest_scrolling_ancestor_offset: LayerVector2D,
|
||||
pub nearest_scrolling_ancestor_viewport: LayerRect,
|
||||
|
@ -103,7 +103,7 @@ pub struct TransformUpdateState {
|
|||
pub current_coordinate_system_id: CoordinateSystemId,
|
||||
|
||||
/// Transform from the coordinate system that started this compatible coordinate system.
|
||||
pub coordinate_system_relative_transform: TransformOrOffset,
|
||||
pub coordinate_system_relative_transform: LayerFastTransform,
|
||||
|
||||
/// True if this node is transformed by an invertible transform. If not, display items
|
||||
/// transformed by this node will not be displayed and display items not transformed by this
|
||||
|
@ -329,17 +329,13 @@ impl ClipScrollTree {
|
|||
|
||||
let root_reference_frame_id = self.root_reference_frame_id();
|
||||
let mut state = TransformUpdateState {
|
||||
parent_reference_frame_transform: LayerToWorldTransform::create_translation(
|
||||
pan.x,
|
||||
pan.y,
|
||||
0.0,
|
||||
),
|
||||
parent_reference_frame_transform: LayerVector2D::new(pan.x, pan.y).into(),
|
||||
parent_accumulated_scroll_offset: LayerVector2D::zero(),
|
||||
nearest_scrolling_ancestor_offset: LayerVector2D::zero(),
|
||||
nearest_scrolling_ancestor_viewport: LayerRect::zero(),
|
||||
parent_clip_chain_index: ClipChainIndex(0),
|
||||
current_coordinate_system_id: CoordinateSystemId::root(),
|
||||
coordinate_system_relative_transform: TransformOrOffset::zero(),
|
||||
coordinate_system_relative_transform: LayerFastTransform::identity(),
|
||||
invertible: true,
|
||||
};
|
||||
let mut next_coordinate_system_id = state.current_coordinate_system_id.next();
|
||||
|
|
|
@ -6,11 +6,10 @@ use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayList, ClipId,
|
|||
use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixelScale, DeviceUintPoint};
|
||||
use api::{DeviceUintRect, DeviceUintSize, DocumentLayer, Epoch, ExtendMode, ExternalScrollId};
|
||||
use api::{FontRenderMode, GlyphInstance, GlyphOptions, GradientStop, ImageKey, ImageRendering};
|
||||
use api::{ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerTransform};
|
||||
use api::{LayerVector2D, LayoutTransform, LayoutVector2D, LineOrientation, LineStyle, LocalClip};
|
||||
use api::{PipelineId, PremultipliedColorF, PropertyBinding, RepeatMode, ScrollSensitivity, Shadow};
|
||||
use api::{TexelRect, TileOffset, TransformStyle, WorldPoint, WorldToLayerTransform, YuvColorSpace};
|
||||
use api::YuvData;
|
||||
use api::{ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerVector2D};
|
||||
use api::{LayoutTransform, LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId};
|
||||
use api::{PremultipliedColorF, PropertyBinding, RepeatMode, ScrollSensitivity, Shadow, TexelRect};
|
||||
use api::{TileOffset, TransformStyle, WorldPoint, YuvColorSpace, YuvData};
|
||||
use app_units::Au;
|
||||
use border::ImageBorderSegment;
|
||||
use clip::{ClipChain, ClipRegion, ClipSource, ClipSources, ClipStore};
|
||||
|
@ -19,12 +18,12 @@ use clip_scroll_tree::{ClipScrollTree, ClipChainIndex};
|
|||
use euclid::{SideOffsets2D, vec2};
|
||||
use frame::{FrameId, ClipIdToIndexMapper};
|
||||
use glyph_rasterizer::FontInstance;
|
||||
use gpu_cache::{GpuCache, GpuCacheHandle};
|
||||
use gpu_cache::GpuCache;
|
||||
use gpu_types::{ClipChainRectIndex, ClipScrollNodeData, PictureType};
|
||||
use hit_test::{HitTester, HitTestingItem, HitTestingRun};
|
||||
use internal_types::{FastHashMap, FastHashSet};
|
||||
use picture::{ContentOrigin, PictureCompositeMode, PictureKind, PicturePrimitive, PictureSurface};
|
||||
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor, GradientPrimitiveCpu};
|
||||
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentDescriptor, CachedGradient, CachedGradientIndex};
|
||||
use prim_store::{ImageCacheKey, ImagePrimitiveCpu, ImageSource, PrimitiveContainer};
|
||||
use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveRun, PrimitiveStore};
|
||||
use prim_store::{ScrollNodeAndClipChain, TextRunPrimitiveCpu};
|
||||
|
@ -35,7 +34,7 @@ use scene::{ScenePipeline, SceneProperties};
|
|||
use std::{mem, usize, f32};
|
||||
use tiling::{CompositeOps, Frame, RenderPass, RenderTargetKind};
|
||||
use tiling::{RenderPassKind, RenderTargetContext, ScrollbarPrimitive};
|
||||
use util::{self, MaxRect, pack_as_float, RectHelpers, recycle_vec};
|
||||
use util::{self, MaxRect, RectHelpers, WorldToLayerFastTransform, recycle_vec};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ScrollbarInfo(pub ClipId, pub LayerRect);
|
||||
|
@ -86,6 +85,7 @@ pub struct FrameBuilder {
|
|||
pub clip_store: ClipStore,
|
||||
hit_testing_runs: Vec<HitTestingRun>,
|
||||
pub config: FrameBuilderConfig,
|
||||
pub cached_gradients: Vec<CachedGradient>,
|
||||
|
||||
// A stack of the current shadow primitives.
|
||||
// The sub-Vec stores a buffer of fast-path primitives to be appended on pop.
|
||||
|
@ -124,6 +124,7 @@ pub struct FrameState<'a> {
|
|||
pub local_clip_rects: &'a mut Vec<LayerRect>,
|
||||
pub resource_cache: &'a mut ResourceCache,
|
||||
pub gpu_cache: &'a mut GpuCache,
|
||||
pub cached_gradients: &'a mut [CachedGradient],
|
||||
}
|
||||
|
||||
pub struct PictureContext<'a> {
|
||||
|
@ -133,7 +134,7 @@ pub struct PictureContext<'a> {
|
|||
pub original_reference_frame_id: Option<ClipId>,
|
||||
pub display_list: &'a BuiltDisplayList,
|
||||
pub draw_text_transformed: bool,
|
||||
pub inv_world_transform: Option<WorldToLayerTransform>,
|
||||
pub inv_world_transform: Option<WorldToLayerFastTransform>,
|
||||
}
|
||||
|
||||
pub struct PictureState {
|
||||
|
@ -173,6 +174,7 @@ impl FrameBuilder {
|
|||
FrameBuilder {
|
||||
hit_testing_runs: Vec::new(),
|
||||
shadow_prim_stack: Vec::new(),
|
||||
cached_gradients: Vec::new(),
|
||||
pending_shadow_contents: Vec::new(),
|
||||
scrollbar_prims: Vec::new(),
|
||||
reference_frame_stack: Vec::new(),
|
||||
|
@ -201,6 +203,7 @@ impl FrameBuilder {
|
|||
FrameBuilder {
|
||||
hit_testing_runs: recycle_vec(self.hit_testing_runs),
|
||||
shadow_prim_stack: recycle_vec(self.shadow_prim_stack),
|
||||
cached_gradients: recycle_vec(self.cached_gradients),
|
||||
pending_shadow_contents: recycle_vec(self.pending_shadow_contents),
|
||||
scrollbar_prims: recycle_vec(self.scrollbar_prims),
|
||||
reference_frame_stack: recycle_vec(self.reference_frame_stack),
|
||||
|
@ -673,11 +676,8 @@ impl FrameBuilder {
|
|||
let root_id = clip_scroll_tree.root_reference_frame_id();
|
||||
if let Some(root_node) = clip_scroll_tree.nodes.get_mut(&root_id) {
|
||||
if let NodeType::ReferenceFrame(ref mut info) = root_node.node_type {
|
||||
info.resolved_transform = LayerTransform::create_translation(
|
||||
viewport_offset.x,
|
||||
viewport_offset.y,
|
||||
0.0,
|
||||
);
|
||||
info.resolved_transform =
|
||||
LayerVector2D::new(viewport_offset.x, viewport_offset.y).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1236,6 +1236,53 @@ impl FrameBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_gradient_impl(
|
||||
&mut self,
|
||||
clip_and_scroll: ScrollNodeAndClipChain,
|
||||
info: &LayerPrimitiveInfo,
|
||||
start_point: LayerPoint,
|
||||
end_point: LayerPoint,
|
||||
stops: ItemRange<GradientStop>,
|
||||
stops_count: usize,
|
||||
extend_mode: ExtendMode,
|
||||
gradient_index: CachedGradientIndex,
|
||||
) {
|
||||
// Try to ensure that if the gradient is specified in reverse, then so long as the stops
|
||||
// are also supplied in reverse that the rendered result will be equivalent. To do this,
|
||||
// a reference orientation for the gradient line must be chosen, somewhat arbitrarily, so
|
||||
// just designate the reference orientation as start < end. Aligned gradient rendering
|
||||
// manages to produce the same result regardless of orientation, so don't worry about
|
||||
// reversing in that case.
|
||||
let reverse_stops = start_point.x > end_point.x ||
|
||||
(start_point.x == end_point.x && start_point.y > end_point.y);
|
||||
|
||||
// To get reftests exactly matching with reverse start/end
|
||||
// points, it's necessary to reverse the gradient
|
||||
// line in some cases.
|
||||
let (sp, ep) = if reverse_stops {
|
||||
(end_point, start_point)
|
||||
} else {
|
||||
(start_point, end_point)
|
||||
};
|
||||
|
||||
let prim = BrushPrimitive::new(
|
||||
BrushKind::LinearGradient {
|
||||
stops_range: stops,
|
||||
stops_count,
|
||||
extend_mode,
|
||||
reverse_stops,
|
||||
start_point: sp,
|
||||
end_point: ep,
|
||||
gradient_index,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
||||
let prim = PrimitiveContainer::Brush(prim);
|
||||
|
||||
self.add_primitive(clip_and_scroll, info, Vec::new(), prim);
|
||||
}
|
||||
|
||||
pub fn add_gradient(
|
||||
&mut self,
|
||||
clip_and_scroll: ScrollNodeAndClipChain,
|
||||
|
@ -1248,62 +1295,40 @@ impl FrameBuilder {
|
|||
tile_size: LayerSize,
|
||||
tile_spacing: LayerSize,
|
||||
) {
|
||||
let tile_repeat = tile_size + tile_spacing;
|
||||
let is_not_tiled = tile_repeat.width >= info.rect.size.width &&
|
||||
tile_repeat.height >= info.rect.size.height;
|
||||
let gradient_index = CachedGradientIndex(self.cached_gradients.len());
|
||||
self.cached_gradients.push(CachedGradient::new());
|
||||
|
||||
let aligned_and_fills_rect = (start_point.x == end_point.x &&
|
||||
start_point.y.min(end_point.y) <= 0.0 &&
|
||||
start_point.y.max(end_point.y) >= info.rect.size.height) ||
|
||||
(start_point.y == end_point.y && start_point.x.min(end_point.x) <= 0.0 &&
|
||||
start_point.x.max(end_point.x) >= info.rect.size.width);
|
||||
let prim_infos = info.decompose(
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
64 * 64,
|
||||
);
|
||||
|
||||
// Fast path for clamped, axis-aligned gradients, with gradient lines intersecting all of rect:
|
||||
let aligned = extend_mode == ExtendMode::Clamp && is_not_tiled && aligned_and_fills_rect;
|
||||
|
||||
// Try to ensure that if the gradient is specified in reverse, then so long as the stops
|
||||
// are also supplied in reverse that the rendered result will be equivalent. To do this,
|
||||
// a reference orientation for the gradient line must be chosen, somewhat arbitrarily, so
|
||||
// just designate the reference orientation as start < end. Aligned gradient rendering
|
||||
// manages to produce the same result regardless of orientation, so don't worry about
|
||||
// reversing in that case.
|
||||
let reverse_stops = !aligned &&
|
||||
(start_point.x > end_point.x ||
|
||||
(start_point.x == end_point.x && start_point.y > end_point.y));
|
||||
|
||||
// To get reftests exactly matching with reverse start/end
|
||||
// points, it's necessary to reverse the gradient
|
||||
// line in some cases.
|
||||
let (sp, ep) = if reverse_stops {
|
||||
(end_point, start_point)
|
||||
if prim_infos.is_empty() {
|
||||
self.add_gradient_impl(
|
||||
clip_and_scroll,
|
||||
info,
|
||||
start_point,
|
||||
end_point,
|
||||
stops,
|
||||
stops_count,
|
||||
extend_mode,
|
||||
gradient_index,
|
||||
);
|
||||
} else {
|
||||
(start_point, end_point)
|
||||
};
|
||||
|
||||
let gradient_cpu = GradientPrimitiveCpu {
|
||||
stops_range: stops,
|
||||
stops_count,
|
||||
extend_mode,
|
||||
reverse_stops,
|
||||
gpu_blocks: [
|
||||
[sp.x, sp.y, ep.x, ep.y].into(),
|
||||
[
|
||||
tile_size.width,
|
||||
tile_size.height,
|
||||
tile_repeat.width,
|
||||
tile_repeat.height,
|
||||
].into(),
|
||||
[pack_as_float(extend_mode as u32), 0.0, 0.0, 0.0].into(),
|
||||
],
|
||||
};
|
||||
|
||||
let prim = if aligned {
|
||||
PrimitiveContainer::AlignedGradient(gradient_cpu)
|
||||
} else {
|
||||
PrimitiveContainer::AngleGradient(gradient_cpu)
|
||||
};
|
||||
|
||||
self.add_primitive(clip_and_scroll, info, Vec::new(), prim);
|
||||
for prim_info in prim_infos {
|
||||
self.add_gradient_impl(
|
||||
clip_and_scroll,
|
||||
&prim_info,
|
||||
start_point,
|
||||
end_point,
|
||||
stops,
|
||||
stops_count,
|
||||
extend_mode,
|
||||
gradient_index,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_radial_gradient_impl(
|
||||
|
@ -1317,17 +1342,18 @@ impl FrameBuilder {
|
|||
ratio_xy: f32,
|
||||
stops: ItemRange<GradientStop>,
|
||||
extend_mode: ExtendMode,
|
||||
gradient_index: CachedGradientIndex,
|
||||
) {
|
||||
let prim = BrushPrimitive::new(
|
||||
BrushKind::RadialGradient {
|
||||
stops_range: stops,
|
||||
extend_mode,
|
||||
stops_handle: GpuCacheHandle::new(),
|
||||
start_center,
|
||||
end_center,
|
||||
start_radius,
|
||||
end_radius,
|
||||
ratio_xy,
|
||||
gradient_index,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
@ -1354,6 +1380,9 @@ impl FrameBuilder {
|
|||
tile_size: LayerSize,
|
||||
tile_spacing: LayerSize,
|
||||
) {
|
||||
let gradient_index = CachedGradientIndex(self.cached_gradients.len());
|
||||
self.cached_gradients.push(CachedGradient::new());
|
||||
|
||||
let prim_infos = info.decompose(
|
||||
tile_size,
|
||||
tile_spacing,
|
||||
|
@ -1371,6 +1400,7 @@ impl FrameBuilder {
|
|||
ratio_xy,
|
||||
stops,
|
||||
extend_mode,
|
||||
gradient_index,
|
||||
);
|
||||
} else {
|
||||
for prim_info in prim_infos {
|
||||
|
@ -1384,6 +1414,7 @@ impl FrameBuilder {
|
|||
ratio_xy,
|
||||
stops,
|
||||
extend_mode,
|
||||
gradient_index,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1703,6 +1734,7 @@ impl FrameBuilder {
|
|||
local_clip_rects,
|
||||
resource_cache,
|
||||
gpu_cache,
|
||||
cached_gradients: &mut self.cached_gradients,
|
||||
};
|
||||
|
||||
let pic_context = PictureContext {
|
||||
|
@ -1871,6 +1903,7 @@ impl FrameBuilder {
|
|||
clip_scroll_tree,
|
||||
use_dual_source_blending,
|
||||
node_data: &node_data,
|
||||
cached_gradients: &self.cached_gradients,
|
||||
};
|
||||
|
||||
pass.build(
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{BorderRadius, ClipId, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag};
|
||||
use api::{LayerPoint, LayerPrimitiveInfo, LayerRect, LayerToWorldTransform, LocalClip, PipelineId};
|
||||
use api::WorldPoint;
|
||||
use api::{LayerPoint, LayerPrimitiveInfo, LayerRect, LocalClip, PipelineId, WorldPoint};
|
||||
use clip::{ClipSource, ClipStore, Contains, rounded_rectangle_contains_point};
|
||||
use clip_scroll_node::{ClipScrollNode, NodeType};
|
||||
use clip_scroll_tree::{ClipChainIndex, ClipScrollTree};
|
||||
use internal_types::FastHashMap;
|
||||
use prim_store::ScrollNodeAndClipChain;
|
||||
use util::LayerToWorldFastTransform;
|
||||
|
||||
/// A copy of important clip scroll node data to use during hit testing. This a copy of
|
||||
/// data from the ClipScrollTree that will persist as a new frame is under construction,
|
||||
|
@ -20,10 +20,10 @@ pub struct HitTestClipScrollNode {
|
|||
regions: Vec<HitTestRegion>,
|
||||
|
||||
/// World transform for content transformed by this node.
|
||||
world_content_transform: LayerToWorldTransform,
|
||||
world_content_transform: LayerToWorldFastTransform,
|
||||
|
||||
/// World viewport transform for content transformed by this node.
|
||||
world_viewport_transform: LayerToWorldTransform,
|
||||
world_viewport_transform: LayerToWorldFastTransform,
|
||||
|
||||
/// Origin of the viewport of the node, used to calculate node-relative positions.
|
||||
node_origin: LayerPoint,
|
||||
|
|
|
@ -7,7 +7,7 @@ use api::{LayerRect, LayerToWorldScale, LayerVector2D, MixBlendMode, PipelineId}
|
|||
use api::{PremultipliedColorF, Shadow};
|
||||
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowCacheKey};
|
||||
use frame_builder::{FrameContext, FrameState, PictureState};
|
||||
use gpu_cache::GpuDataRequest;
|
||||
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
|
||||
use gpu_types::{BrushImageKind, PictureType};
|
||||
use prim_store::{BrushKind, BrushPrimitive, PrimitiveIndex, PrimitiveRun, PrimitiveRunLocalRect};
|
||||
use prim_store::ScrollNodeAndClipChain;
|
||||
|
@ -88,6 +88,10 @@ pub enum PictureKind {
|
|||
// rendering context.
|
||||
reference_frame_id: ClipId,
|
||||
real_local_rect: LayerRect,
|
||||
// An optional cache handle for storing extra data
|
||||
// in the GPU cache, depending on the type of
|
||||
// picture.
|
||||
extra_gpu_data_handle: GpuCacheHandle,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -217,6 +221,7 @@ impl PicturePrimitive {
|
|||
frame_output_pipeline_id,
|
||||
reference_frame_id,
|
||||
real_local_rect: LayerRect::zero(),
|
||||
extra_gpu_data_handle: GpuCacheHandle::new(),
|
||||
},
|
||||
pipeline_id,
|
||||
cull_children: true,
|
||||
|
@ -333,6 +338,7 @@ impl PicturePrimitive {
|
|||
match self.kind {
|
||||
PictureKind::Image {
|
||||
ref mut secondary_render_task_id,
|
||||
ref mut extra_gpu_data_handle,
|
||||
composite_mode,
|
||||
..
|
||||
} => {
|
||||
|
@ -429,6 +435,15 @@ impl PicturePrimitive {
|
|||
pic_state.tasks.extend(pic_state_for_children.tasks);
|
||||
self.surface = None;
|
||||
} else {
|
||||
|
||||
if let FilterOp::ColorMatrix(m) = filter {
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(extra_gpu_data_handle) {
|
||||
for i in 0..5 {
|
||||
request.push([m[i*4], m[i*4+1], m[i*4+2], m[i*4+3]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let picture_task = RenderTask::new_picture(
|
||||
RenderTaskLocation::Dynamic(None, prim_screen_rect.size),
|
||||
prim_index,
|
||||
|
@ -594,17 +609,10 @@ impl PicturePrimitive {
|
|||
// making this more efficient for the common case.
|
||||
match self.kind {
|
||||
PictureKind::TextShadow { .. } => {
|
||||
for _ in 0 .. 5 {
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
PictureKind::Image { composite_mode, .. } => {
|
||||
match composite_mode {
|
||||
Some(PictureCompositeMode::Filter(FilterOp::ColorMatrix(m))) => {
|
||||
for i in 0..5 {
|
||||
request.push([m[i*4], m[i*4+1], m[i*4+2], m[i*4+3]]);
|
||||
}
|
||||
}
|
||||
Some(PictureCompositeMode::Filter(filter)) => {
|
||||
let amount = match filter {
|
||||
FilterOp::Contrast(amount) => amount,
|
||||
|
@ -623,23 +631,14 @@ impl PicturePrimitive {
|
|||
};
|
||||
|
||||
request.push([amount, 1.0 - amount, 0.0, 0.0]);
|
||||
|
||||
for _ in 0 .. 4 {
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
for _ in 0 .. 5 {
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
PictureKind::BoxShadow { color, .. } => {
|
||||
request.push(color.premultiplied());
|
||||
for _ in 0 .. 4 {
|
||||
request.push([0.0; 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use api::{AlphaType, BorderRadius, BuiltDisplayList, ClipId, ClipMode, ColorF, C
|
|||
use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch, ExtendMode, FontRenderMode};
|
||||
use api::{GlyphInstance, GlyphKey, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag};
|
||||
use api::{LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D, LineOrientation};
|
||||
use api::{LineStyle, PremultipliedColorF, WorldToLayerTransform, YuvColorSpace, YuvFormat};
|
||||
use api::{LineStyle, PremultipliedColorF, YuvColorSpace, YuvFormat};
|
||||
use border::{BorderCornerInstance, BorderEdgeKind};
|
||||
use clip_scroll_tree::{ClipChainIndex, CoordinateSystemId};
|
||||
use clip_scroll_node::ClipScrollNode;
|
||||
|
@ -25,11 +25,11 @@ use resource_cache::{CacheItem, ImageProperties, ImageRequest, ResourceCache};
|
|||
use segment::SegmentBuilder;
|
||||
use std::{mem, usize};
|
||||
use std::rc::Rc;
|
||||
use util::{MatrixHelpers, calculate_screen_bounding_rect, pack_as_float};
|
||||
use util::recycle_vec;
|
||||
use util::{MatrixHelpers, WorldToLayerFastTransform, calculate_screen_bounding_rect};
|
||||
use util::{pack_as_float, recycle_vec};
|
||||
|
||||
|
||||
const MIN_BRUSH_SPLIT_AREA: f32 = 128.0 * 128.0;
|
||||
const MIN_BRUSH_SPLIT_AREA: f32 = 256.0 * 256.0;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct ScrollNodeAndClipChain {
|
||||
|
@ -69,9 +69,20 @@ impl PrimitiveOpacity {
|
|||
is_opaque: alpha == 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn accumulate(&mut self, alpha: f32) {
|
||||
self.is_opaque = self.is_opaque && alpha == 1.0;
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct CachedGradientIndex(pub usize);
|
||||
|
||||
pub struct CachedGradient {
|
||||
pub handle: GpuCacheHandle,
|
||||
}
|
||||
|
||||
impl CachedGradient {
|
||||
pub fn new() -> CachedGradient {
|
||||
CachedGradient {
|
||||
handle: GpuCacheHandle::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,8 +135,6 @@ pub enum PrimitiveKind {
|
|||
TextRun,
|
||||
Image,
|
||||
Border,
|
||||
AlignedGradient,
|
||||
AngleGradient,
|
||||
Picture,
|
||||
Brush,
|
||||
}
|
||||
|
@ -211,14 +220,23 @@ pub enum BrushKind {
|
|||
image_rendering: ImageRendering,
|
||||
},
|
||||
RadialGradient {
|
||||
gradient_index: CachedGradientIndex,
|
||||
stops_range: ItemRange<GradientStop>,
|
||||
extend_mode: ExtendMode,
|
||||
stops_handle: GpuCacheHandle,
|
||||
start_center: LayerPoint,
|
||||
end_center: LayerPoint,
|
||||
start_radius: f32,
|
||||
end_radius: f32,
|
||||
ratio_xy: f32,
|
||||
},
|
||||
LinearGradient {
|
||||
gradient_index: CachedGradientIndex,
|
||||
stops_range: ItemRange<GradientStop>,
|
||||
stops_count: usize,
|
||||
extend_mode: ExtendMode,
|
||||
reverse_stops: bool,
|
||||
start_point: LayerPoint,
|
||||
end_point: LayerPoint,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +247,8 @@ impl BrushKind {
|
|||
BrushKind::Picture |
|
||||
BrushKind::Image { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } => true,
|
||||
BrushKind::RadialGradient { .. } |
|
||||
BrushKind::LinearGradient { .. } => true,
|
||||
|
||||
BrushKind::Mask { .. } |
|
||||
BrushKind::Clear |
|
||||
|
@ -359,6 +378,20 @@ impl BrushPrimitive {
|
|||
0.0,
|
||||
]);
|
||||
}
|
||||
BrushKind::LinearGradient { start_point, end_point, extend_mode, .. } => {
|
||||
request.push([
|
||||
start_point.x,
|
||||
start_point.y,
|
||||
end_point.x,
|
||||
end_point.y,
|
||||
]);
|
||||
request.push([
|
||||
pack_as_float(extend_mode as u32),
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
]);
|
||||
}
|
||||
BrushKind::RadialGradient { start_center, end_center, start_radius, end_radius, ratio_xy, extend_mode, .. } => {
|
||||
request.push([
|
||||
start_center.x,
|
||||
|
@ -432,46 +465,6 @@ impl ToGpuBlocks for BorderPrimitiveCpu {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GradientPrimitiveCpu {
|
||||
pub stops_range: ItemRange<GradientStop>,
|
||||
pub stops_count: usize,
|
||||
pub extend_mode: ExtendMode,
|
||||
pub reverse_stops: bool,
|
||||
pub gpu_blocks: [GpuBlockData; 3],
|
||||
}
|
||||
|
||||
impl GradientPrimitiveCpu {
|
||||
fn build_gpu_blocks_for_aligned(
|
||||
&self,
|
||||
display_list: &BuiltDisplayList,
|
||||
mut request: GpuDataRequest,
|
||||
) -> PrimitiveOpacity {
|
||||
let mut opacity = PrimitiveOpacity::opaque();
|
||||
request.extend_from_slice(&self.gpu_blocks);
|
||||
let src_stops = display_list.get(self.stops_range);
|
||||
|
||||
for src in src_stops {
|
||||
request.push(src.color.premultiplied());
|
||||
request.push([src.offset, 0.0, 0.0, 0.0]);
|
||||
opacity.accumulate(src.color.a);
|
||||
}
|
||||
|
||||
opacity
|
||||
}
|
||||
|
||||
fn build_gpu_blocks_for_angle_radial(
|
||||
&self,
|
||||
display_list: &BuiltDisplayList,
|
||||
mut request: GpuDataRequest,
|
||||
) {
|
||||
request.extend_from_slice(&self.gpu_blocks);
|
||||
|
||||
let gradient_builder = GradientGpuBlockBuilder::new(self.stops_range, display_list);
|
||||
gradient_builder.build(self.reverse_stops, &mut request);
|
||||
}
|
||||
}
|
||||
|
||||
// The gradient entry index for the first color stop
|
||||
pub const GRADIENT_DATA_FIRST_STOP: usize = 0;
|
||||
// The gradient entry index for the last color stop
|
||||
|
@ -670,7 +663,7 @@ impl TextRunPrimitiveCpu {
|
|||
pub fn get_font(
|
||||
&self,
|
||||
device_pixel_scale: DevicePixelScale,
|
||||
transform: Option<&LayerToWorldTransform>,
|
||||
transform: Option<LayerToWorldTransform>,
|
||||
) -> FontInstance {
|
||||
let mut font = self.font.clone();
|
||||
font.size = font.size.scale_by(device_pixel_scale.0);
|
||||
|
@ -678,7 +671,7 @@ impl TextRunPrimitiveCpu {
|
|||
if transform.has_perspective_component() || !transform.has_2d_inverse() {
|
||||
font.render_mode = font.render_mode.limit_by(FontRenderMode::Alpha);
|
||||
} else {
|
||||
font.transform = FontTransform::from(transform).quantize();
|
||||
font.transform = FontTransform::from(&transform).quantize();
|
||||
}
|
||||
}
|
||||
font
|
||||
|
@ -688,7 +681,7 @@ impl TextRunPrimitiveCpu {
|
|||
&mut self,
|
||||
resource_cache: &mut ResourceCache,
|
||||
device_pixel_scale: DevicePixelScale,
|
||||
transform: Option<&LayerToWorldTransform>,
|
||||
transform: Option<LayerToWorldTransform>,
|
||||
display_list: &BuiltDisplayList,
|
||||
gpu_cache: &mut GpuCache,
|
||||
) {
|
||||
|
@ -937,8 +930,6 @@ pub enum PrimitiveContainer {
|
|||
TextRun(TextRunPrimitiveCpu),
|
||||
Image(ImagePrimitiveCpu),
|
||||
Border(BorderPrimitiveCpu),
|
||||
AlignedGradient(GradientPrimitiveCpu),
|
||||
AngleGradient(GradientPrimitiveCpu),
|
||||
Picture(PicturePrimitive),
|
||||
Brush(BrushPrimitive),
|
||||
}
|
||||
|
@ -949,7 +940,6 @@ pub struct PrimitiveStore {
|
|||
pub cpu_text_runs: Vec<TextRunPrimitiveCpu>,
|
||||
pub cpu_pictures: Vec<PicturePrimitive>,
|
||||
pub cpu_images: Vec<ImagePrimitiveCpu>,
|
||||
pub cpu_gradients: Vec<GradientPrimitiveCpu>,
|
||||
pub cpu_metadata: Vec<PrimitiveMetadata>,
|
||||
pub cpu_borders: Vec<BorderPrimitiveCpu>,
|
||||
}
|
||||
|
@ -962,7 +952,6 @@ impl PrimitiveStore {
|
|||
cpu_text_runs: Vec::new(),
|
||||
cpu_pictures: Vec::new(),
|
||||
cpu_images: Vec::new(),
|
||||
cpu_gradients: Vec::new(),
|
||||
cpu_borders: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -974,7 +963,6 @@ impl PrimitiveStore {
|
|||
cpu_text_runs: recycle_vec(self.cpu_text_runs),
|
||||
cpu_pictures: recycle_vec(self.cpu_pictures),
|
||||
cpu_images: recycle_vec(self.cpu_images),
|
||||
cpu_gradients: recycle_vec(self.cpu_gradients),
|
||||
cpu_borders: recycle_vec(self.cpu_borders),
|
||||
}
|
||||
}
|
||||
|
@ -1015,6 +1003,7 @@ impl PrimitiveStore {
|
|||
BrushKind::Image { .. } => PrimitiveOpacity::translucent(),
|
||||
BrushKind::YuvImage { .. } => PrimitiveOpacity::opaque(),
|
||||
BrushKind::RadialGradient { .. } => PrimitiveOpacity::translucent(),
|
||||
BrushKind::LinearGradient { .. } => PrimitiveOpacity::translucent(),
|
||||
BrushKind::Picture => {
|
||||
// TODO(gw): This is not currently used. In the future
|
||||
// we should detect opaque pictures.
|
||||
|
@ -1077,29 +1066,6 @@ impl PrimitiveStore {
|
|||
self.cpu_borders.push(border_cpu);
|
||||
metadata
|
||||
}
|
||||
PrimitiveContainer::AlignedGradient(gradient_cpu) => {
|
||||
let metadata = PrimitiveMetadata {
|
||||
opacity: PrimitiveOpacity::translucent(),
|
||||
prim_kind: PrimitiveKind::AlignedGradient,
|
||||
cpu_prim_index: SpecificPrimitiveIndex(self.cpu_gradients.len()),
|
||||
..base_metadata
|
||||
};
|
||||
|
||||
self.cpu_gradients.push(gradient_cpu);
|
||||
metadata
|
||||
}
|
||||
PrimitiveContainer::AngleGradient(gradient_cpu) => {
|
||||
let metadata = PrimitiveMetadata {
|
||||
// TODO: calculate if the gradient is actually opaque
|
||||
opacity: PrimitiveOpacity::translucent(),
|
||||
prim_kind: PrimitiveKind::AngleGradient,
|
||||
cpu_prim_index: SpecificPrimitiveIndex(self.cpu_gradients.len()),
|
||||
..base_metadata
|
||||
};
|
||||
|
||||
self.cpu_gradients.push(gradient_cpu);
|
||||
metadata
|
||||
}
|
||||
};
|
||||
|
||||
self.cpu_metadata.push(metadata);
|
||||
|
@ -1146,7 +1112,7 @@ impl PrimitiveStore {
|
|||
let text = &mut self.cpu_text_runs[metadata.cpu_prim_index.0];
|
||||
// The transform only makes sense for screen space rasterization
|
||||
let transform = if pic_context.draw_text_transformed {
|
||||
Some(&prim_run_context.scroll_node.world_content_transform)
|
||||
Some(prim_run_context.scroll_node.world_content_transform.into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -1304,7 +1270,8 @@ impl PrimitiveStore {
|
|||
);
|
||||
}
|
||||
}
|
||||
BrushKind::RadialGradient { ref mut stops_handle, stops_range, .. } => {
|
||||
BrushKind::RadialGradient { gradient_index, stops_range, .. } => {
|
||||
let stops_handle = &mut frame_state.cached_gradients[gradient_index.0].handle;
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(stops_handle) {
|
||||
let gradient_builder = GradientGpuBlockBuilder::new(
|
||||
stops_range,
|
||||
|
@ -1316,6 +1283,19 @@ impl PrimitiveStore {
|
|||
);
|
||||
}
|
||||
}
|
||||
BrushKind::LinearGradient { gradient_index, stops_range, reverse_stops, .. } => {
|
||||
let stops_handle = &mut frame_state.cached_gradients[gradient_index.0].handle;
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(stops_handle) {
|
||||
let gradient_builder = GradientGpuBlockBuilder::new(
|
||||
stops_range,
|
||||
pic_context.display_list,
|
||||
);
|
||||
gradient_builder.build(
|
||||
reverse_stops,
|
||||
&mut request,
|
||||
);
|
||||
}
|
||||
}
|
||||
BrushKind::Mask { .. } |
|
||||
BrushKind::Solid { .. } |
|
||||
BrushKind::Clear |
|
||||
|
@ -1323,8 +1303,6 @@ impl PrimitiveStore {
|
|||
BrushKind::Picture { .. } => {}
|
||||
}
|
||||
}
|
||||
PrimitiveKind::AlignedGradient |
|
||||
PrimitiveKind::AngleGradient => {}
|
||||
}
|
||||
|
||||
// Mark this GPU resource as required for this frame.
|
||||
|
@ -1342,20 +1320,6 @@ impl PrimitiveStore {
|
|||
let image = &self.cpu_images[metadata.cpu_prim_index.0];
|
||||
image.write_gpu_blocks(request);
|
||||
}
|
||||
PrimitiveKind::AlignedGradient => {
|
||||
let gradient = &self.cpu_gradients[metadata.cpu_prim_index.0];
|
||||
metadata.opacity = gradient.build_gpu_blocks_for_aligned(
|
||||
pic_context.display_list,
|
||||
request,
|
||||
);
|
||||
}
|
||||
PrimitiveKind::AngleGradient => {
|
||||
let gradient = &self.cpu_gradients[metadata.cpu_prim_index.0];
|
||||
gradient.build_gpu_blocks_for_angle_radial(
|
||||
pic_context.display_list,
|
||||
request,
|
||||
);
|
||||
}
|
||||
PrimitiveKind::TextRun => {
|
||||
let text = &self.cpu_text_runs[metadata.cpu_prim_index.0];
|
||||
text.write_gpu_blocks(&mut request);
|
||||
|
@ -1471,14 +1435,14 @@ impl PrimitiveStore {
|
|||
let local_clip_rect = if clip_item.scroll_node_data_index == prim_run_context.scroll_node.node_data_index {
|
||||
local_clip_rect
|
||||
} else {
|
||||
let clip_transform_data = &frame_context
|
||||
.node_data[clip_item.scroll_node_data_index.0 as usize];
|
||||
let clip_transform = frame_context
|
||||
.node_data[clip_item.scroll_node_data_index.0 as usize]
|
||||
.transform;
|
||||
let prim_transform = &prim_run_context.scroll_node.world_content_transform;
|
||||
|
||||
let relative_transform = prim_transform
|
||||
.inverse()
|
||||
.unwrap_or(WorldToLayerTransform::identity())
|
||||
.pre_mul(&clip_transform_data.transform);
|
||||
.unwrap_or(WorldToLayerFastTransform::identity())
|
||||
.pre_mul(&clip_transform.into());
|
||||
|
||||
relative_transform.transform_rect(&local_clip_rect)
|
||||
};
|
||||
|
@ -2061,8 +2025,7 @@ fn get_local_clip_rect_for_nodes(
|
|||
);
|
||||
|
||||
match local_rect {
|
||||
Some(local_rect) =>
|
||||
Some(scroll_node.coordinate_system_relative_transform.unapply(&local_rect)),
|
||||
Some(local_rect) => scroll_node.coordinate_system_relative_transform.unapply(&local_rect),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1007,6 +1007,9 @@ impl RenderBackend {
|
|||
}
|
||||
};
|
||||
|
||||
let msg_update = ResultMsg::UpdateGpuCache(self.gpu_cache.extract_updates());
|
||||
self.result_tx.send(msg_update).unwrap();
|
||||
|
||||
let msg_publish = ResultMsg::PublishDocument(
|
||||
id,
|
||||
render_doc,
|
||||
|
|
|
@ -83,6 +83,10 @@ const GPU_CACHE_RESIZE_TEST: bool = false;
|
|||
/// Number of GPU blocks per UV rectangle provided for an image.
|
||||
pub const BLOCKS_PER_UV_RECT: usize = 2;
|
||||
|
||||
const GPU_TAG_BRUSH_LINEAR_GRADIENT: GpuProfileTag = GpuProfileTag {
|
||||
label: "B_LinearGradient",
|
||||
color: debug_colors::POWDERBLUE,
|
||||
};
|
||||
const GPU_TAG_BRUSH_RADIAL_GRADIENT: GpuProfileTag = GpuProfileTag {
|
||||
label: "B_RadialGradient",
|
||||
color: debug_colors::LIGHTPINK,
|
||||
|
@ -151,14 +155,6 @@ const GPU_TAG_PRIM_TEXT_RUN: GpuProfileTag = GpuProfileTag {
|
|||
label: "TextRun",
|
||||
color: debug_colors::BLUE,
|
||||
};
|
||||
const GPU_TAG_PRIM_GRADIENT: GpuProfileTag = GpuProfileTag {
|
||||
label: "Gradient",
|
||||
color: debug_colors::YELLOW,
|
||||
};
|
||||
const GPU_TAG_PRIM_ANGLE_GRADIENT: GpuProfileTag = GpuProfileTag {
|
||||
label: "AngleGradient",
|
||||
color: debug_colors::POWDERBLUE,
|
||||
};
|
||||
const GPU_TAG_PRIM_BORDER_CORNER: GpuProfileTag = GpuProfileTag {
|
||||
label: "BorderCorner",
|
||||
color: debug_colors::DARKSLATEGREY,
|
||||
|
@ -200,8 +196,6 @@ impl TransformBatchKind {
|
|||
ImageBufferKind::TextureExternal => "Image (External)",
|
||||
ImageBufferKind::Texture2DArray => "Image (Array)",
|
||||
},
|
||||
TransformBatchKind::AlignedGradient => "AlignedGradient",
|
||||
TransformBatchKind::AngleGradient => "AngleGradient",
|
||||
TransformBatchKind::BorderCorner => "BorderCorner",
|
||||
TransformBatchKind::BorderEdge => "BorderEdge",
|
||||
}
|
||||
|
@ -213,8 +207,6 @@ impl TransformBatchKind {
|
|||
TransformBatchKind::Image(..) => GPU_TAG_PRIM_IMAGE,
|
||||
TransformBatchKind::BorderCorner => GPU_TAG_PRIM_BORDER_CORNER,
|
||||
TransformBatchKind::BorderEdge => GPU_TAG_PRIM_BORDER_EDGE,
|
||||
TransformBatchKind::AlignedGradient => GPU_TAG_PRIM_GRADIENT,
|
||||
TransformBatchKind::AngleGradient => GPU_TAG_PRIM_ANGLE_GRADIENT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,6 +227,7 @@ impl BatchKind {
|
|||
BrushBatchKind::MixBlend { .. } => "Brush (Composite)",
|
||||
BrushBatchKind::YuvImage(..) => "Brush (YuvImage)",
|
||||
BrushBatchKind::RadialGradient => "Brush (RadialGradient)",
|
||||
BrushBatchKind::LinearGradient => "Brush (LinearGradient)",
|
||||
}
|
||||
}
|
||||
BatchKind::Transformable(_, batch_kind) => batch_kind.debug_name(),
|
||||
|
@ -255,6 +248,7 @@ impl BatchKind {
|
|||
BrushBatchKind::MixBlend { .. } => GPU_TAG_BRUSH_MIXBLEND,
|
||||
BrushBatchKind::YuvImage(..) => GPU_TAG_BRUSH_YUV_IMAGE,
|
||||
BrushBatchKind::RadialGradient => GPU_TAG_BRUSH_RADIAL_GRADIENT,
|
||||
BrushBatchKind::LinearGradient => GPU_TAG_BRUSH_LINEAR_GRADIENT,
|
||||
}
|
||||
}
|
||||
BatchKind::Transformable(_, batch_kind) => batch_kind.gpu_sampler_tag(),
|
||||
|
@ -1618,6 +1612,7 @@ pub struct Renderer {
|
|||
brush_mix_blend: BrushShader,
|
||||
brush_yuv_image: Vec<Option<BrushShader>>,
|
||||
brush_radial_gradient: BrushShader,
|
||||
brush_linear_gradient: BrushShader,
|
||||
|
||||
/// These are "cache clip shaders". These shaders are used to
|
||||
/// draw clip instances into the cached clip mask. The results
|
||||
|
@ -1638,8 +1633,6 @@ pub struct Renderer {
|
|||
ps_image: Vec<Option<PrimitiveShader>>,
|
||||
ps_border_corner: PrimitiveShader,
|
||||
ps_border_edge: PrimitiveShader,
|
||||
ps_gradient: PrimitiveShader,
|
||||
ps_angle_gradient: PrimitiveShader,
|
||||
|
||||
ps_hw_composite: LazilyCompiledShader,
|
||||
ps_split_composite: LazilyCompiledShader,
|
||||
|
@ -1884,6 +1877,17 @@ impl Renderer {
|
|||
options.precache_shaders)
|
||||
};
|
||||
|
||||
let brush_linear_gradient = try!{
|
||||
BrushShader::new("brush_linear_gradient",
|
||||
&mut device,
|
||||
if options.enable_dithering {
|
||||
&dithering_feature
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
options.precache_shaders)
|
||||
};
|
||||
|
||||
let cs_blur_a8 = try!{
|
||||
LazilyCompiledShader::new(ShaderKind::Cache(VertexArrayKind::Blur),
|
||||
"cs_blur",
|
||||
|
@ -2030,28 +2034,6 @@ impl Renderer {
|
|||
options.precache_shaders)
|
||||
};
|
||||
|
||||
let ps_gradient = try!{
|
||||
PrimitiveShader::new("ps_gradient",
|
||||
&mut device,
|
||||
if options.enable_dithering {
|
||||
&dithering_feature
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
options.precache_shaders)
|
||||
};
|
||||
|
||||
let ps_angle_gradient = try!{
|
||||
PrimitiveShader::new("ps_angle_gradient",
|
||||
&mut device,
|
||||
if options.enable_dithering {
|
||||
&dithering_feature
|
||||
} else {
|
||||
&[]
|
||||
},
|
||||
options.precache_shaders)
|
||||
};
|
||||
|
||||
let ps_hw_composite = try!{
|
||||
LazilyCompiledShader::new(ShaderKind::Primitive,
|
||||
"ps_hardware_composite",
|
||||
|
@ -2303,6 +2285,7 @@ impl Renderer {
|
|||
brush_mix_blend,
|
||||
brush_yuv_image,
|
||||
brush_radial_gradient,
|
||||
brush_linear_gradient,
|
||||
cs_clip_rectangle,
|
||||
cs_clip_border,
|
||||
cs_clip_image,
|
||||
|
@ -2311,8 +2294,6 @@ impl Renderer {
|
|||
ps_image,
|
||||
ps_border_corner,
|
||||
ps_border_edge,
|
||||
ps_gradient,
|
||||
ps_angle_gradient,
|
||||
ps_hw_composite,
|
||||
ps_split_composite,
|
||||
debug: debug_renderer,
|
||||
|
@ -2892,7 +2873,9 @@ impl Renderer {
|
|||
for &mut (_, RenderedDocument { ref mut frame, .. }) in &mut active_documents {
|
||||
frame.profile_counters.reset_targets();
|
||||
self.prepare_gpu_cache(frame);
|
||||
assert!(frame.gpu_cache_frame_id <= self.gpu_cache_frame_id);
|
||||
assert!(frame.gpu_cache_frame_id <= self.gpu_cache_frame_id,
|
||||
"Received frame depends on a later GPU cache epoch ({:?}) than one we received last via `UpdateGpuCache` ({:?})",
|
||||
frame.gpu_cache_frame_id, self.gpu_cache_frame_id);
|
||||
|
||||
self.draw_tile_frame(
|
||||
frame,
|
||||
|
@ -3272,6 +3255,15 @@ impl Renderer {
|
|||
&mut self.renderer_errors,
|
||||
);
|
||||
}
|
||||
BrushBatchKind::LinearGradient => {
|
||||
self.brush_linear_gradient.bind(
|
||||
&mut self.device,
|
||||
key.blend_mode,
|
||||
projection,
|
||||
0,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
}
|
||||
BrushBatchKind::YuvImage(image_buffer_kind, format, color_space) => {
|
||||
let shader_index =
|
||||
Renderer::get_yuv_shader_index(image_buffer_kind, format, color_space);
|
||||
|
@ -3322,24 +3314,6 @@ impl Renderer {
|
|||
&mut self.renderer_errors,
|
||||
);
|
||||
}
|
||||
TransformBatchKind::AlignedGradient => {
|
||||
self.ps_gradient.bind(
|
||||
&mut self.device,
|
||||
transform_kind,
|
||||
projection,
|
||||
0,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
}
|
||||
TransformBatchKind::AngleGradient => {
|
||||
self.ps_angle_gradient.bind(
|
||||
&mut self.device,
|
||||
transform_kind,
|
||||
projection,
|
||||
0,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -4741,6 +4715,7 @@ impl Renderer {
|
|||
self.brush_blend.deinit(&mut self.device);
|
||||
self.brush_mix_blend.deinit(&mut self.device);
|
||||
self.brush_radial_gradient.deinit(&mut self.device);
|
||||
self.brush_linear_gradient.deinit(&mut self.device);
|
||||
self.cs_clip_rectangle.deinit(&mut self.device);
|
||||
self.cs_clip_image.deinit(&mut self.device);
|
||||
self.cs_clip_border.deinit(&mut self.device);
|
||||
|
@ -4766,8 +4741,6 @@ impl Renderer {
|
|||
}
|
||||
self.ps_border_corner.deinit(&mut self.device);
|
||||
self.ps_border_edge.deinit(&mut self.device);
|
||||
self.ps_gradient.deinit(&mut self.device);
|
||||
self.ps_angle_gradient.deinit(&mut self.device);
|
||||
self.ps_hw_composite.deinit(&mut self.device);
|
||||
self.ps_split_composite.deinit(&mut self.device);
|
||||
#[cfg(feature = "capture")]
|
||||
|
|
|
@ -16,7 +16,7 @@ use gpu_types::{ClipScrollNodeData, ClipScrollNodeIndex};
|
|||
use gpu_types::{PrimitiveInstance};
|
||||
use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture};
|
||||
use picture::{PictureKind};
|
||||
use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveStore};
|
||||
use prim_store::{CachedGradient, PrimitiveIndex, PrimitiveKind, PrimitiveStore};
|
||||
use prim_store::{BrushMaskKind, BrushKind, DeferredResolve, EdgeAaSegmentMask};
|
||||
use profiler::FrameProfileCounters;
|
||||
use render_task::{BlitSource, RenderTaskAddress, RenderTaskId, RenderTaskKind};
|
||||
|
@ -46,6 +46,7 @@ pub struct RenderTargetContext<'a> {
|
|||
pub clip_scroll_tree: &'a ClipScrollTree,
|
||||
pub use_dual_source_blending: bool,
|
||||
pub node_data: &'a [ClipScrollNodeData],
|
||||
pub cached_gradients: &'a [CachedGradient],
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
|
@ -599,6 +600,7 @@ impl RenderTarget for AlphaRenderTarget {
|
|||
BrushKind::Line { .. } |
|
||||
BrushKind::YuvImage { .. } |
|
||||
BrushKind::RadialGradient { .. } |
|
||||
BrushKind::LinearGradient { .. } |
|
||||
BrushKind::Image { .. } => {
|
||||
unreachable!("bug: unexpected brush here");
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{BorderRadius, DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixelScale};
|
||||
use api::{DevicePoint, DeviceRect, DeviceSize, LayerPoint, LayerRect, LayerSize};
|
||||
use api::{LayerToWorldTransform, LayerTransform, LayerVector2D, WorldRect};
|
||||
use euclid::{Point2D, Rect, Size2D, TypedPoint2D, TypedRect, TypedSize2D, TypedTransform2D};
|
||||
use euclid::TypedTransform3D;
|
||||
use api::{DevicePoint, DeviceRect, DeviceSize, LayerPixel, LayerPoint, LayerRect, LayerSize};
|
||||
use api::{LayoutPixel, WorldPixel, WorldRect};
|
||||
use euclid::{Point2D, Rect, Size2D, TypedPoint2D, TypedPoint3D, TypedRect, TypedSize2D};
|
||||
use euclid::{TypedTransform2D, TypedTransform3D, TypedVector2D};
|
||||
use num_traits::Zero;
|
||||
use std::{i32, f32};
|
||||
|
||||
|
@ -22,6 +22,7 @@ pub trait MatrixHelpers<Src, Dst> {
|
|||
fn inverse_rect_footprint(&self, rect: &TypedRect<f32, Dst>) -> TypedRect<f32, Src>;
|
||||
fn transform_kind(&self) -> TransformedRectKind;
|
||||
fn is_simple_translation(&self) -> bool;
|
||||
fn is_simple_2d_translation(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
|
||||
|
@ -105,6 +106,14 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
|
|||
self.m31.abs() < NEARLY_ZERO && self.m32.abs() < NEARLY_ZERO &&
|
||||
self.m34.abs() < NEARLY_ZERO
|
||||
}
|
||||
|
||||
fn is_simple_2d_translation(&self) -> bool {
|
||||
if !self.is_simple_translation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.m43.abs() < NEARLY_ZERO
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RectHelpers<U>
|
||||
|
@ -145,7 +154,7 @@ pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
|
|||
}
|
||||
|
||||
pub fn calculate_screen_bounding_rect(
|
||||
transform: &LayerToWorldTransform,
|
||||
transform: &LayerToWorldFastTransform,
|
||||
rect: &LayerRect,
|
||||
device_pixel_scale: DevicePixelScale,
|
||||
) -> DeviceIntRect {
|
||||
|
@ -334,67 +343,189 @@ impl MaxRect for DeviceRect {
|
|||
|
||||
/// An enum that tries to avoid expensive transformation matrix calculations
|
||||
/// when possible when dealing with non-perspective axis-aligned transformations.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TransformOrOffset {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FastTransform<Src, Dst> {
|
||||
/// A simple offset, which can be used without doing any matrix math.
|
||||
Offset(LayerVector2D),
|
||||
Offset(TypedVector2D<f32, Src>),
|
||||
|
||||
/// A transformation with an inverse. If the inverse isn't present, this isn't a 2D
|
||||
/// transformation, which means we need to fall back to using inverse_rect_footprint.
|
||||
/// Since this operation is so expensive, we avoid it for the 2D case.
|
||||
/// A 2D transformation with an inverse.
|
||||
Transform {
|
||||
transform: LayerTransform,
|
||||
inverse: Option<LayerTransform>,
|
||||
}
|
||||
transform: TypedTransform3D<f32, Src, Dst>,
|
||||
inverse: Option<TypedTransform3D<f32, Dst, Src>>,
|
||||
is_2d: bool,
|
||||
},
|
||||
}
|
||||
|
||||
impl TransformOrOffset {
|
||||
pub fn zero() -> TransformOrOffset {
|
||||
TransformOrOffset::Offset(LayerVector2D::zero())
|
||||
impl<Src, Dst> FastTransform<Src, Dst> {
|
||||
pub fn identity() -> Self {
|
||||
FastTransform::Offset(TypedVector2D::zero())
|
||||
}
|
||||
|
||||
fn new_transform(transform: LayerTransform) -> TransformOrOffset {
|
||||
if transform.is_2d() {
|
||||
TransformOrOffset::Transform {
|
||||
transform,
|
||||
inverse: Some(transform.inverse().expect("Expected invertible matrix."))
|
||||
pub fn with_vector(offset: TypedVector2D<f32, Src>) -> Self {
|
||||
FastTransform::Offset(offset)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_transform(transform: TypedTransform3D<f32, Src, Dst>) -> Self {
|
||||
if transform.is_simple_2d_translation() {
|
||||
return FastTransform::Offset(TypedVector2D::new(transform.m41, transform.m42));
|
||||
}
|
||||
let inverse = transform.inverse();
|
||||
let is_2d = transform.is_2d();
|
||||
FastTransform::Transform { transform, inverse, is_2d}
|
||||
}
|
||||
|
||||
pub fn to_transform(&self) -> TypedTransform3D<f32, Src, Dst> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) =>
|
||||
TypedTransform3D::create_translation(offset.x, offset.y, 0.0),
|
||||
FastTransform::Transform { transform, .. } => transform
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_invertible(&self) -> bool {
|
||||
match *self {
|
||||
FastTransform::Offset(..) => true,
|
||||
FastTransform::Transform { ref inverse, .. } => inverse.is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pre_mul<NewSrc>(
|
||||
&self,
|
||||
other: &FastTransform<NewSrc, Src>
|
||||
) -> FastTransform<NewSrc, Dst> {
|
||||
match (self, other) {
|
||||
(&FastTransform::Offset(ref offset), &FastTransform::Offset(ref other_offset)) => {
|
||||
let offset = TypedVector2D::from_untyped(&offset.to_untyped());
|
||||
FastTransform::Offset((offset + *other_offset))
|
||||
}
|
||||
_ => {
|
||||
let new_transform = self.to_transform().pre_mul(&other.to_transform());
|
||||
FastTransform::with_transform(new_transform)
|
||||
}
|
||||
} else {
|
||||
TransformOrOffset::Transform { transform, inverse: None }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply(&self, rect: &LayerRect) -> LayerRect {
|
||||
match *self {
|
||||
TransformOrOffset::Offset(offset) => rect.translate(&offset),
|
||||
TransformOrOffset::Transform {transform, .. } => transform.transform_rect(&rect),
|
||||
#[inline(always)]
|
||||
pub fn pre_translate(&self, other_offset: &TypedVector2D<f32, Src>) -> Self {
|
||||
match self {
|
||||
&FastTransform::Offset(ref offset) =>
|
||||
return FastTransform::Offset(*offset + *other_offset),
|
||||
&FastTransform::Transform { transform, .. } =>
|
||||
FastTransform::with_transform(transform.pre_translate(other_offset.to_3d()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unapply(&self, rect: &LayerRect) -> LayerRect {
|
||||
#[inline(always)]
|
||||
pub fn preserves_2d_axis_alignment(&self) -> bool {
|
||||
match *self {
|
||||
TransformOrOffset::Offset(offset) => rect.translate(&-offset),
|
||||
TransformOrOffset::Transform { inverse: Some(inverse), .. } =>
|
||||
inverse.transform_rect(&rect),
|
||||
TransformOrOffset::Transform { transform, inverse: None } =>
|
||||
transform.inverse_rect_footprint(rect),
|
||||
FastTransform::Offset(..) => true,
|
||||
FastTransform::Transform { ref transform, .. } =>
|
||||
transform.preserves_2d_axis_alignment(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offset(&self, new_offset: LayerVector2D) -> TransformOrOffset {
|
||||
#[inline(always)]
|
||||
pub fn has_perspective_component(&self) -> bool {
|
||||
match *self {
|
||||
TransformOrOffset::Offset(offset) => TransformOrOffset::Offset(offset + new_offset),
|
||||
TransformOrOffset::Transform { transform, .. } => {
|
||||
FastTransform::Offset(..) => false,
|
||||
FastTransform::Transform { ref transform, .. } => transform.has_perspective_component(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_backface_visible(&self) -> bool {
|
||||
match *self {
|
||||
FastTransform::Offset(..) => false,
|
||||
FastTransform::Transform { ref transform, .. } => transform.is_backface_visible(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn transform_point2d(&self, point: &TypedPoint2D<f32, Src>) -> TypedPoint2D<f32, Dst> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => {
|
||||
let new_point = *point + offset;
|
||||
TypedPoint2D::from_untyped(&new_point.to_untyped())
|
||||
}
|
||||
FastTransform::Transform { ref transform, .. } => transform.transform_point2d(point),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn transform_point3d(&self, point: &TypedPoint3D<f32, Src>) -> TypedPoint3D<f32, Dst> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) =>
|
||||
TypedPoint3D::new(point.x + offset.x, point.y + offset.y, point.z),
|
||||
FastTransform::Transform { ref transform, .. } => transform.transform_point3d(point),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn transform_rect(&self, rect: &TypedRect<f32, Src>) -> TypedRect<f32, Dst> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) =>
|
||||
TypedRect::from_untyped(&rect.to_untyped().translate(&offset.to_untyped())),
|
||||
FastTransform::Transform { ref transform, .. } => transform.transform_rect(rect),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unapply(&self, rect: &TypedRect<f32, Dst>) -> Option<TypedRect<f32, Src>> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) =>
|
||||
Some(TypedRect::from_untyped(&rect.to_untyped().translate(&-offset.to_untyped()))),
|
||||
FastTransform::Transform { inverse: Some(ref inverse), is_2d: true, .. } =>
|
||||
Some(inverse.transform_rect(&rect)),
|
||||
FastTransform::Transform { ref transform, is_2d: false, .. } =>
|
||||
Some(transform.inverse_rect_footprint(rect)),
|
||||
FastTransform::Transform { inverse: None, .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn offset(&self, new_offset: TypedVector2D<f32, Src>) -> Self {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => FastTransform::Offset(offset + new_offset),
|
||||
FastTransform::Transform { ref transform, .. } => {
|
||||
let transform = transform.pre_translate(new_offset.to_3d());
|
||||
TransformOrOffset::new_transform(transform)
|
||||
FastTransform::with_transform(transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self, transform: LayerTransform) -> Option<TransformOrOffset> {
|
||||
if transform.is_simple_translation() {
|
||||
let offset = LayerVector2D::new(transform.m41, transform.m42);
|
||||
Some(self.offset(offset))
|
||||
pub fn post_translate(&self, new_offset: TypedVector2D<f32, Dst>) -> Self {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) => {
|
||||
let offset = offset.to_untyped() + new_offset.to_untyped();
|
||||
FastTransform::Offset(TypedVector2D::from_untyped(&offset))
|
||||
}
|
||||
FastTransform::Transform { ref transform, .. } => {
|
||||
let transform = transform.post_translate(new_offset.to_3d());
|
||||
FastTransform::with_transform(transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn inverse(&self) -> Option<FastTransform<Dst, Src>> {
|
||||
match *self {
|
||||
FastTransform::Offset(offset) =>
|
||||
Some(FastTransform::Offset(TypedVector2D::new(-offset.x, -offset.y))),
|
||||
FastTransform::Transform { transform, inverse: Some(inverse), is_2d, } =>
|
||||
Some(FastTransform::Transform {
|
||||
transform: inverse,
|
||||
inverse: Some(transform),
|
||||
is_2d
|
||||
}),
|
||||
FastTransform::Transform { inverse: None, .. } => None,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self, transform: TypedTransform3D<f32, Src, Dst>) -> Option<Self> {
|
||||
if transform.is_simple_2d_translation() {
|
||||
Some(self.offset(TypedVector2D::new(transform.m41, transform.m42)))
|
||||
} else {
|
||||
// If we break 2D axis alignment or have a perspective component, we need to start a
|
||||
// new incompatible coordinate system with which we cannot share clips without masking.
|
||||
|
@ -402,3 +533,26 @@ impl TransformOrOffset {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Src, Dst> From<TypedTransform3D<f32, Src, Dst>> for FastTransform<Src, Dst> {
|
||||
fn from(transform: TypedTransform3D<f32, Src, Dst>) -> FastTransform<Src, Dst> {
|
||||
FastTransform::with_transform(transform)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Src, Dst> Into<TypedTransform3D<f32, Src, Dst>> for FastTransform<Src, Dst> {
|
||||
fn into(self) -> TypedTransform3D<f32, Src, Dst> {
|
||||
self.to_transform()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Src, Dst> From<TypedVector2D<f32, Src>> for FastTransform<Src, Dst> {
|
||||
fn from(vector: TypedVector2D<f32, Src>) -> FastTransform<Src, Dst> {
|
||||
FastTransform::with_vector(vector)
|
||||
}
|
||||
}
|
||||
|
||||
pub type LayoutFastTransform = FastTransform<LayoutPixel, LayoutPixel>;
|
||||
pub type LayerFastTransform = FastTransform<LayerPixel, LayerPixel>;
|
||||
pub type LayerToWorldFastTransform = FastTransform<LayerPixel, WorldPixel>;
|
||||
pub type WorldToLayerFastTransform = FastTransform<WorldPixel, LayerPixel>;
|
||||
|
|
|
@ -54,14 +54,6 @@ const SHADERS: &[Shader] = &[
|
|||
name: "ps_border_edge",
|
||||
features: PRIM_FEATURES,
|
||||
},
|
||||
Shader {
|
||||
name: "ps_gradient",
|
||||
features: PRIM_FEATURES,
|
||||
},
|
||||
Shader {
|
||||
name: "ps_angle_gradient",
|
||||
features: PRIM_FEATURES,
|
||||
},
|
||||
Shader {
|
||||
name: "ps_hardware_composite",
|
||||
features: PRIM_FEATURES,
|
||||
|
@ -81,7 +73,7 @@ const SHADERS: &[Shader] = &[
|
|||
// Brush shaders
|
||||
Shader {
|
||||
name: "brush_yuv_image",
|
||||
features: &["", "YUV_NV12", "YUV_PLANAR", "YUV_INTERLEAVED"],
|
||||
features: &["", "YUV_NV12", "YUV_PLANAR", "YUV_INTERLEAVED", "YUV_NV12,TEXTURE_RECT"],
|
||||
},
|
||||
Shader {
|
||||
name: "brush_mask",
|
||||
|
@ -109,6 +101,10 @@ const SHADERS: &[Shader] = &[
|
|||
},
|
||||
Shader {
|
||||
name: "brush_radial_gradient",
|
||||
features: &[ "DITHERING" ],
|
||||
},
|
||||
Shader {
|
||||
name: "brush_linear_gradient",
|
||||
features: &[],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1 +1 @@
|
|||
e8d2ffb404a85651fe08a6d09abbece9bd2b9182
|
||||
8a19316a733a484bf9bafb8257e3008b1418bfe4
|
||||
|
|
|
@ -76,6 +76,11 @@ public:
|
|||
if (mHandle) {
|
||||
::MesHandleFree(mHandle);
|
||||
}
|
||||
if (mBuffer) {
|
||||
// Bug 1440564: You'd think that MesHandleFree would free the buffer,
|
||||
// since it was created by RPC, but it doesn't.
|
||||
midl_user_free(mBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long GetEmptySize()
|
||||
|
|
|
@ -93,6 +93,9 @@ nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
|||
reinterpret_cast<void*>(true));
|
||||
#endif // DEBUG
|
||||
|
||||
mCustomContentContainer->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
|
||||
reinterpret_cast<void*>(true));
|
||||
|
||||
aElements.AppendElement(mCustomContentContainer);
|
||||
|
||||
// Do not create an accessible object for the container.
|
||||
|
|
|
@ -4612,12 +4612,11 @@ ScrollFrameHelper::CreateAnonymousContent(
|
|||
}
|
||||
}
|
||||
|
||||
nsNodeInfoManager *nodeInfoManager =
|
||||
presContext->Document()->NodeInfoManager();
|
||||
RefPtr<NodeInfo> nodeInfo;
|
||||
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbar, nullptr,
|
||||
kNameSpaceID_XUL,
|
||||
nsINode::ELEMENT_NODE);
|
||||
nsNodeInfoManager* nodeInfoManager = presContext->Document()->NodeInfoManager();
|
||||
RefPtr<NodeInfo> nodeInfo =
|
||||
nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbar, nullptr,
|
||||
kNameSpaceID_XUL,
|
||||
nsINode::ELEMENT_NODE);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (canHaveHorizontal) {
|
||||
|
@ -4636,6 +4635,9 @@ ScrollFrameHelper::CreateAnonymousContent(
|
|||
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
NS_LITERAL_STRING("always"), false);
|
||||
if (mIsRoot) {
|
||||
mHScrollbarContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
|
||||
reinterpret_cast<void*>(true));
|
||||
|
||||
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
|
||||
NS_LITERAL_STRING("true"), false);
|
||||
}
|
||||
|
@ -4659,6 +4661,8 @@ ScrollFrameHelper::CreateAnonymousContent(
|
|||
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
NS_LITERAL_STRING("always"), false);
|
||||
if (mIsRoot) {
|
||||
mVScrollbarContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
|
||||
reinterpret_cast<void*>(true));
|
||||
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::root_,
|
||||
NS_LITERAL_STRING("true"), false);
|
||||
}
|
||||
|
@ -4697,11 +4701,13 @@ ScrollFrameHelper::CreateAnonymousContent(
|
|||
mResizerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, dir, false);
|
||||
|
||||
if (mIsRoot) {
|
||||
mResizerContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
|
||||
reinterpret_cast<void*>(true));
|
||||
|
||||
Element* browserRoot = GetBrowserRoot(mOuter->GetContent());
|
||||
mCollapsedResizer = !(browserRoot &&
|
||||
browserRoot->HasAttr(kNameSpaceID_None, nsGkAtoms::showresizer));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mResizerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::element,
|
||||
NS_LITERAL_STRING("_parent"), false);
|
||||
}
|
||||
|
@ -4718,6 +4724,10 @@ ScrollFrameHelper::CreateAnonymousContent(
|
|||
kNameSpaceID_XUL,
|
||||
nsINode::ELEMENT_NODE);
|
||||
NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent), nodeInfo.forget());
|
||||
if (mIsRoot) {
|
||||
mScrollCornerContent->SetProperty(nsGkAtoms::docLevelNativeAnonymousContent,
|
||||
reinterpret_cast<void*>(true));
|
||||
}
|
||||
if (!aElements.AppendElement(mScrollCornerContent))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ fuzzy-if(skiaContent,1,342) == percent-2.html percent-2-ref.html
|
|||
fuzzy-if(skiaContent,1,343) == percent-3.html percent-3-ref.html
|
||||
|
||||
# more serious tests, using SVG reference
|
||||
fuzzy-if(skiaContent,17,58) fuzzy-if(webrender,42-42,66-66) == border-circle-2.html border-circle-2-ref.xhtml
|
||||
fuzzy-if(gtkWidget,14,280) fuzzy-if(cocoaWidget,4,582) fuzzy-if(Android,36,264) fuzzy-if(d2d,51,323) fuzzy-if(winWidget&&!d2d,16,377) fuzzy-if(skiaContent,63,398) fuzzy-if(webrender,64-64,897-897) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
|
||||
fuzzy-if(skiaContent,17,58) fuzzy-if(webrender,30-30,70-70) == border-circle-2.html border-circle-2-ref.xhtml
|
||||
fuzzy-if(gtkWidget,14,280) fuzzy-if(cocoaWidget,4,582) fuzzy-if(Android,36,264) fuzzy-if(d2d,51,323) fuzzy-if(winWidget&&!d2d,16,377) fuzzy-if(skiaContent,63,398) fuzzy-if(webrender,62-62,930-930) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
|
||||
|
||||
# Corners
|
||||
fuzzy-if(skiaContent,17,47) fuzzy-if(webrender,42-42,52-52) == corner-1.html corner-1-ref.svg # bottom corners different radius than top corners
|
||||
fuzzy-if(gtkWidget,23,5) fuzzy-if(winWidget&&!d2d,23,5) fuzzy-if(d2d,32,8) fuzzy-if(Android,10,8) fuzzy-if(skiaContent,18,49) fuzzy-if(webrender,42-42,51-51) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
|
||||
fuzzy-if(skiaContent,17,47) fuzzy-if(webrender,30-30,58-58) == corner-1.html corner-1-ref.svg # bottom corners different radius than top corners
|
||||
fuzzy-if(gtkWidget,23,5) fuzzy-if(winWidget&&!d2d,23,5) fuzzy-if(d2d,32,8) fuzzy-if(Android,10,8) fuzzy-if(skiaContent,18,49) fuzzy-if(webrender,30-30,57-57) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
|
||||
fuzzy-if(gtkWidget,3,10) fuzzy-if(winWidget&&!d2d,3,10) fuzzy-if(d2d,15,32) fuzzy-if(Android,3,15) fuzzy-if(skiaContent,18,90) fails-if(webrender) == corner-3.html corner-3-ref.svg
|
||||
fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,19-19,96-96) == corner-4.html corner-4-ref.svg
|
||||
fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,13-13,104-104) == corner-4.html corner-4-ref.svg
|
||||
|
||||
# Test that radii too long are reduced
|
||||
== border-reduce-height.html border-reduce-height-ref.html
|
||||
|
@ -39,7 +39,7 @@ fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,19-19,96-96) == corner-4.html cor
|
|||
fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
|
||||
!= clipping-2.html about:blank # background color clipped to inner/outer border, can't get
|
||||
# great tests for this due to antialiasing problems described in bug 466572
|
||||
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) fuzzy-if(skiaContent,17,62) fuzzy-if(webrender,42-42,66-66) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
|
||||
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) fuzzy-if(skiaContent,17,62) fuzzy-if(webrender,30-30,70-70) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
|
||||
|
||||
# Tests for clipping the contents of replaced elements and overflow!=visible
|
||||
!= clipping-4-ref.html clipping-4-notref.html
|
||||
|
|
|
@ -14,7 +14,7 @@ fails-if(Android) == boxshadow-button.html boxshadow-button-ref.html
|
|||
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,999) fuzzy-if(webrender,47-47,1080-1080) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
|
||||
|
||||
fails-if(Android) == boxshadow-fileupload.html boxshadow-fileupload-ref.html
|
||||
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),98,152) fuzzy-if(skiaContent,13,28) fuzzy-if(webrender,25,49) == boxshadow-inner-basic.html boxshadow-inner-basic-ref.svg
|
||||
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),98,152) fuzzy-if(skiaContent,13,28) fuzzy-if(webrender,19-19,50-50) == boxshadow-inner-basic.html boxshadow-inner-basic-ref.svg
|
||||
random-if(layersGPUAccelerated) == boxshadow-mixed.html boxshadow-mixed-ref.html
|
||||
== boxshadow-mixed-2.html boxshadow-mixed-2-ref.html
|
||||
random-if(d2d) fuzzy-if(skiaContent,1,100) fuzzy-if(webrender,127,3528) == boxshadow-rounded-spread.html boxshadow-rounded-spread-ref.html
|
||||
|
@ -40,7 +40,7 @@ fuzzy(13,9445) fuzzy-if(d2d,13,10926) fails-if(webrender) == boxshadow-inset-lar
|
|||
== overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html
|
||||
fuzzy-if(webrender,1,655) == 611574-1.html 611574-1-ref.html
|
||||
fuzzy-if(webrender,4,144) == 611574-2.html 611574-2-ref.html
|
||||
fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fuzzy-if(webrender,53-53,80-80) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
|
||||
fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fuzzy-if(webrender,34-34,82-82) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
|
||||
fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fails-if(webrender) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows
|
||||
== 1178575.html 1178575-ref.html
|
||||
== 1178575-2.html 1178575-2-ref.html
|
||||
|
|
|
@ -1199,7 +1199,7 @@ fails-if(Android||cocoaWidget) == 456147.xul 456147-ref.html # bug 458047
|
|||
fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,15,69) fuzzy-if(skiaContent,42,150) == 456219-1a.html 456219-1-ref.html # bug 1128229
|
||||
fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,15,69) fuzzy-if(skiaContent,42,150) == 456219-1b.html 456219-1-ref.html # bug 1128229
|
||||
fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,15,69) fuzzy-if(skiaContent,42,150) == 456219-1c.html 456219-1-ref.html # bug 1128229
|
||||
fuzzy-if(skiaContent,1,45) == 456219-2.html 456219-2-ref.html
|
||||
fuzzy-if(skiaContent,1,45) fuzzy-if(webrender,9-9,8-8) == 456219-2.html 456219-2-ref.html
|
||||
== 456330-1.gif 456330-1-ref.png
|
||||
== 456484-1.html 456484-1-ref.html
|
||||
== 457398-1.html 457398-1-ref.html
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
default-preferences pref(layout.css.box-decoration-break.enabled,true)
|
||||
|
||||
== box-decoration-break-1.html box-decoration-break-1-ref.html
|
||||
fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,6-6,8644-8796) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
|
||||
fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,11-11,8772-8924) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
|
||||
fuzzy(45,460) fuzzy-if(skiaContent,57,439) fuzzy-if(Android,57,1330) fuzzy-if(styloVsGecko,45,1410) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543
|
||||
random-if(!gtkWidget) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html
|
||||
== box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html
|
||||
|
|
|
@ -20,9 +20,9 @@ fuzzy-if(d2d,255,24) == element-paint-transform-03.html element-paint-transform-
|
|||
fuzzy-if(asyncPan,2,140) fuzzy-if(skiaContent,3,106) == element-paint-native-widget.html element-paint-native-widget-ref.html # in -ref the scrollframe is active and layerized differently with APZ
|
||||
fails-if(usesRepeatResampling) == element-paint-subimage-sampling-restriction.html about:blank
|
||||
== element-paint-clippath.html element-paint-clippath-ref.html
|
||||
fuzzy-if(webrender,51-51,723-723) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
|
||||
fuzzy-if(webrender,35-35,706-706) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
|
||||
fuzzy-if(skiaContent,1,326) == element-paint-sharpness-01b.html element-paint-sharpness-01c.html
|
||||
fuzzy-if(webrender,51-51,723-723) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html
|
||||
fuzzy-if(webrender,35-35,706-706) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html
|
||||
== element-paint-sharpness-02a.html element-paint-sharpness-02b.html
|
||||
== element-paint-sharpness-02b.html element-paint-sharpness-02c.html
|
||||
== element-paint-paintserversize-rounding-01.html element-paint-paintserversize-rounding-01-ref.html
|
||||
|
|
|
@ -54,7 +54,7 @@ fuzzy-if(webrender,64-64,1106-1106) == clip-path-ellipse-008.html clip-path-elli
|
|||
fuzzy(64,146) == clip-path-inset-002a.html clip-path-inset-002-ref.html
|
||||
fuzzy(64,146) == clip-path-inset-002b.html clip-path-inset-002-ref.html
|
||||
fuzzy(64,146) == clip-path-inset-002c.html clip-path-inset-002-ref.html
|
||||
fuzzy(64,340) fuzzy-if(webrender,72-72,292-292) == clip-path-inset-003.html clip-path-inset-003-ref.html
|
||||
fuzzy(64,340) fuzzy-if(webrender,69-69,292-292) == clip-path-inset-003.html clip-path-inset-003-ref.html
|
||||
|
||||
== clip-path-stroke-001.html clip-path-stroke-001-ref.html
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# If --with-gradle is specified, build mobile/android with Gradle. If no
|
||||
# Gradle binary is specified, or if --without-gradle is specified, use the in
|
||||
# tree Gradle wrapper. The wrapper downloads and installs Gradle, which is
|
||||
# good for local developers but not good in automation.
|
||||
# Gradle binary is specified use the in tree Gradle wrapper. The wrapper
|
||||
# downloads and installs Gradle, which is good for local developers but not
|
||||
# good in automation.
|
||||
option('--with-gradle', nargs='?',
|
||||
default=True,
|
||||
help='Enable building mobile/android with Gradle '
|
||||
|
@ -15,6 +15,10 @@ option('--with-gradle', nargs='?',
|
|||
|
||||
@depends('--with-gradle')
|
||||
def with_gradle(value):
|
||||
if not value:
|
||||
die('Building --without-gradle is no longer supported: '
|
||||
'see https://bugzilla.mozilla.org/show_bug.cgi?id=1414415.')
|
||||
|
||||
if value:
|
||||
return True
|
||||
|
||||
|
|
|
@ -55,12 +55,12 @@ def migrate(ctx):
|
|||
]
|
||||
),
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('search-field'),
|
||||
id=FTL.Identifier('search-input'),
|
||||
attributes=[
|
||||
FTL.Attribute(
|
||||
FTL.Identifier('style'),
|
||||
CONCAT(
|
||||
FTL.TextElement('min-width: '),
|
||||
FTL.TextElement('width: '),
|
||||
COPY(
|
||||
'browser/chrome/browser/preferences/preferences.dtd',
|
||||
'searchField.width'
|
||||
|
|
|
@ -1162,4 +1162,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
|||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1527796029054000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1527882307482000);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,7 +8,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1530215215690000);
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1530301494484000);
|
||||
%%
|
||||
0-1.party, 1
|
||||
0.me.uk, 1
|
||||
|
@ -2775,6 +2775,7 @@ autoverzekeringafsluiten.com, 1
|
|||
autozane.com, 1
|
||||
autres-talents.fr, 1
|
||||
auvernet.org, 1
|
||||
aux-arts-de-la-table.com, 1
|
||||
auxquatrevents.ch, 1
|
||||
av01.tv, 1
|
||||
av0ndale.de, 1
|
||||
|
@ -4344,7 +4345,6 @@ blunderify.se, 1
|
|||
bluproducts.com.es, 1
|
||||
blurringexistence.net, 1
|
||||
blusmurf.net, 1
|
||||
blutopia.xyz, 1
|
||||
blvdmb.com, 1
|
||||
bm-i.ch, 1
|
||||
bm-immo.ch, 1
|
||||
|
@ -4942,14 +4942,12 @@ brunosouza.org, 1
|
|||
bruun.co, 1
|
||||
bryankaplan.com, 1
|
||||
bryanquigley.com, 1
|
||||
bryanshearer.accountant, 1
|
||||
brynnan.nl, 1
|
||||
brztec.com, 1
|
||||
bs-network.net, 1
|
||||
bs-security.com, 1
|
||||
bs.sb, 1
|
||||
bs.to, 1
|
||||
bsa157.org, 1
|
||||
bsagan.fr, 1
|
||||
bsalyzer.com, 1
|
||||
bsatroop794.org, 1
|
||||
|
@ -5686,7 +5684,6 @@ cave-reynard.ch, 1
|
|||
cavevinsdefrance.fr, 1
|
||||
cavzodiaco.com.br, 1
|
||||
caylercapital.com, 1
|
||||
cayounglab.co.jp, 1
|
||||
cazaviajes.es, 1
|
||||
cazes.info, 1
|
||||
cbamo.org, 1
|
||||
|
@ -6350,7 +6347,7 @@ cirugiasplasticas.com.mx, 1
|
|||
cirujanooral.com, 1
|
||||
cirurgicagervasio.com.br, 1
|
||||
cirurgicalucena.com.br, 1
|
||||
ciscodude.net, 0
|
||||
ciscodude.net, 1
|
||||
cisoaid.com, 1
|
||||
ciss.ltd, 1
|
||||
cisy.me, 1
|
||||
|
@ -8197,7 +8194,6 @@ decodeanddestroy.com, 1
|
|||
decoder.link, 1
|
||||
decomplify.com, 1
|
||||
decor-d.com, 1
|
||||
decoraid.com, 1
|
||||
decoratrix.com, 1
|
||||
decorauvent.ca, 1
|
||||
decorestilo.com.br, 1
|
||||
|
@ -8280,6 +8276,7 @@ dekoh-shouyu.com, 1
|
|||
dekonix.ru, 1
|
||||
delahrzolder.nl, 1
|
||||
delbecqvo.be, 1
|
||||
delbrouck.ch, 1
|
||||
deleidscheflesch.nl, 1
|
||||
delfic.org, 1
|
||||
delfino.cr, 1
|
||||
|
@ -8306,7 +8303,6 @@ deltadata.ch, 1
|
|||
deltaonlineguards.com, 1
|
||||
deltasmart.ch, 1
|
||||
deltava.org, 1
|
||||
demandware.com, 1
|
||||
demarche-expresse.com, 1
|
||||
demarle.ch, 1
|
||||
dementiapraecox.de, 1
|
||||
|
@ -8531,7 +8527,6 @@ devzero.io, 1
|
|||
dewaard.de, 1
|
||||
dewalch.net, 1
|
||||
dewapress.com, 1
|
||||
dewebwerf.nl, 1
|
||||
dexalo.de, 1
|
||||
dezeregio.nl, 1
|
||||
dezet-ev.de, 1
|
||||
|
@ -9454,7 +9449,7 @@ duo.com, 1
|
|||
duo.money, 1
|
||||
duoluodeyu.com, 1
|
||||
duoquadragintien.fr, 1
|
||||
dupisces.com.tw, 1
|
||||
dupisces.com.tw, 0
|
||||
dupree.co, 1
|
||||
durangoenergyllc.com, 1
|
||||
durdle.com, 1
|
||||
|
@ -9474,7 +9469,6 @@ dustygroove.com, 1
|
|||
dustyspokesbnb.ca, 1
|
||||
dutch.desi, 1
|
||||
dutch1.nl, 1
|
||||
dutchessuganda.com, 1
|
||||
dutchrank.nl, 1
|
||||
dutchwanderers.nl, 1
|
||||
dutchweballiance.nl, 1
|
||||
|
@ -10148,7 +10142,6 @@ emma-o.com, 1
|
|||
emmagraystore.com, 1
|
||||
emmaliddell.com, 1
|
||||
emmanuelle-et-julien.ch, 1
|
||||
emmdy.com, 1
|
||||
emmehair.com, 1
|
||||
emoji.bzh, 1
|
||||
emojiengine.com, 1
|
||||
|
@ -10188,6 +10181,7 @@ en-crypt.me, 1
|
|||
en-maktoob.search.yahoo.com, 0
|
||||
en4rab.co.uk, 1
|
||||
en4u.org, 1
|
||||
enaah.de, 1
|
||||
enaim.de, 1
|
||||
enamae.net, 1
|
||||
encadrer-mon-enfant.com, 1
|
||||
|
@ -10944,7 +10938,6 @@ exit9wineandliquor.com, 1
|
|||
exmoe.com, 1
|
||||
exo.do, 1
|
||||
exon.io, 1
|
||||
exoscale.ch, 1
|
||||
exoticads.com, 1
|
||||
exousiakaidunamis.pw, 1
|
||||
exp.de, 1
|
||||
|
@ -12241,7 +12234,6 @@ fromthesoutherncross.com, 1
|
|||
fronteers.nl, 0
|
||||
frontline.cloud, 1
|
||||
frontline6.com, 1
|
||||
frostbytes.net, 1
|
||||
frosthall.com, 1
|
||||
frostprotection.co.uk, 1
|
||||
frostwarning.com, 1
|
||||
|
@ -12918,7 +12910,6 @@ gevaulug.fr, 1
|
|||
geyduschek.be, 1
|
||||
gfast.ru, 1
|
||||
gfcleisure.co.uk, 1
|
||||
gfecs.de, 1
|
||||
gfk-kunststoff-luebben.de, 1
|
||||
gflame.de, 1
|
||||
gflclan.ru, 1
|
||||
|
@ -12980,7 +12971,6 @@ gifzilla.net, 0
|
|||
gig-raiffeisen.de, 1
|
||||
gig.ru, 0
|
||||
giga.nl, 1
|
||||
gigabitz.pw, 1
|
||||
gigantism.com, 1
|
||||
gigawa.lt, 1
|
||||
gigawattz.com, 1
|
||||
|
@ -13470,7 +13460,6 @@ grenadiercorps-kaarst.de, 1
|
|||
grenadiere-kaarst.de, 1
|
||||
grenadierkorps-kaarst.de, 1
|
||||
grenadierkorps.de, 1
|
||||
grendel.no, 1
|
||||
grengine.ch, 1
|
||||
grepmaste.rs, 1
|
||||
grepular.com, 1
|
||||
|
@ -13975,6 +13964,7 @@ hash.works, 1
|
|||
hashcat.net, 1
|
||||
hashes.org, 1
|
||||
hashi.dk, 1
|
||||
hashiconf.com, 1
|
||||
hashiconf.eu, 1
|
||||
hashicorp.com, 1
|
||||
hashimah.ca, 1
|
||||
|
@ -14986,7 +14976,6 @@ hyperalgesia.com, 1
|
|||
hyperbolic-mayonnaise-interceptor.ovh, 1
|
||||
hyperion.io, 1
|
||||
hyperreal.biz, 1
|
||||
hyperreal.info, 1
|
||||
hypersomnia.com, 1
|
||||
hyperthymia.com, 1
|
||||
hyphen.co.za, 1
|
||||
|
@ -15602,6 +15591,7 @@ innerfence.com, 1
|
|||
innerform.com, 1
|
||||
innermostparts.org, 1
|
||||
innit.be, 1
|
||||
innohb.com, 1
|
||||
innolabfribourg.ch, 1
|
||||
innoloop.com, 1
|
||||
innophate-security.com, 1
|
||||
|
@ -15764,6 +15754,7 @@ intmissioncenter.org, 1
|
|||
into.technology, 1
|
||||
inton.biz, 1
|
||||
intoparking.com, 0
|
||||
intpforum.com, 1
|
||||
intracom.com, 1
|
||||
intradayseasonals.com, 1
|
||||
intranetsec-regionra.fr, 1
|
||||
|
@ -15817,7 +15808,6 @@ iodine.com, 1
|
|||
iodu.re, 1
|
||||
ioiart.eu, 1
|
||||
iojo.net, 1
|
||||
iompost.com, 1
|
||||
iomstamps.com, 1
|
||||
ionc.ca, 1
|
||||
ionlabs.kr, 1
|
||||
|
@ -16298,7 +16288,6 @@ jammysplodgers.co.uk, 1
|
|||
jamon.ca, 1
|
||||
jamonsilva.com, 1
|
||||
jamstatic.fr, 0
|
||||
jamyeprice.com, 0
|
||||
jan-and-maaret.de, 1
|
||||
jan-bucher.ch, 1
|
||||
jan-rieger.de, 1
|
||||
|
@ -16509,6 +16498,7 @@ jet-stream.fr, 1
|
|||
jetapi.org, 1
|
||||
jetbbs.com, 1
|
||||
jetbrains.pw, 1
|
||||
jetflex.de, 1
|
||||
jetkittens.co.uk, 1
|
||||
jetmirshatri.com, 1
|
||||
jetsetboyz.net, 1
|
||||
|
@ -17471,6 +17461,7 @@ kidbacker.com, 1
|
|||
kiddyboom.ua, 1
|
||||
kids-at-home.ch, 1
|
||||
kids-castles.com, 1
|
||||
kids2day.in, 1
|
||||
kidsareatrip.com, 1
|
||||
kidsforsavingearth.org, 1
|
||||
kidsinwoods-interfacesouth.org, 1
|
||||
|
@ -18719,6 +18710,7 @@ leuenhagen.com, 1
|
|||
leuthardtfamily.com, 1
|
||||
levans.fr, 1
|
||||
levanscatering.com, 1
|
||||
levelcheat.com, 1
|
||||
leveluprails.com, 1
|
||||
levelupwear.com, 1
|
||||
levendwater.org, 1
|
||||
|
@ -18889,7 +18881,6 @@ lilaccakeboutique.com, 1
|
|||
liliang13.com, 1
|
||||
lilismartinis.com, 1
|
||||
lillepuu.com, 1
|
||||
lily-bearing.com, 1
|
||||
lily-inn.com, 1
|
||||
lilyfarmfreshskincare.com, 1
|
||||
lilygreen.co.za, 1
|
||||
|
@ -19345,7 +19336,6 @@ lovelens.li, 1
|
|||
lovelive-anime.tk, 1
|
||||
lovelive.us, 1
|
||||
lovelivewiki.com, 1
|
||||
lovelytimes.net, 1
|
||||
lovemomiji.com, 1
|
||||
lovenwishes.com, 1
|
||||
loveph.one, 1
|
||||
|
@ -19560,7 +19550,6 @@ lynxbroker.de, 1
|
|||
lynxpro.nl, 1
|
||||
lyon-interactive.com, 1
|
||||
lyon-synergie.com, 1
|
||||
lyoness.digital, 1
|
||||
lyonl.com, 1
|
||||
lyricfm.ie, 1
|
||||
lys.ch, 1
|
||||
|
@ -20801,7 +20790,7 @@ mig5.net, 1
|
|||
miggy.org, 1
|
||||
mightymillionsraffle.com, 1
|
||||
miguel.pw, 1
|
||||
migueldemoura.com, 1
|
||||
migueldemoura.com, 0
|
||||
migueldominguez.ch, 1
|
||||
miguelgfierro.com, 1
|
||||
miguelmartinez.ch, 1
|
||||
|
@ -21504,6 +21493,7 @@ mrjooz.com, 1
|
|||
mrkapowski.com, 1
|
||||
mrketolocksmith.com, 1
|
||||
mrknee.gr, 1
|
||||
mrksk.com, 1
|
||||
mrleonardo.com, 1
|
||||
mrliu.me, 1
|
||||
mrmoregame.de, 1
|
||||
|
@ -21929,7 +21919,6 @@ myssl.com, 1
|
|||
mystatus24.com, 1
|
||||
mysteriouscode.io, 1
|
||||
mysterymind.ch, 1
|
||||
mysterysear.ch, 1
|
||||
mystic-welten.de, 1
|
||||
mystickphysick.com, 1
|
||||
mysticplumes.com, 1
|
||||
|
@ -22470,7 +22459,6 @@ neurobiology.com, 1
|
|||
neurochip.com, 1
|
||||
neurocny.cloud, 1
|
||||
neuroethics.com, 1
|
||||
neurogroove.info, 1
|
||||
neurolab.no, 1
|
||||
neuronasdigitales.com, 1
|
||||
neuropharmacology.com, 1
|
||||
|
@ -23313,6 +23301,7 @@ oleodecopayba.com.br, 1
|
|||
olgiati.org, 1
|
||||
olgui.net, 1
|
||||
olightstore.com, 1
|
||||
olightstore.ro, 1
|
||||
oliode.tk, 1
|
||||
oliveoil.bot, 1
|
||||
oliveoiltest.com, 1
|
||||
|
@ -23525,7 +23514,6 @@ opendataincubator.eu, 1
|
|||
opendecide.com, 1
|
||||
openevic.info, 1
|
||||
openfir.st, 1
|
||||
openfitapi-falke.azurewebsites.net, 1
|
||||
opengg.me, 1
|
||||
openings.ninja, 1
|
||||
openintelligence.uk, 1
|
||||
|
@ -24938,6 +24926,8 @@ plumbingbenoni.co.za, 1
|
|||
plumlocosoft.com, 1
|
||||
plumnet.ch, 1
|
||||
plumpie.net, 0
|
||||
plur.com.au, 1
|
||||
plural.cafe, 1
|
||||
plus-5.com, 1
|
||||
plus.google.com, 1
|
||||
plus.sandbox.google.com, 1
|
||||
|
@ -25180,6 +25170,7 @@ postdarwinism.com, 1
|
|||
postdeck.de, 1
|
||||
posteo.de, 0
|
||||
posters.win, 1
|
||||
posterspy.com, 1
|
||||
postfalls-naturopathic.com, 1
|
||||
postfinance.ch, 1
|
||||
postmatescode.com, 1
|
||||
|
@ -25193,6 +25184,7 @@ potature.rimini.it, 1
|
|||
potature.roma.it, 1
|
||||
potbar.com, 1
|
||||
potbox.com, 1
|
||||
potentialproject.com, 1
|
||||
pothe.com, 1
|
||||
pothe.de, 1
|
||||
potlytics.com, 1
|
||||
|
@ -25602,7 +25594,6 @@ proxybay.one, 1
|
|||
proxybay.tv, 1
|
||||
proxydesk.eu, 1
|
||||
proxyportal.net, 1
|
||||
proxyportal.org, 1
|
||||
proymaganadera.com, 1
|
||||
prpferrara.it, 1
|
||||
prplz.io, 1
|
||||
|
@ -25884,6 +25875,7 @@ quaggan.co, 1
|
|||
quai10.org, 0
|
||||
quakelive.dk, 0
|
||||
qualite-ecole-et-formation.ch, 1
|
||||
quality-life.gr, 1
|
||||
qualityedgarsolutions.com, 1
|
||||
qualityhomesystems.com, 1
|
||||
qualityofcourse.com, 0
|
||||
|
@ -26212,7 +26204,6 @@ reachrss.com, 1
|
|||
reaconverter.com, 1
|
||||
react-db.com, 1
|
||||
reactivarte.es, 1
|
||||
reactive-press.com, 1
|
||||
read.sc, 1
|
||||
reades.co.uk, 1
|
||||
readheadcopywriting.com, 1
|
||||
|
@ -26894,7 +26885,6 @@ rockuse.com.br, 1
|
|||
rockymountainspice.com, 1
|
||||
rocssti.net, 1
|
||||
rodarion.pl, 1
|
||||
roddis.net, 1
|
||||
rodehutskors.net, 1
|
||||
rodeobull.biz, 1
|
||||
rodeohire.com, 1
|
||||
|
@ -27618,6 +27608,7 @@ savetheinternet.eu, 1
|
|||
savic.com, 1
|
||||
savingbytes.com, 1
|
||||
savinggoliath.com, 1
|
||||
savingrecipe.com, 1
|
||||
savingsbondwizard.gov, 1
|
||||
savingsomegreen.com, 1
|
||||
savingsstoreonline.ca, 1
|
||||
|
@ -28963,6 +28954,7 @@ skylocker.nl, 1
|
|||
skyloisirs.ch, 1
|
||||
skyminds.net, 1
|
||||
skynet233.ch, 1
|
||||
skynethk.com, 1
|
||||
skynetnetwork.eu.org, 1
|
||||
skynetz.tk, 1
|
||||
skype.com, 1
|
||||
|
@ -29244,7 +29236,6 @@ socialdj.de, 1
|
|||
socialhams.net, 1
|
||||
socialmedia.ro, 1
|
||||
socialnitro.com, 1
|
||||
socialnous.co, 1
|
||||
socialrank.com, 1
|
||||
socialsecurity.gov, 0
|
||||
socialtrends.pl, 1
|
||||
|
@ -29352,7 +29343,6 @@ somali-derp.com, 1
|
|||
somaliagenda.com, 1
|
||||
somanao.com, 1
|
||||
somcase.com.br, 1
|
||||
somebodycares.org, 1
|
||||
somecrazy.com, 1
|
||||
somethingsimilar.com, 1
|
||||
sommefeldt.com, 1
|
||||
|
@ -29976,7 +29966,6 @@ stevenberg.net, 1
|
|||
stevengoodpaster.com, 1
|
||||
stevenhumphrey.uk, 1
|
||||
stevenkwan.me, 1
|
||||
stevenroddis.com, 1
|
||||
stevens.se, 1
|
||||
stevenski.com, 0
|
||||
steventress.com, 1
|
||||
|
@ -30668,7 +30657,6 @@ talenthero.io, 1
|
|||
talenthub.co.nz, 1
|
||||
talentos.pt, 1
|
||||
taler.net, 1
|
||||
talideon.com, 0
|
||||
talk.google.com, 1
|
||||
talk.xyz, 1
|
||||
talkgadget.google.com, 1
|
||||
|
@ -31682,6 +31670,7 @@ tintencenter.com, 1
|
|||
tintenfix.net, 1
|
||||
tintenfux.de, 1
|
||||
tintenland.de, 1
|
||||
tintenprofi.de, 1
|
||||
tiny.ee, 1
|
||||
tinyhousefinance.com.au, 1
|
||||
tinylan.com, 1
|
||||
|
@ -31737,7 +31726,6 @@ tkn.tokyo, 1
|
|||
tkts.cl, 1
|
||||
tkusano.jp, 1
|
||||
tkw01536.de, 1
|
||||
tlach.cz, 1
|
||||
tlca.org, 1
|
||||
tlcnet.info, 1
|
||||
tlehseasyads.com, 1
|
||||
|
@ -33011,6 +32999,7 @@ uspsoig.gov, 1
|
|||
ussm.gov, 1
|
||||
ussuka.com, 1
|
||||
ust.space, 1
|
||||
ustr.gov, 0
|
||||
usualbeings.com, 1
|
||||
uswitch.com, 1
|
||||
ut-addicted.com, 1
|
||||
|
@ -33578,6 +33567,7 @@ vivamusic.es, 1
|
|||
vivanosports.com.br, 1
|
||||
vivatv.com.tw, 1
|
||||
vivendi.de, 1
|
||||
vivianmaier.cn, 1
|
||||
vivid-academy.com, 1
|
||||
vividinflatables.co.uk, 1
|
||||
vividlumen.com, 1
|
||||
|
@ -34452,7 +34442,6 @@ wiktoriaslife.com, 1
|
|||
wilane.org, 1
|
||||
wilcodeboer.me, 1
|
||||
wild-emotion-events.de, 1
|
||||
wild-turtles.com, 1
|
||||
wildbirds.dk, 1
|
||||
wildboaratvparts.com, 1
|
||||
wildcard.hu, 1
|
||||
|
@ -35105,7 +35094,6 @@ xn--80aaagmgvmvmcuoq7r.xn--p1ai, 1
|
|||
xn--80anogxed.xn--p1ai, 1
|
||||
xn--80aocgsfei.xn--p1ai, 1
|
||||
xn--80azelb.xn--p1ai, 1
|
||||
xn--88j2fy28hbxmnnf9zlw5buzd.com, 1
|
||||
xn--8dry00a7se89ay98epsgxxq.com, 1
|
||||
xn--8mr166hf6s.xn--fiqs8s, 1
|
||||
xn--90accgba6bldkcbb7a.xn--p1acf, 1
|
||||
|
@ -35536,6 +35524,7 @@ yourdaddy.dk, 1
|
|||
yourforex.org, 1
|
||||
yourfriendlytech.com, 1
|
||||
yourgames.tv, 1
|
||||
yourhair.net, 1
|
||||
yoursbookstore.jp, 1
|
||||
yourself.today, 1
|
||||
yourticketbooking.com, 1
|
||||
|
|
|
@ -9,6 +9,7 @@ ChromeUtils.import("resource://services-sync/service.js");
|
|||
ChromeUtils.import("resource://services-sync/util.js");
|
||||
ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
ChromeUtils.import("resource:///modules/PlacesUIUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/PlacesTransactions.jsm");
|
||||
|
||||
let engine;
|
||||
let store;
|
||||
|
@ -455,18 +456,6 @@ add_task(async function test_onItemAdded() {
|
|||
let syncBmkGUID = await PlacesUtils.promiseItemGuid(syncBmkID);
|
||||
await verifyTrackedItems([syncFolderGUID, syncBmkGUID]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
|
||||
|
||||
await resetTracker();
|
||||
await startTracking();
|
||||
|
||||
_("Insert a separator using the sync API");
|
||||
let index = (await PlacesUtils.bookmarks.fetch(syncFolderGUID)).index;
|
||||
let syncSepID = PlacesUtils.bookmarks.insertSeparator(
|
||||
PlacesUtils.bookmarks.bookmarksMenuFolder,
|
||||
index);
|
||||
let syncSepGUID = await PlacesUtils.promiseItemGuid(syncSepID);
|
||||
await verifyTrackedItems(["menu", syncSepGUID]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
|
||||
} finally {
|
||||
_("Clean up.");
|
||||
await cleanup();
|
||||
|
@ -1242,30 +1231,27 @@ add_task(async function test_onItemDeleted_removeFolderTransaction() {
|
|||
|
||||
await startTracking();
|
||||
|
||||
let txn = PlacesUtils.bookmarks.getRemoveFolderTransaction(folder_id);
|
||||
let txn = PlacesTransactions.Remove({guid: folder_guid});
|
||||
// We haven't executed the transaction yet.
|
||||
await verifyTrackerEmpty();
|
||||
|
||||
_("Execute the remove folder transaction");
|
||||
txn.doTransaction();
|
||||
await txn.transact();
|
||||
await verifyTrackedItems(["menu", folder_guid, fx_guid, tb_guid]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 3);
|
||||
await resetTracker();
|
||||
|
||||
_("Undo the remove folder transaction");
|
||||
txn.undoTransaction();
|
||||
await PlacesTransactions.undo();
|
||||
|
||||
// At this point, the restored folder has the same ID, but a different GUID.
|
||||
let new_folder_guid = await PlacesUtils.promiseItemGuid(folder_id);
|
||||
|
||||
await verifyTrackedItems(["menu", new_folder_guid]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
|
||||
await verifyTrackedItems(["menu", folder_guid, fx_guid, tb_guid]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 3);
|
||||
await resetTracker();
|
||||
|
||||
_("Redo the transaction");
|
||||
txn.redoTransaction();
|
||||
await verifyTrackedItems(["menu", new_folder_guid]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
|
||||
await PlacesTransactions.redo();
|
||||
await verifyTrackedItems(["menu", folder_guid, fx_guid, tb_guid]);
|
||||
Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 3);
|
||||
} finally {
|
||||
_("Clean up.");
|
||||
await cleanup();
|
||||
|
|
|
@ -374,24 +374,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clipboard"
|
||||
version = "0.4.0"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"clipboard-win 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clipboard-win 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"objc_id 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x11-clipboard 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x11-clipboard 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "2.0.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -461,7 +459,7 @@ dependencies = [
|
|||
"bluetooth_traits 0.0.1",
|
||||
"canvas 0.0.1",
|
||||
"canvas_traits 0.0.1",
|
||||
"clipboard 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clipboard 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"compositing 0.0.1",
|
||||
"debugger 0.0.1",
|
||||
"devtools_traits 0.0.1",
|
||||
|
@ -3486,11 +3484,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "x11-clipboard"
|
||||
version = "0.1.4"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xcb 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xcb 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3505,7 +3503,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "xcb"
|
||||
version = "0.7.7"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3582,8 +3580,8 @@ dependencies = [
|
|||
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
|
||||
"checksum clang-sys 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00048189ee171715296dfe3b2fcfd439563c7bfec0d98d3976ce3402d62c8f07"
|
||||
"checksum clap 2.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc34bf7d5d66268b466b9852bca925ec1d2650654dab4da081e63fd230145c2e"
|
||||
"checksum clipboard 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd3a9a938558f33ec1baaa6ca631a69c104aafaacbc66868d9ad28cf5f30564f"
|
||||
"checksum clipboard-win 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "693b1280c514045382dfdbb78d1594b1b03cdb66320aeb7ebd2bd38d49bae959"
|
||||
"checksum clipboard 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b4623b47d8637fc9d47564583d4cc01eb8c8e34e26b2bf348bf4b036acb657"
|
||||
"checksum clipboard-win 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14cc3e6c075926b96490d5f90d4a5af7be8012a4d8a8698e619655085a7641a3"
|
||||
"checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
|
||||
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
||||
"checksum cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0c23085dde1ef4429df6e5896b89356d35cdd321fb43afe3e378d010bb5adc6"
|
||||
|
@ -3824,9 +3822,9 @@ dependencies = [
|
|||
"checksum ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04614a58714f3fd4a8b1da4bcae9f031c532d35988c3d39627619248113f8be8"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db27c597c187da52194a4b8232e7d869503911aab9ff726fefb76d7a830f78ed"
|
||||
"checksum x11-clipboard 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "731230b8edcbb9d99247105e4c9ec0a538594d50ad68d2afa8662195f9db2973"
|
||||
"checksum x11-clipboard 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78a35cd979d17b95e0706ab1f3425ecc98565d3873902bd5944b9f5f388327d1"
|
||||
"checksum x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "326c500cdc166fd7c70dd8c8a829cd5c0ce7be5a5d98c25817de2b9bdc67faf8"
|
||||
"checksum xcb 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7cede38417fcdf2f0a9d8abf1cea1c1b066320a8a316e9583a0d717c334fafb2"
|
||||
"checksum xcb 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "400cebeaedeca931825f11606874080f18aa51370dd3d7e11bc08d5aac8b3142"
|
||||
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
|
||||
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
|
||||
"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
|
||||
|
|
|
@ -79,14 +79,14 @@ mac-nightly:
|
|||
linux-rel-intermittent:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach build --release
|
||||
- ./etc/ci/check_intermittents.sh --log-raw intermittents.log
|
||||
|
||||
linux-rel-nogate:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach build --release
|
||||
- python ./etc/ci/chaos_monkey_test.py
|
||||
- env RUSTFLAGS= bash ./etc/ci/mutation_test.sh
|
||||
|
@ -104,7 +104,7 @@ linux-dev:
|
|||
commands:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach test-tidy --no-progress --all
|
||||
- ./mach test-tidy --no-progress --self-test
|
||||
- ./mach build --dev
|
||||
|
@ -124,7 +124,7 @@ linux-rel-wpt:
|
|||
commands:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach build --release --with-debug-assertions
|
||||
- ./mach test-wpt-failure
|
||||
- ./mach test-wpt --release --processes 24 --total-chunks 2 --this-chunk 1 --log-raw test-wpt.log --log-errorsummary wpt-errorsummary.log --always-succeed
|
||||
|
@ -138,7 +138,7 @@ linux-rel-css:
|
|||
commands:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach build --release --with-debug-assertions
|
||||
- ./mach test-wpt --release --processes 24 --total-chunks 2 --this-chunk 2 --log-raw test-wpt.log --log-errorsummary wpt-errorsummary.log --always-succeed
|
||||
- ./mach filter-intermittents wpt-errorsummary.log --log-intermittents intermittents.log --log-filteredsummary filtered-wpt-errorsummary.log --tracker-api default --reporter-api default
|
||||
|
@ -150,7 +150,7 @@ linux-rel-css:
|
|||
linux-nightly:
|
||||
- ./mach clean-nightlies --keep 3 --force
|
||||
- ./mach clean-cargo-cache --keep 3 --force
|
||||
- ./mach clean
|
||||
- ./etc/ci/clean_build_artifacts.sh
|
||||
- ./mach build --release
|
||||
- ./mach package --release
|
||||
- ./mach upload-nightly linux
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
rm -rf target/{debug,release,doc,geckolib}
|
|
@ -67,12 +67,10 @@ function unsafe_run_tests() {
|
|||
# last commit with the new results.
|
||||
function unsafe_update_metadata() {
|
||||
./mach update-wpt "${1}" || return 1
|
||||
# Ignore any metadata changes to files that weren't modified by this sync.
|
||||
git checkout -- tests/wpt/mozilla/meta || return 2
|
||||
# Ensure any new directories or ini files are included in these changes.
|
||||
git add tests/wpt/metadata || return 3
|
||||
git add tests/wpt/metadata tests/wpt/mozilla/meta || return 2
|
||||
# Merge all changes with the existing commit.
|
||||
git commit -a --amend --no-edit || return 4
|
||||
git commit -a --amend --no-edit || return 3
|
||||
}
|
||||
|
||||
# Push the branch to a remote branch, then open a PR for the branch
|
||||
|
|
|
@ -111,6 +111,7 @@ class Test(MachCommandBase):
|
|||
both harnesses will be invoked.
|
||||
"""
|
||||
from mozlog.commandline import setup_logging
|
||||
from mozlog.handlers import StreamHandler
|
||||
from moztest.resolve import get_suite_definition, TestResolver, TEST_SUITES
|
||||
|
||||
resolver = self._spawn(TestResolver)
|
||||
|
@ -125,7 +126,9 @@ class Test(MachCommandBase):
|
|||
default_level = self._mach_context.settings['test']['level']
|
||||
log = setup_logging('mach-test', log_args, {default_format: sys.stdout},
|
||||
{'level': default_level})
|
||||
log.handlers[0].formatter.inner.summary_on_shutdown = True
|
||||
for handler in log.handlers:
|
||||
if isinstance(handler, StreamHandler):
|
||||
handler.formatter.inner.summary_on_shutdown = True
|
||||
|
||||
status = None
|
||||
for suite_name in run_suites:
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче