Merge mozilla-central to mozilla-inbound. a=merge CLOSED TREE

This commit is contained in:
Ciure Andrei 2018-02-03 00:15:11 +02:00
commit 6c09be0569
50 changed files with 549 additions and 531 deletions

View File

@ -601,6 +601,10 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="1"/>
</emItem>
<emItem blockID="2104a522-bb2f-4b04-ad0d-b0c571644552" id="{ed352072-ddf0-4cb4-9cb6-d8aa3741c2de}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>
</emItem>
<emItem blockID="510bbd9b-b883-4837-90ab-8e353e27e1be" id="{3B4DE07A-DE43-4DBC-873F-05835FF67DCE}">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3"/>

View File

@ -37,8 +37,6 @@ ChromeUtils.import("resource://gre/modules/AsyncShutdown.jsm");
ChromeUtils.defineModuleGetter(this, "console",
"resource://gre/modules/Console.jsm");
ChromeUtils.defineModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
ChromeUtils.defineModuleGetter(this, "RunState",
"resource:///modules/sessionstore/RunState.jsm");
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
@ -200,14 +198,17 @@ var SessionFileInternal = {
failures: 0
},
// Resolved once initialization is complete.
// The promise never rejects.
_deferredInitialized: PromiseUtils.defer(),
// `true` once we have started initialization, i.e. once something
// has been scheduled that will eventually resolve `_deferredInitialized`.
// `true` once we have started initialization of the worker.
_initializationStarted: false,
// A string that will be set to the session file name part that was read from
// disk. It will be available _after_ a session file read() is done.
_readOrigin: null,
// `true` if the old, uncompressed, file format was used to read from disk, as
// a fallback mechanism.
_usingOldExtension: false,
// The ID of the latest version of Gecko for which we have an upgrade backup
// or |undefined| if no upgrade backup was ever written.
get latestUpgradeBackupID() {
@ -221,6 +222,7 @@ var SessionFileInternal = {
async _readInternal(useOldExtension) {
let result;
let noFilesFound = true;
this._usingOldExtension = useOldExtension;
// Attempt to load by order of priority from the various backups
for (let key of this.Paths.loadOrder) {
@ -285,8 +287,6 @@ var SessionFileInternal = {
// Find the correct session file, read it and setup the worker.
async read() {
this._initializationStarted = true;
// Load session files with lz4 compression.
let {result, noFilesFound} = await this._readInternal(false);
if (!result) {
@ -310,39 +310,55 @@ var SessionFileInternal = {
useOldExtension: false
};
}
this._readOrigin = result.origin;
result.noFilesFound = noFilesFound;
// Initialize the worker (in the background) to let it handle backups and also
// as a workaround for bug 964531.
let promiseInitialized = SessionWorker.post("init", [result.origin, result.useOldExtension, this.Paths, {
maxUpgradeBackups: Services.prefs.getIntPref(PREF_MAX_UPGRADE_BACKUPS, 3),
maxSerializeBack: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_BACK, 10),
maxSerializeForward: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_FWD, -1)
}]);
promiseInitialized.catch(err => {
// Ensure that we report errors but that they do not stop us.
Promise.reject(err);
}).then(() => this._deferredInitialized.resolve());
this._initWorker();
return result;
},
// Post a message to the worker, making sure that it has been initialized
// first.
async _postToWorker(...args) {
if (!this._initializationStarted) {
// Initializing the worker is somewhat complex, as proper handling of
// backups requires us to first read and check the session. Consequently,
// the only way to initialize the worker is to first call `this.read()`.
// Initialize the worker in the background.
// Since this called _before_ any other messages are posted to the worker (see
// `_postToWorker()`), we know that this initialization process will be completed
// on time.
// Thus, effectively, this blocks callees on its completion.
// In case of a worker crash/ shutdown during its initialization phase,
// `_checkWorkerHealth()` will detect it and flip the `_initializationStarted`
// property back to `false`. This means that we'll respawn the worker upon the
// next request, followed by the initialization sequence here. In other words;
// exactly the same procedure as when the worker crashed/ shut down 'regularly'.
//
// This will never throw an error.
_initWorker() {
return new Promise(resolve => {
if (this._initializationStarted) {
resolve();
return;
}
// The call to `this.read()` causes background initialization of the worker.
// Initialization will be complete once `this._deferredInitialized.promise`
// resolves.
this.read();
}
await this._deferredInitialized.promise;
if (!this._readOrigin) {
throw new Error("_initWorker called too early! Please read the session file from disk first.");
}
this._initializationStarted = true;
SessionWorker.post("init", [this._readOrigin, this._usingOldExtension, this.Paths, {
maxUpgradeBackups: Services.prefs.getIntPref(PREF_MAX_UPGRADE_BACKUPS, 3),
maxSerializeBack: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_BACK, 10),
maxSerializeForward: Services.prefs.getIntPref(PREF_MAX_SERIALIZE_FWD, -1)
}]).catch(err => {
// Ensure that we report errors but that they do not stop us.
Promise.reject(err);
}).then(resolve);
});
},
// Post a message to the worker, making sure that it has been initialized first.
async _postToWorker(...args) {
await this._initWorker();
return SessionWorker.post(...args);
},
@ -355,6 +371,10 @@ var SessionFileInternal = {
_checkWorkerHealth() {
if (this._workerHealth.failures >= kMaxWriteFailures) {
SessionWorker.terminate();
// Flag as not-initialized, to ensure that the worker state init is performed
// upon the next request.
this._initializationStarted = false;
// Reset the counter and report to telemetry.
this._workerHealth.failures = 0;
Telemetry.scalarAdd("browser.session.restore.worker_restart_count", 1);
}
@ -431,7 +451,11 @@ var SessionFileInternal = {
},
wipe() {
return this._postToWorker("wipe");
return this._postToWorker("wipe").then(() => {
// After a wipe, we need to make sure to re-initialize upon the next read(),
// because the state variables as sent to the worker have changed.
this._initializationStarted = false;
});
},
_recordTelemetry(telemetry) {

View File

@ -22,6 +22,11 @@ function promiseRead(path) {
return File.read(path, {encoding: "utf-8", compression: "lz4"});
}
async function reInitSessionFile() {
await SessionFile.wipe();
await SessionFile.read();
}
add_task(async function init() {
// Make sure that we are not racing with SessionSaver's time based
// saves.
@ -40,8 +45,7 @@ add_task(async function test_creation() {
await File.writeAtomic(OLD_BACKUP, "sessionstore.bak");
await File.writeAtomic(OLD_UPGRADE_BACKUP, "sessionstore upgrade backup");
await SessionFile.wipe();
await SessionFile.read(); // Reinitializes SessionFile
await reInitSessionFile();
// Ensure none of the sessionstore files and backups exists
for (let k of Paths.loadOrder) {
@ -63,7 +67,8 @@ add_task(async function test_creation() {
ok((await File.exists(Paths.recovery)), "After write, recovery sessionstore file exists again");
ok(!(await File.exists(Paths.recoveryBackup)), "After write, recoveryBackup sessionstore doesn't exist");
ok((await promiseRead(Paths.recovery)).includes(URL), "Recovery sessionstore file contains the required tab");
ok(!(await File.exists(Paths.clean)), "After first write, clean shutdown sessionstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.clean)), "After first write, clean shutdown " +
"sessionstore doesn't exist, since we haven't shutdown yet");
// Open a second tab, save session, ensure that the correct files exist.
info("Testing situation after a second write");
@ -79,17 +84,20 @@ add_task(async function test_creation() {
let backup = await promiseRead(Paths.recoveryBackup);
ok(!backup.includes(URL2), "Recovery backup doesn't contain the latest url");
ok(backup.includes(URL), "Recovery backup contains the original url");
ok(!(await File.exists(Paths.clean)), "After first write, clean shutdown sessinstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.clean)), "After first write, clean shutdown " +
"sessionstore doesn't exist, since we haven't shutdown yet");
info("Reinitialize, ensure that we haven't leaked sensitive files");
await SessionFile.read(); // Reinitializes SessionFile
await SessionSaver.run();
ok(!(await File.exists(Paths.clean)), "After second write, clean shutdown sessonstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.upgradeBackup)), "After second write, clean shutdwn sessionstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.nextUpgradeBackup)), "After second write, clean sutdown sessionstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.clean)), "After second write, clean shutdown " +
"sessionstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.upgradeBackup)), "After second write, clean " +
"shutdown sessionstore doesn't exist, since we haven't shutdown yet");
ok(!(await File.exists(Paths.nextUpgradeBackup)), "After second write, clean " +
"shutdown sessionstore doesn't exist, since we haven't shutdown yet");
gBrowser.removeTab(tab);
await SessionFile.wipe();
});
var promiseSource = async function(name) {
@ -107,8 +115,7 @@ var promiseSource = async function(name) {
};
add_task(async function test_recovery() {
// Remove all files.
await SessionFile.wipe();
await reInitSessionFile();
info("Attempting to recover from the recovery file");
// Create Paths.recovery, ensure that we can recover from it.
@ -116,7 +123,6 @@ add_task(async function test_recovery() {
await File.makeDir(Paths.backups);
await File.writeAtomic(Paths.recovery, SOURCE, {encoding: "utf-8", compression: "lz4"});
is((await SessionFile.read()).source, SOURCE, "Recovered the correct source from the recovery file");
await SessionFile.wipe();
info("Corrupting recovery file, attempting to recover from recovery backup");
SOURCE = await promiseSource("Paths.recoveryBackup");
@ -124,7 +130,6 @@ add_task(async function test_recovery() {
await File.writeAtomic(Paths.recoveryBackup, SOURCE, {encoding: "utf-8", compression: "lz4"});
await File.writeAtomic(Paths.recovery, "<Invalid JSON>", {encoding: "utf-8", compression: "lz4"});
is((await SessionFile.read()).source, SOURCE, "Recovered the correct source from the recovery file");
await SessionFile.wipe();
});
add_task(async function test_recovery_inaccessible() {
@ -133,6 +138,7 @@ add_task(async function test_recovery_inaccessible() {
return;
}
await reInitSessionFile();
info("Making recovery file inaccessible, attempting to recover from recovery backup");
let SOURCE_RECOVERY = await promiseSource("Paths.recovery");
let SOURCE = await promiseSource("Paths.recoveryBackup");
@ -148,12 +154,13 @@ add_task(async function test_recovery_inaccessible() {
});
add_task(async function test_clean() {
await SessionFile.wipe();
await reInitSessionFile();
let SOURCE = await promiseSource("Paths.clean");
await File.writeAtomic(Paths.clean, SOURCE, {encoding: "utf-8", compression: "lz4"});
await SessionFile.read();
await SessionSaver.run();
is((await promiseRead(Paths.cleanBackup)), SOURCE, "After first read/write, clean shutdown file has been moved to cleanBackup");
is((await promiseRead(Paths.cleanBackup)), SOURCE, "After first read/write, " +
"clean shutdown file has been moved to cleanBackup");
});
@ -180,6 +187,7 @@ add_task(async function test_version() {
* Tests fallback to previous backups if format version is unknown.
*/
add_task(async function test_version_fallback() {
await reInitSessionFile();
info("Preparing data, making sure that it has a version number");
let SOURCE = await promiseSource("Paths.clean");
let BACKUP_SOURCE = await promiseSource("Paths.cleanBackup");
@ -205,5 +213,5 @@ add_task(async function test_version_fallback() {
});
add_task(async function cleanup() {
await SessionFile.wipe();
await reInitSessionFile();
});

View File

@ -14,7 +14,7 @@ const PREF_MAX_UPGRADE_BACKUPS = "browser.sessionstore.upgradeBackup.maxUpgradeB
* build where the last backup was created and creating arbitrary JSON data
* for a new backup.
*/
var prepareTest = async function() {
function prepareTest() {
let result = {};
result.buildID = Services.appinfo.platformBuildID;
@ -22,12 +22,12 @@ var prepareTest = async function() {
result.contents = JSON.stringify({"browser_upgrade_backup.js": Math.random()});
return result;
};
}
/**
* Retrieves all upgrade backups and returns them in an array.
*/
var getUpgradeBackups = async function() {
async function getUpgradeBackups() {
let iterator;
let backups = [];
@ -50,17 +50,17 @@ var getUpgradeBackups = async function() {
// return results
return backups;
};
}
add_task(async function init() {
// Wait until initialization is complete
await SessionStore.promiseInitialized;
await SessionFile.wipe();
});
add_task(async function test_upgrade_backup() {
let test = await prepareTest();
let test = prepareTest();
info("Let's check if we create an upgrade backup");
await SessionFile.wipe();
await OS.File.writeAtomic(Paths.clean, test.contents, {encoding: "utf-8", compression: "lz4"});
await SessionFile.read(); // First call to read() initializes the SessionWorker
await SessionFile.write(""); // First call to write() triggers the backup
@ -82,9 +82,11 @@ add_task(async function test_upgrade_backup() {
});
add_task(async function test_upgrade_backup_removal() {
let test = await prepareTest();
let test = prepareTest();
let maxUpgradeBackups = Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3);
info("Let's see if we remove backups if there are too many");
await SessionFile.wipe();
await OS.File.makeDir(Paths.backups);
await OS.File.writeAtomic(Paths.clean, test.contents, {encoding: "utf-8", compression: "lz4"});
// if the nextUpgradeBackup already exists (from another test), remove it

View File

@ -28,13 +28,26 @@ updateAppInfo({
platformVersion: "",
});
add_task(async function setup() {
let source = do_get_file("data/sessionstore_valid.js");
source.copyTo(profd, "sessionstore.js");
var gSourceHandle;
async function prepareWithLimit(back, fwd) {
await SessionFile.wipe();
if (!gSourceHandle) {
gSourceHandle = do_get_file("data/sessionstore_valid.js");
}
gSourceHandle.copyTo(profd, "sessionstore.js");
await writeCompressedFile(Paths.clean.replace("jsonlz4", "js"), Paths.clean);
Services.prefs.setIntPref("browser.sessionstore.max_serialize_back", back);
Services.prefs.setIntPref("browser.sessionstore.max_serialize_forward", fwd);
// Finish SessionFile initialization.
await SessionFile.read();
}
add_task(async function setup() {
await SessionFile.read();
// Reset prefs on cleanup.
registerCleanupFunction(() => {
@ -54,12 +67,6 @@ function createSessionState(index) {
return {windows: [{tabs: [tabState]}]};
}
async function setMaxBackForward(back, fwd) {
Services.prefs.setIntPref("browser.sessionstore.max_serialize_back", back);
Services.prefs.setIntPref("browser.sessionstore.max_serialize_forward", fwd);
await SessionFile.read();
}
async function writeAndParse(state, path, options = {}) {
await SessionWorker.post("write", [state, options]);
return JSON.parse(await File.read(path, {encoding: "utf-8", compression: "lz4"}));
@ -69,7 +76,7 @@ add_task(async function test_shistory_cap_none() {
let state = createSessionState(5);
// Don't limit the number of shistory entries.
await setMaxBackForward(-1, -1);
await prepareWithLimit(-1, -1);
// Check that no caps are applied.
let diskState = await writeAndParse(state, Paths.clean, {isFinalWrite: true});
@ -78,7 +85,7 @@ add_task(async function test_shistory_cap_none() {
add_task(async function test_shistory_cap_middle() {
let state = createSessionState(5);
await setMaxBackForward(2, 3);
await prepareWithLimit(2, 3);
// Cap is only applied on clean shutdown.
let diskState = await writeAndParse(state, Paths.recovery);
@ -95,7 +102,7 @@ add_task(async function test_shistory_cap_middle() {
add_task(async function test_shistory_cap_lower_bound() {
let state = createSessionState(1);
await setMaxBackForward(5, 5);
await prepareWithLimit(5, 5);
// Cap is only applied on clean shutdown.
let diskState = await writeAndParse(state, Paths.recovery);
@ -110,7 +117,7 @@ add_task(async function test_shistory_cap_lower_bound() {
add_task(async function test_shistory_cap_upper_bound() {
let state = createSessionState(MAX_ENTRIES);
await setMaxBackForward(5, 5);
await prepareWithLimit(5, 5);
// Cap is only applied on clean shutdown.
let diskState = await writeAndParse(state, Paths.recovery);
@ -124,3 +131,8 @@ add_task(async function test_shistory_cap_upper_bound() {
tabState.index = 6;
Assert.deepEqual(state, diskState, "cap applied");
});
add_task(async function cleanup() {
await SessionFile.wipe();
await SessionFile.read();
});

View File

@ -385,6 +385,11 @@ notification[value="translation"] menulist > .menulist-dropmarker {
%include ../shared/autocomplete.inc.css
%include ../shared/urlbar-autocomplete.inc.css
:root {
--urlbar-popup-url-color: -moz-nativehyperlinktext;
--urlbar-popup-action-color: -moz-nativehyperlinktext;
}
#PopupAutoComplete > richlistbox > richlistitem[originaltype~="datalist-first"] {
border-top: 1px solid ThreeDShadow;
}
@ -400,79 +405,6 @@ notification[value="translation"] menulist > .menulist-dropmarker {
font-size: 0.9em;
}
html|span.ac-tag {
background-color: MenuText;
color: Menu;
border-radius: 2px;
border: 1px solid transparent;
padding: 0 1px;
}
.ac-separator:not([selected=true]),
.ac-url:not([selected=true]),
.ac-action:not([selected=true]) {
color: -moz-nativehyperlinktext;
}
.ac-tags-text[selected] > html|span.ac-tag {
background-color: HighlightText;
color: Highlight;
}
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
.ac-type-icon[type=bookmark] {
list-style-image: url("chrome://browser/skin/bookmark.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=bookmark][selected][current] {
fill: white;
}
.ac-type-icon[type=keyword],
.ac-site-icon[type=searchengine] {
list-style-image: url(chrome://browser/skin/search-glass.svg);
-moz-context-properties: fill;
fill: GrayText;
}
.ac-type-icon[type=keyword][selected],
.ac-site-icon[type=searchengine][selected] {
fill: highlighttext;
}
.ac-type-icon[type=switchtab],
.ac-type-icon[type=remotetab] {
list-style-image: url("chrome://browser/skin/urlbar-tab.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=switchtab][selected],
.ac-type-icon[type=remotetab][selected] {
fill: white;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}
.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment) {
color: GrayText;
font-size: smaller;
}
.autocomplete-treebody::-moz-tree-cell(suggesthint) {
border-top: 1px solid GrayText;
}
/* Bookmarking panel */
#editBookmarkPanelStarIcon {
list-style-image: url("chrome://browser/skin/places/starred48.png");

View File

@ -331,6 +331,11 @@ html|input.urlbar-input {
%include ../shared/autocomplete.inc.css
%include ../shared/urlbar-autocomplete.inc.css
:root {
--urlbar-popup-url-color: hsl(210, 77%, 47%);
--urlbar-popup-action-color: hsl(178, 100%, 28%);
}
/* Give an extra margin top to align the top of the awesomebar with the
* bottom of the nav bar, OSX calculates the panel position with an missing
* 1px - https://bugzilla.mozilla.org/show_bug.cgi?id=1406353
@ -354,86 +359,6 @@ html|input.urlbar-input {
font-size: 12px;
}
html|span.ac-tag {
background-color: hsl(216, 0%, 88%);
color: hsl(0, 0%, 0%);
border-radius: 2px;
border: 1px solid transparent;
padding: 0 1px;
}
.ac-separator:not([selected=true]) {
color: hsl(0, 0%, 50%);
}
.ac-url:not([selected=true]) {
color: hsl(210, 77%, 47%);
}
.ac-action:not([selected=true]) {
color: hsl(178, 100%, 28%);
}
.ac-tags-text[selected] > html|span.ac-tag {
background-color: hsl(0, 0%, 100%);
color: hsl(210, 80%, 40%);
}
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
.ac-type-icon[type=bookmark] {
list-style-image: url("chrome://browser/skin/bookmark.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=bookmark][selected][current] {
fill: white;
}
.ac-type-icon[type=keyword],
.ac-site-icon[type=searchengine] {
list-style-image: url(chrome://browser/skin/search-glass.svg);
-moz-context-properties: fill;
fill: GrayText;
}
.ac-type-icon[type=keyword][selected],
.ac-site-icon[type=searchengine][selected] {
fill: highlighttext;
}
.ac-type-icon[type=switchtab],
.ac-type-icon[type=remotetab] {
list-style-image: url("chrome://browser/skin/urlbar-tab.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=switchtab][selected],
.ac-type-icon[type=remotetab][selected] {
fill: white;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}
.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
{
color: GrayText;
font-size: smaller;
}
.autocomplete-treebody::-moz-tree-cell(suggesthint) {
border-top: 1px solid GrayText;
}
#BMB_bookmarksPopup[side="top"],
#BMB_bookmarksPopup[side="bottom"] {
margin-left: -26px;

View File

@ -28,6 +28,20 @@
padding: 0;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}
.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment) {
color: GrayText;
font-size: smaller;
}
.autocomplete-treebody::-moz-tree-cell(suggesthint) {
border-top: 1px solid GrayText;
}
/* Popup states */
.autocomplete-richlistitem:hover,

View File

@ -30,12 +30,22 @@
:root:not([uidensity=compact]):not([chromehidden~="toolbar"]) #PanelUI-button {
margin-inline-start: 3px;
border-inline-start: 1px solid;
border-image: linear-gradient(transparent 4px, rgba(0,0,0,.1) 4px, rgba(0,0,0,.1) calc(100% - 4px), transparent calc(100% - 4px));
border-image: linear-gradient(
transparent 4px,
var(--lwt-toolbar-vertical-separator, rgba(0,0,0,.1)) 4px,
var(--lwt-toolbar-vertical-separator, rgba(0,0,0,.1)) calc(100% - 4px),
transparent calc(100% - 4px)
);
border-image-slice: 1;
}
:root:not([uidensity=compact]):not([chromehidden~="toolbar"]) #nav-bar[brighttext] > #PanelUI-button {
border-image-source: linear-gradient(transparent 4px, rgba(100%,100%,100%,.2) 4px, rgba(100%,100%,100%,.2) calc(100% - 4px), transparent calc(100% - 4px));
border-image-source: linear-gradient(
transparent 4px,
var(--lwt-toolbar-vertical-separator, rgba(255,255,255,.2)) 4px,
var(--lwt-toolbar-vertical-separator, rgba(255,255,255,.2)) calc(100% - 4px),
transparent calc(100% - 4px)
);
}
#PanelUI-menu-button[badge-status] > .toolbarbutton-badge-stack > .toolbarbutton-badge {

View File

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

View File

@ -168,7 +168,7 @@
skin/classic/browser/stop.svg (../shared/icons/stop.svg)
skin/classic/browser/stop-to-reload.svg (../shared/icons/stop-to-reload.svg)
skin/classic/browser/sync.svg (../shared/icons/sync.svg)
skin/classic/browser/synced-tabs.svg (../shared/icons/synced-tabs.svg)
skin/classic/browser/tab.svg (../shared/icons/tab.svg)
skin/classic/browser/bookmarks-toolbar.svg (../shared/icons/bookmarks-toolbar.svg)
skin/classic/browser/webIDE.svg (../shared/icons/webIDE.svg)
skin/classic/browser/window.svg (../shared/icons/window.svg)
@ -231,4 +231,3 @@
skin/classic/browser/privatebrowsing/private-browsing.svg (../shared/privatebrowsing/private-browsing.svg)
skin/classic/browser/privatebrowsing/tracking-protection-off.svg (../shared/privatebrowsing/tracking-protection-off.svg)
skin/classic/browser/privatebrowsing/tracking-protection.svg (../shared/privatebrowsing/tracking-protection.svg)
skin/classic/browser/urlbar-tab.svg (../shared/urlbar-tab.svg)

View File

@ -75,7 +75,7 @@
#appMenuRecentlyClosedTabs,
#appMenu-library-remotetabs-button {
list-style-image: url("chrome://browser/skin/synced-tabs.svg");
list-style-image: url("chrome://browser/skin/tab.svg");
}
#PanelUI-remotetabs-syncnow {

View File

@ -62,7 +62,7 @@
}
.search-panel-input-value {
color: -moz-fieldtext;
color: var(--autocomplete-popup-color);
}
.search-panel-one-offs {
@ -200,10 +200,19 @@
list-style-image: none;
}
.search-panel-tree > .autocomplete-treebody,
.search-panel-tree > .autocomplete-treebody::-moz-tree-row {
background: none;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
border-top: none !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
color: var(--autocomplete-popup-color) !important;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
padding-inline-start: 2px;
padding-inline-end: 2px;
@ -214,11 +223,12 @@
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
list-style-image: url("chrome://browser/skin/history.svg");
-moz-context-properties: fill;
fill: graytext;
fill: currentColor;
fill-opacity: 0.6;
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
fill: HighlightText;
fill-opacity: 1;
}
.search-setting-button {

View File

@ -155,7 +155,7 @@ toolbarseparator + #sidebar-extensions-separator {
#sidebar-switcher-tabs > .toolbarbutton-icon,
#sidebar-box[sidebarcommand="viewTabsSidebar"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
list-style-image: url(chrome://browser/skin/synced-tabs.svg);
list-style-image: url(chrome://browser/skin/tab.svg);
-moz-context-properties: fill;
fill: currentColor;
opacity: 0.8;

View File

@ -208,7 +208,7 @@ toolbar[brighttext] {
}
#sync-button {
list-style-image: url("chrome://browser/skin/synced-tabs.svg");
list-style-image: url("chrome://browser/skin/tab.svg");
}
#feed-button {

View File

@ -4,12 +4,27 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
:root {
--autocomplete-popup-background: -moz-field;
--autocomplete-popup-color: -moz-fieldtext;
--autocomplete-popup-highlight-background: Highlight;
--autocomplete-popup-highlight-color: HighlightText;
}
#treecolAutoCompleteImage {
max-width: 36px;
}
#PopupAutoCompleteRichResult,
#PopupSearchAutoComplete {
background: var(--autocomplete-popup-background);
color: var(--autocomplete-popup-color);
}
#PopupAutoCompleteRichResult .autocomplete-richlistbox {
padding: 4px 3px;
background: transparent;
color: inherit;
}
#PopupAutoCompleteRichResult .autocomplete-richlistitem {
@ -24,6 +39,74 @@
border-inline-end: var(--item-padding-end) solid transparent;
}
#PopupAutoCompleteRichResult .autocomplete-richlistitem[selected],
.search-panel-tree > .autocomplete-treebody::-moz-tree-row(selected) {
background: var(--autocomplete-popup-highlight-background);
color: var(--autocomplete-popup-highlight-color);
}
.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text(selected) {
color: var(--autocomplete-popup-highlight-color) !important;
}
:root[uidensity=touch] #PopupAutoCompleteRichResult .autocomplete-richlistitem {
min-height: 40px;
}
/* Awesomebar popup items */
.ac-separator:not([selected=true]) {
color: GrayText;
}
.ac-url:not([selected=true]) {
color: var(--urlbar-popup-url-color);
}
.ac-action:not([selected=true]) {
color: var(--urlbar-popup-action-color);
}
html|span.ac-tag {
background-color: var(--arrowpanel-dimmed);
border-radius: 2px;
border: 1px solid var(--panel-separator-color);
padding: 0 1px;
}
.ac-tags-text[selected] > html|span.ac-tag {
background-color: var(--autocomplete-popup-highlight-color);
color: var(--autocomplete-popup-highlight-background);
}
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
.ac-site-icon,
.ac-type-icon {
-moz-context-properties: fill, fill-opacity;
fill: currentColor;
fill-opacity: 0.6;
}
.ac-site-icon[selected],
.ac-type-icon[selected] {
fill-opacity: 1;
}
.ac-type-icon[type=bookmark] {
list-style-image: url("chrome://browser/skin/bookmark.svg");
}
.ac-type-icon[type=keyword],
.ac-site-icon[type=searchengine] {
list-style-image: url(chrome://browser/skin/search-glass.svg);
}
.ac-type-icon[type=switchtab],
.ac-type-icon[type=remotetab] {
list-style-image: url("chrome://browser/skin/tab.svg");
}

View File

@ -1,6 +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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M15 11h-1V5a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v6H1a1 1 0 0 0 0 2h14a1 1 0 1 0 0-2z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 421 B

View File

@ -609,117 +609,24 @@ html|*.urlbar-input:-moz-lwtheme::placeholder,
font-size: 12px;
}
html|span.ac-tag {
border-radius: 2px;
border: 1px solid transparent;
padding: 0 1px;
}
.ac-separator,
.ac-url,
.ac-action {
font-size: 12px;
}
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
@media (-moz-windows-default-theme) {
.ac-title:not([selected=true]) {
color: hsl(0, 0%, 0%);
}
.ac-separator:not([selected=true]) {
color: hsl(0, 0%, 50%);
}
.ac-url:not([selected=true]) {
color: hsl(210, 77%, 47%);
}
.ac-action:not([selected=true]) {
color: hsl(178, 100%, 28%);
}
html|span.ac-tag {
background-color: hsl(216, 0%, 88%);
color: hsl(0, 0%, 0%);
}
.ac-tags-text[selected] > html|span.ac-tag {
background-color: hsl(0, 0%, 100%);
color: hsl(210, 80%, 40%);
:root {
--urlbar-popup-url-color: hsl(210, 77%, 47%);
--urlbar-popup-action-color: hsl(178, 100%, 28%);
}
}
@media (-moz-windows-default-theme: 0) {
.ac-separator:not([selected=true]),
.ac-url:not([selected=true]),
.ac-action:not([selected=true]) {
color: -moz-nativehyperlinktext;
:root {
--urlbar-popup-url-color: -moz-nativehyperlinktext;
--urlbar-popup-action-color: -moz-nativehyperlinktext;
}
html|span.ac-tag {
background-color: -moz-FieldText;
color: -moz-Field;
}
.ac-tags-text[selected] > html|span.ac-tag {
background-color: HighlightText;
color: Highlight;
}
}
.ac-type-icon[type=bookmark] {
list-style-image: url("chrome://browser/skin/bookmark.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=bookmark][selected][current] {
fill: white;
}
.ac-type-icon[type=keyword],
.ac-site-icon[type=searchengine] {
list-style-image: url(chrome://browser/skin/search-glass.svg);
-moz-context-properties: fill;
fill: GrayText;
}
.ac-type-icon[type=keyword][selected],
.ac-site-icon[type=searchengine][selected] {
fill: highlighttext;
}
.ac-type-icon[type=switchtab],
.ac-type-icon[type=remotetab] {
list-style-image: url("chrome://browser/skin/urlbar-tab.svg");
-moz-context-properties: fill;
fill: #b2b2b2;
}
.ac-type-icon[type=switchtab][selected],
.ac-type-icon[type=remotetab][selected] {
fill: white;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: GrayText;
}
.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
{
color: GrayText;
font-size: smaller;
}
.autocomplete-treebody::-moz-tree-cell(suggesthint) {
border-top: 1px solid GrayText;
}
/* bookmarking panel */

View File

@ -283,12 +283,11 @@ CustomElementRegistry::~CustomElementRegistry()
}
CustomElementDefinition*
CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
CustomElementRegistry::LookupCustomElementDefinition(nsAtom* aNameAtom,
nsAtom* aTypeAtom) const
{
RefPtr<nsAtom> localNameAtom = NS_Atomize(aLocalName);
CustomElementDefinition* data = mCustomDefinitions.GetWeak(aTypeAtom);
if (data && data->mLocalName == localNameAtom) {
if (data && data->mLocalName == aNameAtom) {
return data;
}

View File

@ -376,7 +376,7 @@ public:
* https://html.spec.whatwg.org/#look-up-a-custom-element-definition
*/
CustomElementDefinition* LookupCustomElementDefinition(
const nsAString& aLocalName, nsAtom* aTypeAtom) const;
nsAtom* aNameAtom, nsAtom* aTypeAtom) const;
CustomElementDefinition* LookupCustomElementDefinition(
JSContext* aCx, JSObject *aConstructor) const;

View File

@ -26,11 +26,14 @@ struct MiscContainer final
// Note eStringBase and eAtomBase is used also to handle the type of
// mStringBits.
//
// Note that we use a relaxed atomic here so that we can use Compare-And-Swap
// Note that we use an atomic here so that we can use Compare-And-Swap
// to cache the serialization during the parallel servo traversal. This case
// (which happens when the main thread is blocked) is the only case where
// mStringBits is mutated off-main-thread.
mozilla::Atomic<uintptr_t, mozilla::Relaxed> mStringBits;
// mStringBits is mutated off-main-thread. The Atomic needs to be
// ReleaseAcquire so that the pointer to the serialization does not become
// observable to other threads before the initialization of the pointed-to
// memory is also observable.
mozilla::Atomic<uintptr_t, mozilla::ReleaseAcquire> mStringBits;
union {
struct {
union {

View File

@ -10043,9 +10043,11 @@ nsContentUtils::TryToUpgradeElement(Element* aElement)
NodeInfo* nodeInfo = aElement->NodeInfo();
RefPtr<nsAtom> typeAtom =
aElement->GetCustomElementData()->GetCustomElementType();
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(),
nodeInfo->NameAtom(),
nodeInfo->NamespaceID(),
typeAtom);
if (definition) {
@ -10129,9 +10131,10 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a
CustomElementDefinition* definition = aDefinition;
if (CustomElementRegistry::IsCustomElementEnabled() && isCustomElement &&
!definition) {
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(),
nodeInfo->NameAtom(),
nodeInfo->NamespaceID(),
typeAtom);
}
@ -10243,7 +10246,7 @@ nsContentUtils::NewXULOrHTMLElement(Element** aResult, mozilla::dom::NodeInfo* a
/* static */ CustomElementDefinition*
nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
const nsAString& aLocalName,
nsAtom* aNameAtom,
uint32_t aNameSpaceID,
nsAtom* aTypeAtom)
{
@ -10265,7 +10268,7 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
return nullptr;
}
return registry->LookupCustomElementDefinition(aLocalName, aTypeAtom);
return registry->LookupCustomElementDefinition(aNameAtom, aTypeAtom);
}
/* static */ void

View File

@ -3057,7 +3057,7 @@ public:
*/
static mozilla::dom::CustomElementDefinition*
LookupCustomElementDefinition(nsIDocument* aDoc,
const nsAString& aLocalName,
nsAtom* aNameAtom,
uint32_t aNameSpaceID,
nsAtom* aTypeAtom);

View File

@ -512,9 +512,11 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
// cloned.
RefPtr<nsAtom> typeAtom = extension.IsEmpty() ? tagAtom : NS_Atomize(extension);
cloneElem->SetCustomElementData(new CustomElementData(typeAtom));
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
CustomElementDefinition* definition =
nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
nodeInfo->LocalName(),
nodeInfo->NameAtom(),
nodeInfo->NamespaceID(),
typeAtom);
if (definition) {

View File

@ -41,7 +41,7 @@ typedef struct {
guint source_id;
int numAxes;
int numButtons;
char idstring[128];
char idstring[256];
char devpath[PATH_MAX];
} Gamepad;

View File

@ -46,7 +46,8 @@ var statsExpectedByType = {
"transportId", "localCandidateId", "remoteCandidateId", "state",
"priority", "nominated", "writable", "readable",
"bytesSent", "bytesReceived",
"lastPacketSentTimestamp", "lastPacketReceivedTimestamp",],
"lastPacketSentTimestamp", "lastPacketReceivedTimestamp",
"componentId",],
optional: ["selected",],
unimplemented: ["totalRoundTripTime", "currentRoundTripTime",
"availableOutgoingBitrate", "availableIncomingBitrate",

View File

@ -183,6 +183,7 @@ struct ParamTraits<mozilla::dom::RTCIceCandidatePairStats>
WriteParam(aMsg, aParam.mReadable);
WriteParam(aMsg, aParam.mRemoteCandidateId);
WriteParam(aMsg, aParam.mSelected);
WriteParam(aMsg, aParam.mComponentId);
WriteParam(aMsg, aParam.mState);
WriteParam(aMsg, aParam.mBytesSent);
WriteParam(aMsg, aParam.mBytesReceived);
@ -201,6 +202,7 @@ struct ParamTraits<mozilla::dom::RTCIceCandidatePairStats>
!ReadParam(aMsg, aIter, &(aResult->mReadable)) ||
!ReadParam(aMsg, aIter, &(aResult->mRemoteCandidateId)) ||
!ReadParam(aMsg, aIter, &(aResult->mSelected)) ||
!ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
!ReadParam(aMsg, aIter, &(aResult->mState)) ||
!ReadParam(aMsg, aIter, &(aResult->mBytesSent)) ||
!ReadParam(aMsg, aIter, &(aResult->mBytesReceived)) ||

View File

@ -138,6 +138,8 @@ dictionary RTCIceCandidatePairStats : RTCStats {
DOMHighResTimeStamp lastPacketSentTimestamp;
DOMHighResTimeStamp lastPacketReceivedTimestamp;
boolean selected;
[ChromeOnly]
unsigned long componentId; // moz
};
enum RTCStatsIceCandidateType {

View File

@ -9,11 +9,20 @@
* @returns {Promise}
*/
function documentReady() {
if (document.contentType === 'application/vnd.mozilla.xul+xml') {
// XUL
return new Promise(
resolve => document.addEventListener(
'MozBeforeInitialXULLayout', resolve, { once: true }
)
);
}
// HTML
const rs = document.readyState;
if (rs === 'interactive' || rs === 'completed') {
return Promise.resolve();
}
return new Promise(
resolve => document.addEventListener(
'readystatechange', resolve, { once: true }

View File

@ -404,6 +404,8 @@ nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
pair.priority = p1->priority;
pair.nominated = p1->peer_nominated || p1->nominated;
pair.component_id = p1->remote->component->component_id;
// As discussed with drno: a component's can_send field (set to true
// by ICE consent) is a very close approximation for writable and
// readable. Note: the component for the local candidate never has

View File

@ -126,6 +126,7 @@ struct NrIceCandidatePair {
NrIceCandidate remote;
// TODO(bcampen@mozilla.com): Is it important to put the foundation in here?
std::string codeword;
uint64_t component_id;
// for RTCIceCandidatePairStats
uint64_t bytes_sent;

View File

@ -3412,6 +3412,7 @@ static void RecordIceStats_s(
s.mLastPacketSentTimestamp.Construct(candPair.ms_since_last_send);
s.mLastPacketReceivedTimestamp.Construct(candPair.ms_since_last_recv);
s.mState.Construct(RTCStatsIceCandidatePairState(candPair.state));
s.mComponentId.Construct(candPair.component_id);
report->mIceCandidatePairStats.Value().AppendElement(s, fallible);
}

View File

@ -410,8 +410,9 @@ nsHtml5TreeOperation::CreateHTMLElement(
RefPtr<nsAtom> typeAtom =
(aCreator == NS_NewCustomElement) ? tagAtom : isAtom;
MOZ_ASSERT(nodeInfo->NameAtom()->Equals(nodeInfo->LocalName()));
definition = nsContentUtils::LookupCustomElementDefinition(document,
nodeInfo->LocalName(), nodeInfo->NamespaceID(), typeAtom);
nodeInfo->NameAtom(), nodeInfo->NamespaceID(), typeAtom);
if (definition) {
willExecuteScript = true;

View File

@ -1162,4 +1162,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1525979905534000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1526066279722000);

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1528399093845000);
const PRTime gPreloadListExpirationTime = INT64_C(1528485467104000);
%%
0-1.party, 1
0.me.uk, 1
@ -127,6 +127,7 @@ const PRTime gPreloadListExpirationTime = INT64_C(1528399093845000);
11scc.com, 1
11thstreetcoffee.com, 1
11urss.com, 1
1212873467.rsc.cdn77.org, 1
1218641649.rsc.cdn77.org, 1
123comparer.fr, 1
123djdrop.com, 1
@ -540,7 +541,6 @@ const PRTime gPreloadListExpirationTime = INT64_C(1528399093845000);
91travel.info, 1
92url.com, 1
9449-27a1-22a1-e0d9-4237-dd99-e75e-ac85-2f47-9d34.de, 1
94cs.cn, 0
9500years.com, 1
9617818.com, 1
9617818.net, 1
@ -1410,6 +1410,7 @@ alinasmusicstudio.com, 1
alinode.com, 1
alisonisrealestate.com, 1
alisonlitchfield.com, 1
alistairstowing.com, 1
alisync.com, 1
aliwebstore.com, 1
alix-board.de, 1
@ -1843,7 +1844,6 @@ animaemundi.be, 1
animal-liberation.com, 1
animal-rights.com, 1
animalistic.io, 1
animalnet.de, 0
animalstropic.com, 1
animaltesting.fr, 1
animationsmusicales.ch, 1
@ -2522,6 +2522,7 @@ athlin.de, 1
atigerseye.com, 1
atishchenko.com, 1
atisoft.biz, 1
atisoft.com.tr, 1
atisoft.net, 1
atisoft.net.tr, 1
atisoft.web.tr, 1
@ -2777,7 +2778,6 @@ awin.la, 1
awk.tw, 1
awksolutions.com, 1
awningsaboveus.com, 1
awomaninherprime.com, 1
awsmdev.de, 1
awxg.com, 1
awxg.org, 1
@ -5045,6 +5045,7 @@ buyinginvestmentproperty.com, 1
buyingsellingflorida.com, 1
buyjewel.shop, 1
buymindhack.com, 1
buynowdepot.com, 0
buypapercheap.net, 1
buyplussize.shop, 1
buyprofessional.shop, 1
@ -5069,7 +5070,6 @@ bwilkinson.co.uk, 1
bws16.de, 1
bwwb.nu, 1
bx-n.de, 1
bx-web.com, 1
bxdev.me, 1
bxp40.at, 1
by1896.com, 1
@ -6308,6 +6308,7 @@ cleanbrowsing.org, 1
cleancode.club, 1
cleansewellness.com, 1
cleanstar.org, 1
clear.ml, 1
clearance365.co.uk, 1
clearblueday.co.uk, 1
clearbreezesecuritydoors.com.au, 1
@ -6522,7 +6523,6 @@ coccolebenessere.it, 1
cocinoyo.com, 1
cock.li, 1
cockedey.in, 1
cocker.cc, 0
cockerspanielamericano.com.br, 1
cockerspanielingles.com.br, 1
cocktail-shaken.nl, 1
@ -7737,6 +7737,7 @@ darioturchetti.me, 1
darisni.me, 1
dark-infection.de, 1
dark-vision.cz, 1
darkag.ovh, 1
darkcores.net, 1
darkdestiny.ch, 1
darkengine.io, 1
@ -8341,7 +8342,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
@ -8913,7 +8913,6 @@ dorfbrunnen.eu, 1
doriangirod.ch, 1
dorianharmans.nl, 1
dorianmuthig.com, 1
dormebebe.com.br, 1
dormiu.com, 1
dormiu.com.br, 1
dorquelle.com, 1
@ -9609,6 +9608,7 @@ effishiency.com, 1
effizienta.ch, 1
efflam.net, 1
eft.boutique, 1
egablo.black, 1
egami.ch, 1
eganassociates.com.au, 1
egarden.it, 1
@ -10497,6 +10497,7 @@ etkaddict.com, 1
etoile-usedcars.com, 1
etre-soi.ch, 1
etre-vivant.fr, 1
etrker.com, 1
etudesbibliques.fr, 1
etudesbibliques.net, 1
etudesbibliques.org, 1
@ -11126,6 +11127,7 @@ fengyadi.com, 1
fengyi.tel, 1
fenster-bank.at, 1
fenster-bank.de, 1
fensterbau-mutscheller.de, 1
feras-alhajjaji.com, 1
ferdies.co.za, 1
fergusoncastle.com, 1
@ -11457,6 +11459,7 @@ flipneus.net, 1
fliptable.org, 1
flirt-norden.de, 1
flirtfaces.de, 1
flirtycourts.com, 1
flmortgagebank.com, 1
floaternet.com, 1
flocktofedora.org, 1
@ -11467,7 +11470,6 @@ flood.io, 1
flooringnightmares.com, 1
floort.net, 0
flopix.net, 0
flopy.club, 1
florence.uk.net, 1
florenceapp.co.uk, 1
florent-tatard.fr, 1
@ -12235,7 +12237,6 @@ gambetti.fr, 1
gambit.pro, 1
gambitboard.com, 1
gambitnash.co.uk, 1
gambitnash.com, 1
gambitprint.com, 1
gamblersgaming.eu, 1
game-files.net, 0
@ -12527,7 +12528,6 @@ geoscope.ch, 1
geosphereservices.com, 1
geotab.com, 1
geraintwhite.co.uk, 1
gerald-zojer.com, 1
geraldsonrealty.com, 1
gerardobsd.com, 1
gerardozamudio.mx, 1
@ -12589,7 +12589,6 @@ getitlive.de, 1
getitpeople.com, 1
getmango.com, 1
getmdl.io, 1
getmerch.eu, 1
getnib.com, 1
getnikola.com, 1
geto.ml, 1
@ -12957,6 +12956,7 @@ googlesource.com, 1
goombi.fr, 1
goonersworld.co.uk, 1
gootax.pro, 1
gootlijsten.nl, 1
goozp.com, 1
gopher.tk, 1
goproallaccess.com, 1
@ -13427,6 +13427,7 @@ haccp.roma.it, 1
hacettepeteknokent.com.tr, 1
hachre.de, 1
hack.club, 1
hack.cz, 1
hackademix.net, 1
hackanders.com, 1
hackbarth.guru, 1
@ -14087,7 +14088,7 @@ hilti.kz, 0
hilti.lv, 0
hiltonarubabeachservices.com, 1
hiltonhyland.com, 1
himens.com, 0
himens.com, 1
hindmanfuneralhomes.com, 1
hingle.me, 1
hinrich.de, 1
@ -14122,7 +14123,6 @@ hirevets.gov, 1
hirezzportal.com, 1
hirotaka.org, 1
hirte-digital.de, 1
hirzaconsult.ro, 1
hisbrucker.net, 1
hisnet.de, 1
hispanic.dating, 1
@ -15114,6 +15114,7 @@ indianaantlersupply.com, 1
indianaffairs.gov, 0
indiawise.co.uk, 1
indicateurs-flash.fr, 1
indieethos.com, 1
indiegame.space, 1
indievelopment.nl, 1
indigoinflatables.com, 1
@ -15439,7 +15440,6 @@ investir.ch, 1
investor.gov, 1
investorforms.com, 1
investorloanshub.com, 1
investpay.ru, 1
invinsec.com, 1
invioinc.com, 1
invis.net, 1
@ -16286,7 +16286,6 @@ jobtestprep.nl, 1
jobtestprep.se, 1
jobwinner.ch, 1
jobzninja.com, 1
jodel.ninja, 1
jodlajodla.si, 1
joduska.me, 1
jodyboucher.com, 1
@ -17266,7 +17265,6 @@ klarmobil-empfehlen.de, 1
klasfauseweh.de, 1
klatschreime.de, 1
klausbrinch.dk, 1
klausimas.lt, 1
klaver.it, 1
klaw.xyz, 1
kle.cz, 1
@ -17294,7 +17292,7 @@ klimchuk.by, 1
klimchuk.com, 1
klingeletest.de, 1
klinikac.co.id, 0
klinkerstreet.com.ua, 1
klinkerstreet.com.ua, 0
klinknetz.de, 1
klm-huisjes.nl, 1
klmhouses.com, 1
@ -17462,6 +17460,7 @@ korobi.io, 1
korobkovsky.ru, 1
korono.de, 1
korosiprogram.hu, 1
korp.fr, 1
korrelzout.nl, 1
kortgebyr.dk, 1
koryfi.com, 1
@ -17803,6 +17802,7 @@ laforetenchantee.ch, 1
lafosseobservatoire.be, 1
lafr4nc3.net, 1
lafr4nc3.xyz, 1
lag-gbr.gq, 1
lagarderob.ru, 0
lagazzettadigitale.it, 1
lagerauftrag.info, 1
@ -17869,7 +17869,7 @@ lang-php.com, 1
langatang.com, 1
langguth.io, 1
langkahteduh.com, 1
langly.fr, 0
langly.fr, 1
langstreckensaufen.de, 1
languageterminal.com, 1
langworth.com, 1
@ -18428,6 +18428,7 @@ liduan.net, 1
liebel.org, 1
lieblingsholz.de, 1
lied8.eu, 1
liehuojun.com, 1
lieuu.com, 1
lifanov.com, 1
lifebetweenlives.com.au, 1
@ -18898,7 +18899,6 @@ lottosonline.com, 1
lottospielen24.org, 0
lotuscloud.de, 1
lotw.de, 1
lotz.li, 1
lou.lt, 1
louange-reconvilier.ch, 1
loucanfixit.com, 1
@ -19078,6 +19078,7 @@ lunidea.com, 1
lunight.ml, 1
lunis.net, 1
lunix.io, 1
lunorian.is, 1
luoe.me, 1
luoh.cc, 1
luoh.me, 1
@ -19914,6 +19915,7 @@ mdek.at, 1
mdewendt.de, 1
mdf-bis.com, 1
mdiv.pl, 1
mdkr.nl, 1
mdlayher.com, 1
mdma.net, 1
mdmed.clinic, 1
@ -20249,7 +20251,7 @@ meyash.co, 1
meyeraviation.com, 1
mf-fischer.de, 1
mfen.de, 1
mfgod.com, 0
mfgod.com, 1
mfiles.pl, 1
mflodin.se, 1
mfrsgb45.org, 1
@ -20672,7 +20674,6 @@ mnedc.org, 1
mneeb.de, 1
mnguyen.io, 1
mnitro.com, 1
mnium.de, 1
mnsure.org, 1
mnt-tech.fr, 1
mnt9.de, 1
@ -21429,7 +21430,6 @@ myproblog.com, 1
myptsite.com, 1
mypup.nl, 1
myrandomtips.com, 1
myranicol.com, 1
myrealestatemate.com.au, 1
myref.net, 1
myrekber.co.id, 1
@ -22654,6 +22654,7 @@ oblikdom.ru, 1
oblondata.io, 1
obrienlab.com, 1
obscur.us, 1
observatory.se, 1
obsidianirc.net, 1
obsproject.com, 1
obtima.org, 1
@ -23399,7 +23400,6 @@ paio2-rec.com, 1
paio2.com, 1
paipuman.jp, 1
paizinhovirgula.com, 1
pajadam.me, 1
pajowu.de, 1
pajuvuo.fi, 1
paket.ml, 1
@ -24582,6 +24582,7 @@ port.im, 1
port.social, 1
port443.hamburg, 1
port443.se, 1
port67.org, 1
port80.hamburg, 1
portailevangelique.ca, 1
portal.tirol.gv.at, 1
@ -24755,7 +24756,6 @@ premierheart.com, 1
premiership-predictors.co.uk, 1
premiumweb.co.id, 1
premiumwebdesign.it, 1
premiumzweirad.de, 0
prenatalgeboortekaartjes.nl, 1
prenger.co, 1
prepaid-cards.xyz, 1
@ -24823,6 +24823,7 @@ printeknologies.com, 1
printerleasing.be, 1
printexpress.cloud, 1
printf.de, 1
printfn.com, 0
printler.com, 1
printmet.com, 1
printsos.com, 1
@ -24917,7 +24918,6 @@ prof.ch, 1
profection.biz, 1
professionalboundaries.com, 1
professors.ee, 1
profi-durchgangsmelder.de, 1
profidea.cz, 1
profile.tf, 1
profiles.google.com, 1
@ -26363,6 +26363,7 @@ roland.io, 1
rolandkolodziej.com, 1
rolandreed.cn, 1
rolandszabo.com, 1
roleplayhome.com, 1
roligprylar.se, 1
rollercoasteritalia.it, 1
rollingbarge.com, 1
@ -26618,6 +26619,7 @@ runreport.fr, 1
runschrauger.com, 1
runvs.io, 1
ruobiyi.com, 1
ruobr.ru, 1
ruri.io, 1
rus-trip.ru, 1
rusempire.ru, 1
@ -26855,7 +26857,7 @@ samsungphonegenerator.xyz, 1
samsungxoa.com, 1
samuelkeeley.com, 1
samuellaulhau.fr, 1
samui-samui.de, 1
samui-samui.de, 0
samuirehabcenter.com, 1
samvanderkris.com, 1
samwilberforce.com, 1
@ -27128,7 +27130,7 @@ schokokeks.org, 1
scholarly.com.ph, 1
scholarly.ph, 1
scholierenvervoerzeeland.nl, 1
schollbox.de, 1
schollbox.de, 0
schont.org, 1
school.in.th, 1
schooli.io, 1
@ -29126,6 +29128,7 @@ stamboomvanderwal.nl, 1
stameystreet.com, 1
stamkassa.nl, 1
stammtisch.domains, 1
stamonicatourandtravel.com, 1
stampederadon.com, 1
stanandjerre.org, 1
standagainstspying.org, 1
@ -29376,7 +29379,6 @@ stonewuu.com, 1
stony.com, 1
stonystratford.org, 1
stopakwardhandshakes.org, 1
stopbreakupnow.org, 1
stopbullying.gov, 1
stopfraud.gov, 1
stopthethyroidmadness.com, 1
@ -30864,7 +30866,6 @@ tianshili.me, 1
tianxicaipiao.com, 1
tianxicaipiao.win, 1
tianxicp.com, 1
tibbitshall.ca, 1
tibipg.com, 1
tibovanheule.site, 1
ticfleet.com, 1
@ -31754,7 +31755,6 @@ turigum.com, 1
turismo.cl, 1
turkiet.guide, 1
turkish.dating, 1
turkrock.com, 1
turn-sticks.com, 1
turnaroundforum.de, 1
turncircles.com, 1
@ -32072,7 +32072,6 @@ uniekglas.nl, 1
unifiednetwork.me, 1
uniform-agri.com, 1
uniformebateriasheliar.com.br, 1
uniformehope.com.br, 1
uniformespousoalegre.com.br, 1
unikoingold.com, 1
unikrn.com, 1
@ -32197,6 +32196,7 @@ urbanmelbourne.info, 1
urbanmic.com, 1
urbannewsservice.com, 1
urbansparrow.in, 1
urbanstylestaging.com, 1
urbanwildlifealliance.org, 1
urbexdk.nl, 1
urcentral.com, 1
@ -32240,7 +32240,6 @@ usd.de, 1
usds.gov, 1
use.be, 1
usebean.com, 1
usedesk.ru, 1
usedu.us, 1
useresponse.com, 1
usetypo3.com, 1
@ -32409,6 +32408,7 @@ vantru.is, 1
vanvoro.us, 0
vanwunnik.com, 1
vapecom-shop.com, 1
vapehour.com, 1
vapemania.eu, 1
vaperolles.ch, 1
vapesense.co.uk, 1
@ -32641,7 +32641,6 @@ vidbooster.com, 1
vide-dressing.org, 0
vide-greniers.org, 0
vide-maisons.org, 0
videnskabsklubben.dk, 1
videogamesartwork.com, 1
videoload.co, 1
videorullen.se, 1
@ -32709,7 +32708,6 @@ viltsu.net, 1
vima.ch, 1
vimeo.com, 1
vimeosucks.nyc, 1
vinagro.sk, 1
vinarstvimodryhrozen.cz, 1
vincentcox.com, 0
vincentpancol.com, 1
@ -33159,6 +33157,7 @@ waterschaplimburg.nl, 1
watertrails.io, 1
waterworkscondos.com, 1
watsonwork.me, 1
wattechweb.com, 1
wave-ola.es, 1
wavesboardshop.com, 1
wavesoftime.com, 1
@ -33256,6 +33255,7 @@ webdesignerinwarwickshire.co.uk, 1
webdesignlabor.ch, 1
webdesignplay.com, 1
webdesignplayground.io, 1
webdesignssussex.co.uk, 1
webdev-quiz.de, 1
webdevops.io, 1
webdosh.com, 1
@ -34285,7 +34285,6 @@ xilef.org, 1
xilegames.com, 1
xiliant.com, 1
xilkoi.net, 1
ximage.me, 0
ximbo.net, 1
xin-in.com, 1
xin-in.net, 1
@ -34523,7 +34522,6 @@ y3451.com, 1
yaay.com.br, 1
yabrt.cn, 1
yabuisha.jp, 1
yaccin.com, 1
yachigoya.com, 1
yacineboumaza.fr, 1
yacobo.com, 1
@ -35169,6 +35167,7 @@ zuefle.net, 1
zuehlcke.de, 1
zug-anwalt.de, 1
zug.fr, 1
zug.io, 1
zughilfen-test.de, 1
zuiacg.com, 1
zukix.com, 1
@ -35201,7 +35200,6 @@ zwerimex.com, 1
zwollemag.nl, 1
zwy.ch, 1
zwy.me, 0
zx6rninja.de, 1
zx7r.de, 1
zxity.co.uk, 1
zxity.ltd, 1

View File

@ -124,6 +124,7 @@ reftest:
by-test-platform:
linux64-qr/.*: 1
windows10-64-asan.*: 3
windows10-64-ccov.*: 3
default: default
reftest-gpu:

View File

@ -5,6 +5,7 @@
from abc import ABCMeta, abstractmethod, abstractproperty
from argparse import ArgumentParser, SUPPRESS
from distutils.util import strtobool
from distutils import spawn
from itertools import chain
from urlparse import urlparse
import logging
@ -804,11 +805,20 @@ class MochitestArguments(ArgumentContainer):
if not mozinfo.isLinux:
parser.error(
'--use-test-media-devices is only supported on Linux currently')
for f in ['/usr/bin/gst-launch-0.10', '/usr/bin/pactl']:
if not os.path.isfile(f):
parser.error(
'Missing binary %s required for '
'--use-test-media-devices' % f)
gst01 = spawn.find_executable("gst-launch-0.1")
gst10 = spawn.find_executable("gst-launch-1.0")
pactl = spawn.find_executable("pactl")
if not (gst01 or gst10):
parser.error(
'Missing gst-launch-{0.1,1.0}, required for '
'--use-test-media-devices')
if not pactl:
parser.error(
'Missing binary pactl required for '
'--use-test-media-devices')
if options.nested_oop:
options.e10s = True

View File

@ -15,6 +15,7 @@ sys.path.insert(0, SCRIPT_DIR)
from argparse import Namespace
from collections import defaultdict
from contextlib import closing
from distutils import spawn
import copy
import ctypes
import glob
@ -744,20 +745,29 @@ def findTestMediaDevices(log):
return None
# Feed it a frame of output so it has something to display
subprocess.check_call(['/usr/bin/gst-launch-0.10', 'videotestsrc',
gst01 = spawn.find_executable("gst-launch-0.1")
gst10 = spawn.find_executable("gst-launch-1.0")
if gst01:
gst = gst01
else:
gst = gst10
subprocess.check_call([gst, 'videotestsrc',
'pattern=green', 'num-buffers=1', '!',
'v4l2sink', 'device=%s' % device])
info['video'] = name
pactl = spawn.find_executable("pactl")
pacmd = spawn.find_executable("pacmd")
# Use pactl to see if the PulseAudio module-null-sink module is loaded.
def null_sink_loaded():
o = subprocess.check_output(
['/usr/bin/pactl', 'list', 'short', 'modules'])
[pactl, 'list', 'short', 'modules'])
return filter(lambda x: 'module-null-sink' in x, o.splitlines())
if not null_sink_loaded():
# Load module-null-sink
subprocess.check_call(['/usr/bin/pactl', 'load-module',
subprocess.check_call([pactl, 'load-module',
'module-null-sink'])
if not null_sink_loaded():
@ -765,7 +775,7 @@ def findTestMediaDevices(log):
return None
# Whether it was loaded or not make it the default output
subprocess.check_call(['/usr/bin/pacmd', 'set-default-sink', 'null'])
subprocess.check_call([pacmd, 'set-default-sink', 'null'])
# Hardcode the name since it's always the same.
info['audio'] = 'Monitor of Null Output'

View File

@ -1,12 +0,0 @@
// This file is needed to work around a Firefox bug where capability.principal
// prefs in user.js don't get recognized until the second browser launch
// which is too late for our purposes of using quit.js. Loading the principals
// from prefs.js avoids this issue.
/* globals user_pref */
user_pref("capability.principal.codebase.p0.granted", "UniversalPreferencesWrite UniversalXPConnect UniversalPreferencesRead");
user_pref("capability.principal.codebase.p0.id", "file://");
user_pref("capability.principal.codebase.p0.subjectName", "");
user_pref("capability.principal.codebase.p1.granted", "UniversalPreferencesWrite UniversalXPConnect UniversalPreferencesRead");
user_pref("capability.principal.codebase.p1.id", "http://localhost");
user_pref("capability.principal.codebase.p1.subjectName", "");
user_pref("signed.applets.codebase_principal_support", true);

View File

@ -63,12 +63,9 @@ function canQuitApplication() {
}
function goQuitApplication(waitForSafeBrowsing) {
const privs = "UniversalPreferencesRead UniversalPreferencesWrite " +
"UniversalXPConnect";
/* eslint-disable mozilla/use-chromeutils-import */
try {
netscape.security.PrivilegeManager.enablePrivilege(privs);
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (ex) {
throw ("goQuitApplication: privilege failure " + ex);
}

View File

@ -153,6 +153,7 @@ class Theme {
case "toolbar_field":
case "toolbar_field_text":
case "toolbar_field_border":
case "toolbar_field_separator":
case "toolbar_top_separator":
case "toolbar_bottom_separator":
case "toolbar_vertical_separator":

View File

@ -117,6 +117,10 @@
"$ref": "ThemeColor",
"optional": true
},
"toolbar_field_separator": {
"$ref": "ThemeColor",
"optional": true
},
"toolbar_top_separator": {
"$ref": "ThemeColor",
"optional": true

View File

@ -5,7 +5,8 @@
add_task(async function test_support_separator_properties() {
const SEPARATOR_TOP_COLOR = "#ff00ff";
const SEPARATOR_VERTICAL_COLOR = "#9400ff";
const SEPARATOR_VERTICAL_COLOR = "#f0000f";
const SEPARATOR_FIELD_COLOR = "#9400ff";
const SEPARATOR_BOTTOM_COLOR = "#3366cc";
let extension = ExtensionTestUtils.loadExtension({
@ -19,6 +20,7 @@ add_task(async function test_support_separator_properties() {
"textcolor": TEXT_COLOR,
"toolbar_top_separator": SEPARATOR_TOP_COLOR,
"toolbar_vertical_separator": SEPARATOR_VERTICAL_COLOR,
"toolbar_field_separator": SEPARATOR_FIELD_COLOR,
"toolbar_bottom_separator": SEPARATOR_BOTTOM_COLOR,
},
},
@ -41,13 +43,21 @@ add_task(async function test_support_separator_properties() {
let mainWin = document.querySelector("#main-window");
Assert.equal(
window.getComputedStyle(mainWin).getPropertyValue("--urlbar-separator-color"),
SEPARATOR_VERTICAL_COLOR,
SEPARATOR_FIELD_COLOR,
"Toolbar field separator color properly set"
);
let panelUIButton = document.querySelector("#PanelUI-button");
Assert.ok(
window.getComputedStyle(panelUIButton)
.getPropertyValue("border-image-source")
.includes(`rgb(${hexToRGB(SEPARATOR_VERTICAL_COLOR).join(", ")})`),
"Vertical separator color properly set"
);
let toolbox = document.querySelector("#navigator-toolbox");
Assert.equal(
window.getComputedStyle(toolbox, ":after").borderBottomColor,
window.getComputedStyle(toolbox, "::after").borderBottomColor,
`rgb(${hexToRGB(SEPARATOR_BOTTOM_COLOR).join(", ")})`,
"Bottom separator color properly set"
);

View File

@ -10361,9 +10361,9 @@
},
"MIXED_CONTENT_OBJECT_SUBREQUEST": {
"record_in_processes": ["main", "content"],
"alert_emails": ["seceng-telemetry@mozilla.com"],
"alert_emails": ["seceng-telemetry@mozilla.com", "jkt@mozilla.com"],
"bug_numbers": [1244116],
"expires_in_version": "60",
"expires_in_version": "67",
"kind": "enumerated",
"n_values": 10,
"description": "How often objects load insecure content on secure pages (counting pages, not objects). 0=pages with no mixed object subrequests, 1=pages with mixed object subrequests"

View File

@ -83,6 +83,11 @@ html {
text-align: left;
}
.bottom-border td {
border-bottom: thin solid;
border-color: black;
}
.trickled {
background-color: #bdf;
}

View File

@ -664,6 +664,7 @@ ICEStats.prototype = {
let tbody = stats.map(stat => [
stat["local-candidate"],
stat["remote-candidate"],
stat.componentId,
stat.state,
stat.priority,
stat.nominated,
@ -673,7 +674,8 @@ ICEStats.prototype = {
].map(entry => Object.is(entry, undefined) ? "" : entry));
let statsTable = new SimpleTable(
["local_candidate", "remote_candidate", "ice_state",
["local_candidate", "remote_candidate",
"ice_component_id", "ice_state",
"priority", "nominated", "selected",
"ice_pair_bytes_sent", "ice_pair_bytes_received"
].map(columnName => getString(columnName)),
@ -692,6 +694,17 @@ ICEStats.prototype = {
}
});
// if the next row's component id changes, mark the bottom of the
// current row with a thin, black border to differentiate the
// component id grouping.
let rowCount = statsTable.rows.length - 1;
for (var i = 0; i < rowCount; i++) {
if (statsTable.rows[i].cells[2].innerHTML !==
statsTable.rows[i + 1].cells[2].innerHTML) {
statsTable.rows[i].className = "bottom-border";
}
}
return statsTable;
},
@ -791,10 +804,10 @@ ICEStats.prototype = {
for (let pair of this._report.iceCandidatePairStats) {
let local = candidates.get(pair.localCandidateId);
let remote = candidates.get(pair.remoteCandidateId);
if (local) {
stat = {
["local-candidate"]: this.candidateToString(local),
componentId: pair.componentId,
state: pair.state,
priority: pair.priority,
nominated: pair.nominated,
@ -818,10 +831,17 @@ ICEStats.prototype = {
}
}
return stats.sort((a, b) => (b.bytesSent ?
(b.bytesSent || 0) - (a.bytesSent || 0) :
(b.priority || 0) - (a.priority || 0)
));
// sort (group by) componentId first, then bytesSent if available, else by
// priority
return stats.sort((a, b) => {
if (a.componentId != b.componentId) {
return a.componentId - b.componentId;
}
return (b.bytesSent ?
(b.bytesSent || 0) - (a.bytesSent || 0) :
(b.priority || 0) - (a.priority || 0)
);
});
},
candidateToString(c) {

View File

@ -71,6 +71,7 @@ ice_restart_count_label = ICE restarts
ice_rollback_count_label = ICE rollbacks
ice_pair_bytes_sent = Bytes sent
ice_pair_bytes_received = Bytes received
ice_component_id = Component ID
# LOCALIZATION NOTE (av_sync_label): "A/V" stands for Audio/Video.
# "sync" is an abbreviation for sychronization. This is used as

View File

@ -23,9 +23,10 @@ const kCSSVarsMap = new Map([
["--url-and-searchbar-background-color", "toolbar_field"],
["--url-and-searchbar-color", "toolbar_field_text"],
["--lwt-toolbar-field-border-color", "toolbar_field_border"],
["--urlbar-separator-color", "toolbar_field_separator"],
["--tabs-border-color", "toolbar_top_separator"],
["--lwt-toolbar-vertical-separator", "toolbar_vertical_separator"],
["--toolbox-border-bottom-color", "toolbar_bottom_separator"],
["--urlbar-separator-color", "toolbar_vertical_separator"],
["--lwt-toolbarbutton-icon-fill", "icon_color"],
["--lwt-toolbarbutton-icon-fill-attention", "icon_attention_color"],
]);

View File

@ -273,7 +273,11 @@ nsWaylandDisplay::GetShm()
wl_registry_add_listener(registry, &registry_listener, this);
wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
wl_display_roundtrip_queue(mDisplay, mEventQueue);
if (mEventQueue) {
wl_display_roundtrip_queue(mDisplay, mEventQueue);
} else {
wl_display_roundtrip(mDisplay);
}
MOZ_RELEASE_ASSERT(mShm, "Wayland registry query failed!");
}