зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
250785729c
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
До Ширина: | Высота: | Размер: 451 B После Ширина: | Высота: | Размер: 451 B |
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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>
|
До Ширина: | Высота: | Размер: 421 B |
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3057,7 +3057,7 @@ public:
|
|||
*/
|
||||
static mozilla::dom::CustomElementDefinition*
|
||||
LookupCustomElementDefinition(nsIDocument* aDoc,
|
||||
const nsAString& aLocalName,
|
||||
nsAtom* aNameAtom,
|
||||
uint32_t aNameSpaceID,
|
||||
nsAtom* aTypeAtom);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct {
|
|||
guint source_id;
|
||||
int numAxes;
|
||||
int numButtons;
|
||||
char idstring[128];
|
||||
char idstring[256];
|
||||
char devpath[PATH_MAX];
|
||||
} Gamepad;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)) ||
|
||||
|
|
|
@ -138,6 +138,8 @@ dictionary RTCIceCandidatePairStats : RTCStats {
|
|||
DOMHighResTimeStamp lastPacketSentTimestamp;
|
||||
DOMHighResTimeStamp lastPacketReceivedTimestamp;
|
||||
boolean selected;
|
||||
[ChromeOnly]
|
||||
unsigned long componentId; // moz
|
||||
};
|
||||
|
||||
enum RTCStatsIceCandidateType {
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -117,6 +117,10 @@
|
|||
"$ref": "ThemeColor",
|
||||
"optional": true
|
||||
},
|
||||
"toolbar_field_separator": {
|
||||
"$ref": "ThemeColor",
|
||||
"optional": true
|
||||
},
|
||||
"toolbar_top_separator": {
|
||||
"$ref": "ThemeColor",
|
||||
"optional": true
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -83,6 +83,11 @@ html {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
.bottom-border td {
|
||||
border-bottom: thin solid;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.trickled {
|
||||
background-color: #bdf;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"],
|
||||
]);
|
||||
|
|
|
@ -273,7 +273,11 @@ nsWaylandDisplay::GetShm()
|
|||
wl_registry_add_listener(registry, ®istry_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!");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче