MozReview-Commit-ID: HDHJC8X9xWG
This commit is contained in:
Wes Kocher 2017-02-22 15:06:46 -08:00
Родитель c90805dae5 b7294d3167
Коммит 29443ed98c
123 изменённых файлов: 16351 добавлений и 15092 удалений

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

@ -460,6 +460,7 @@ const gStoragePressureObserver = {
let buttons = [];
let usage = parseInt(data);
let prefStrBundle = document.getElementById("bundle_preferences");
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
let notificationBox = document.getElementById("high-priority-global-notificationbox");
buttons.push({
label: prefStrBundle.getString("spaceAlert.learnMoreButton.label"),
@ -474,7 +475,7 @@ const gStoragePressureObserver = {
// This is because this usage is small and not the main cause for space issue.
// In order to avoid the bad and wrong impression among users that
// firefox eats disk space a lot, indicate users to clean up other disk space.
msg = prefStrBundle.getString("spaceAlert.under5GB.description");
msg = prefStrBundle.getFormattedString("spaceAlert.under5GB.message", [brandShortName]);
buttons.push({
label: prefStrBundle.getString("spaceAlert.under5GB.okButton.label"),
accessKey: prefStrBundle.getString("spaceAlert.under5GB.okButton.accesskey"),
@ -483,15 +484,15 @@ const gStoragePressureObserver = {
} else {
// The firefox-used space >= 5GB, then guide users to about:preferences
// to clear some data stored on firefox by websites.
let descriptionStringID = "spaceAlert.over5GB.description";
let descriptionStringID = "spaceAlert.over5GB.message";
let prefButtonLabelStringID = "spaceAlert.over5GB.prefButton.label";
let prefButtonAccesskeyStringID = "spaceAlert.over5GB.prefButton.accesskey";
if (AppConstants.platform == "win") {
descriptionStringID = "spaceAlert.over5GB.descriptionWin";
descriptionStringID = "spaceAlert.over5GB.messageWin";
prefButtonLabelStringID = "spaceAlert.over5GB.prefButtonWin.label";
prefButtonAccesskeyStringID = "spaceAlert.over5GB.prefButtonWin.accesskey";
}
msg = prefStrBundle.getString(descriptionStringID);
msg = prefStrBundle.getFormattedString(descriptionStringID, [brandShortName]);
buttons.push({
label: prefStrBundle.getString(prefButtonLabelStringID),
accessKey: prefStrBundle.getString(prefButtonAccesskeyStringID),
@ -3435,7 +3436,7 @@ var PrintPreviewListener = {
let browser = gBrowser.selectedBrowser;
let preferredRemoteType = browser.remoteType;
this._tabBeforePrintPreview = gBrowser.selectedTab;
this._printPreviewTab = gBrowser.loadOneTab("about:blank", {
this._printPreviewTab = gBrowser.loadOneTab("about:printpreview", {
inBackground: false,
preferredRemoteType,
sameProcessAsFrameLoader: browser.frameLoader
@ -3446,7 +3447,7 @@ var PrintPreviewListener = {
},
createSimplifiedBrowser() {
let browser = this._tabBeforePrintPreview.linkedBrowser;
this._simplifyPageTab = gBrowser.loadOneTab("about:blank", {
this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", {
inBackground: true,
sameProcessAsFrameLoader: browser.frameLoader
});

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

@ -388,7 +388,7 @@ this.SessionStore = {
let win = aState.windows[i];
for (let j = win.tabs.length - 1; j >= 0; j--) {
let tab = win.tabs[j];
if (!SessionStoreInternal._shouldSaveTabState(tab)) {
if (!SessionStoreInternal._shouldSaveTab(tab)) {
win.tabs.splice(j, 1);
if (win.selected > j) {
win.selected--;
@ -4198,10 +4198,29 @@ var SessionStoreInternal = {
!(aTabState.entries.length == 1 &&
(aTabState.entries[0].url == "about:blank" ||
aTabState.entries[0].url == "about:newtab" ||
aTabState.entries[0].url == "about:printpreview" ||
aTabState.entries[0].url == "about:privatebrowsing") &&
!aTabState.userTypedValue);
},
/**
* Determine if the tab state we're passed is something we should keep to be
* reopened at session restore. This is used when we are saving the current
* session state to disk. This method is very similar to _shouldSaveTabState,
* however, "about:blank" and "about:newtab" tabs will still be saved to disk.
*
* @param aTabState
* The current tab state
* @returns boolean
*/
_shouldSaveTab: function ssi_shouldSaveTab(aTabState) {
// If the tab has one of the following transient about: history entry,
// then we don't actually want to write this tab's data to disk.
return aTabState.entries.length &&
!(aTabState.entries[0].url == "about:printpreview" ||
aTabState.entries[0].url == "about:privatebrowsing");
},
/**
* This is going to take a state as provided at startup (via
* nsISessionStartup.state) and split it into 2 parts. The first part

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

@ -271,9 +271,10 @@ var FormAutofillContent = {
ProfileAutocomplete.ensureUnregistered();
}
});
Services.cpmm.sendAsyncMessage("FormAutofill:getEnabledStatus");
// TODO: use initialProcessData:
// Services.cpmm.initialProcessData.autofillEnabled
if (Services.cpmm.initialProcessData.autofillEnabled) {
ProfileAutocomplete.ensureRegistered();
}
},
/**

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

@ -80,11 +80,10 @@ FormAutofillParent.prototype = {
// Observing the pref and storage changes
Services.prefs.addObserver(ENABLED_PREF, this, false);
Services.obs.addObserver(this, "formautofill-storage-changed", false);
this._enabled = this._getStatus();
// Force to trigger the onStatusChanged function for setting listeners properly
// while initizlization
this._onStatusChanged();
Services.ppmm.addMessageListener("FormAutofill:getEnabledStatus", this);
this._setStatus(this._getStatus());
},
observe(subject, topic, data) {
@ -104,8 +103,7 @@ FormAutofillParent.prototype = {
// Observe pref changes and update _enabled cache if status is changed.
let currentStatus = this._getStatus();
if (currentStatus !== this._enabled) {
this._enabled = currentStatus;
this._onStatusChanged();
this._setStatus(currentStatus);
}
break;
}
@ -118,8 +116,7 @@ FormAutofillParent.prototype = {
let currentStatus = this._getStatus();
if (currentStatus !== this._enabled) {
this._enabled = currentStatus;
this._onStatusChanged();
this._setStatus(currentStatus);
}
break;
}
@ -143,6 +140,9 @@ FormAutofillParent.prototype = {
}
Services.ppmm.broadcastAsyncMessage("FormAutofill:enabledStatus", this._enabled);
// Sync process data autofillEnabled to make sure the value up to date
// no matter when the new content process is initialized.
Services.ppmm.initialProcessData.autofillEnabled = this._enabled;
},
/**
@ -159,6 +159,16 @@ FormAutofillParent.prototype = {
return this._profileStore.getAll().length > 0;
},
/**
* Set status and trigger _onStatusChanged.
*
* @param {boolean} newStatus The latest status we want to set for _enabled
*/
_setStatus(newStatus) {
this._enabled = newStatus;
this._onStatusChanged();
},
/**
* Handles the message coming from FormAutofillContent.
*
@ -171,10 +181,6 @@ FormAutofillParent.prototype = {
case "FormAutofill:GetProfiles":
this._getProfiles(data, target);
break;
case "FormAutofill:getEnabledStatus":
Services.ppmm.broadcastAsyncMessage("FormAutofill:enabledStatus",
this._enabled);
break;
}
},

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

@ -69,11 +69,11 @@ ProfileAutoCompleteResult.prototype = {
* @returns {number} The number of results
*/
get matchCount() {
return this._matchingProfiles.length;
return this._popupLabels.length;
},
_checkIndexBounds(index) {
if (index < 0 || index >= this._matchingProfiles.length) {
if (index < 0 || index >= this._popupLabels.length) {
throw Components.Exception("Index out of range.", Cr.NS_ERROR_ILLEGAL_VALUE);
}
},
@ -123,7 +123,10 @@ ProfileAutoCompleteResult.prototype = {
},
_generateLabels(focusedFieldName, allFieldNames, profiles) {
return profiles.map(profile => {
// Skip results without a primary label.
return profiles.filter(profile => {
return !!profile[focusedFieldName];
}).map(profile => {
return {
primary: profile[focusedFieldName],
secondary: this._getSecondaryLabel(focusedFieldName,

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

@ -8,13 +8,15 @@ Cu.import("resource://formautofill/FormAutofillParent.jsm");
add_task(function* test_enabledStatus_init() {
let formAutofillParent = new FormAutofillParent();
sinon.spy(formAutofillParent, "_onStatusChanged");
sinon.spy(formAutofillParent, "_setStatus");
// Default status is false before initialization
do_check_eq(formAutofillParent._enabled, false);
do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, undefined);
formAutofillParent.init();
do_check_eq(formAutofillParent._onStatusChanged.called, true);
do_check_eq(formAutofillParent._setStatus.called, true);
do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, false);
formAutofillParent._uninit();
});
@ -22,36 +24,36 @@ add_task(function* test_enabledStatus_init() {
add_task(function* test_enabledStatus_observe() {
let formAutofillParent = new FormAutofillParent();
sinon.stub(formAutofillParent, "_getStatus");
sinon.spy(formAutofillParent, "_onStatusChanged");
sinon.spy(formAutofillParent, "_setStatus");
// _enabled = _getStatus() => No need to trigger onStatusChanged
formAutofillParent._enabled = true;
formAutofillParent._getStatus.returns(true);
formAutofillParent.observe(null, "nsPref:changed", "browser.formautofill.enabled");
do_check_eq(formAutofillParent._onStatusChanged.called, false);
do_check_eq(formAutofillParent._setStatus.called, false);
// _enabled != _getStatus() => Need to trigger onStatusChanged
formAutofillParent._getStatus.returns(false);
formAutofillParent.observe(null, "nsPref:changed", "browser.formautofill.enabled");
do_check_eq(formAutofillParent._onStatusChanged.called, true);
do_check_eq(formAutofillParent._setStatus.called, true);
// profile added => Need to trigger onStatusChanged
formAutofillParent._getStatus.returns(!formAutofillParent._enabled);
formAutofillParent._onStatusChanged.reset();
formAutofillParent._setStatus.reset();
formAutofillParent.observe(null, "formautofill-storage-changed", "add");
do_check_eq(formAutofillParent._onStatusChanged.called, true);
do_check_eq(formAutofillParent._setStatus.called, true);
// profile removed => Need to trigger onStatusChanged
formAutofillParent._getStatus.returns(!formAutofillParent._enabled);
formAutofillParent._onStatusChanged.reset();
formAutofillParent._setStatus.reset();
formAutofillParent.observe(null, "formautofill-storage-changed", "remove");
do_check_eq(formAutofillParent._onStatusChanged.called, true);
do_check_eq(formAutofillParent._setStatus.called, true);
// profile updated => no need to trigger onStatusChanged
formAutofillParent._getStatus.returns(!formAutofillParent._enabled);
formAutofillParent._onStatusChanged.reset();
formAutofillParent._setStatus.reset();
formAutofillParent.observe(null, "formautofill-storage-changed", "update");
do_check_eq(formAutofillParent._onStatusChanged.called, false);
do_check_eq(formAutofillParent._setStatus.called, false);
});
add_task(function* test_enabledStatus_getStatus() {
@ -82,3 +84,19 @@ add_task(function* test_enabledStatus_getStatus() {
Services.prefs.setBoolPref("browser.formautofill.enabled", false);
do_check_eq(formAutofillParent._getStatus(), false);
});
add_task(function* test_enabledStatus_setStatus() {
let formAutofillParent = new FormAutofillParent();
sinon.spy(formAutofillParent, "_onStatusChanged");
formAutofillParent._setStatus(true);
do_check_eq(formAutofillParent._enabled, true);
do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, true);
do_check_eq(formAutofillParent._onStatusChanged.called, true);
formAutofillParent._onStatusChanged.reset();
formAutofillParent._setStatus(false);
do_check_eq(formAutofillParent._enabled, false);
do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, false);
do_check_eq(formAutofillParent._onStatusChanged.called, true);
});

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

@ -12,11 +12,17 @@ let matchingProfiles = [{
organization: "Mozilla",
"street-address": "331 E. Evelyn Avenue",
tel: "1-650-903-0800",
}, {
guid: "test-guid-3",
organization: "",
"street-address": "321, No Name St.",
tel: "1-000-000-0000",
}];
let allFieldNames = ["street-address", "organization", "tel"];
let testCases = [{
description: "Focus on an `organization` field",
options: {},
matchingProfiles,
allFieldNames,
@ -46,6 +52,7 @@ let testCases = [{
}],
},
}, {
description: "Focus on an `tel` field",
options: {},
matchingProfiles,
allFieldNames,
@ -72,9 +79,19 @@ let testCases = [{
secondary: "331 E. Evelyn Avenue",
}),
image: "",
}, {
value: "1-000-000-0000",
style: "autofill-profile",
comment: JSON.stringify(matchingProfiles[2]),
label: JSON.stringify({
primary: "1-000-000-0000",
secondary: "321, No Name St.",
}),
image: "",
}],
},
}, {
description: "Focus on an `street-address` field",
options: {},
matchingProfiles,
allFieldNames,
@ -101,9 +118,19 @@ let testCases = [{
secondary: "Mozilla",
}),
image: "",
}, {
value: "321, No Name St.",
style: "autofill-profile",
comment: JSON.stringify(matchingProfiles[2]),
label: JSON.stringify({
primary: "321, No Name St.",
secondary: "1-000-000-0000",
}),
image: "",
}],
},
}, {
description: "No matching profiles",
options: {},
matchingProfiles: [],
allFieldNames,
@ -115,6 +142,7 @@ let testCases = [{
items: [],
},
}, {
description: "Search with failure",
options: {resultCode: Ci.nsIAutoCompleteResult.RESULT_FAILURE},
matchingProfiles: [],
allFieldNames,
@ -128,13 +156,14 @@ let testCases = [{
}];
add_task(function* test_all_patterns() {
testCases.forEach(pattern => {
let actual = new ProfileAutoCompleteResult(pattern.searchString,
pattern.fieldName,
pattern.allFieldNames,
pattern.matchingProfiles,
pattern.options);
let expectedValue = pattern.expected;
testCases.forEach(testCase => {
do_print("Starting testcase: " + testCase.description);
let actual = new ProfileAutoCompleteResult(testCase.searchString,
testCase.fieldName,
testCase.allFieldNames,
testCase.matchingProfiles,
testCase.options);
let expectedValue = testCase.expected;
equal(actual.searchResult, expectedValue.searchResult);
equal(actual.defaultIndex, expectedValue.defaultIndex);
equal(actual.matchCount, expectedValue.items.length);

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

@ -636,6 +636,7 @@
@RESPATH@/greprefs.js
@RESPATH@/defaults/autoconfig/prefcalls.js
@RESPATH@/browser/defaults/permissions
@RESPATH@/browser/defaults/blocklists
; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325)
; Technically this is an app pref file, but we are keeping it in the original

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

@ -207,12 +207,16 @@ spaceAlert.over5GB.prefButton.accesskey=O
# LOCALIZATION NOTE (spaceAlert.over5GB.prefButtonWin.label): On Windows Preferences is called Options
spaceAlert.over5GB.prefButtonWin.label=Open Options
spaceAlert.over5GB.prefButtonWin.accesskey=O
spaceAlert.over5GB.description=Firefox is running out of disk space. Website contents may not display properly. You can clear stored site data in Preferences > Advanced > Site Data.
# LOCALIZATION NOTE (spaceAlert.over5GB.descriptionWin): On Windows Preferences is called Options
spaceAlert.over5GB.descriptionWin=Firefox is running out of disk space. Website contents may not display properly. You can clear stored site data in Options > Advanced > Site Data.
# LOCALIZATION NOTE (spaceAlert.over5GB.message): %S = brandShortName
spaceAlert.over5GB.message=%S is running out of disk space. Website contents may not display properly. You can clear stored site data in Preferences > Advanced > Site Data.
# LOCALIZATION NOTE (spaceAlert.over5GB.messageWin):
# - On Windows Preferences is called Options
# - %S = brandShortName
spaceAlert.over5GB.messageWin=%S is running out of disk space. Website contents may not display properly. You can clear stored site data in Options > Advanced > Site Data.
spaceAlert.under5GB.okButton.label=OK, Got it
spaceAlert.under5GB.okButton.accesskey=K
spaceAlert.under5GB.description=Firefox is running out of disk space. Website contents may not display properly. Visit “Learn More” to optimize your disk usage for better browsing experience.
# LOCALIZATION NOTE (spaceAlert.under5GB.message): %S = brandShortName
spaceAlert.under5GB.message=%S is running out of disk space. Website contents may not display properly. Visit “Learn More” to optimize your disk usage for better browsing experience.
# LOCALIZATION NOTE (featureEnableRequiresRestart, featureDisableRequiresRestart, restartTitle): %S = brandShortName
featureEnableRequiresRestart=%S must restart to enable this feature.

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

@ -4,8 +4,6 @@
"use strict";
const { Cu, Ci } = require("chrome");
const { TargetFactory } = require("devtools/client/framework/target");
const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/main");
@ -21,20 +19,25 @@ const { Task } = require("devtools/shared/task");
* ws:
* {Boolean} If true, connect via websocket instread of regular TCP connection.
*
* type: tab, process
* {String} The type of target to connect to. Currently tabs and processes are supported types.
* type: tab, process, window
* {String} The type of target to connect to.
*
* If type="tab":
* If type == "tab":
* id:
* {Number} the tab outerWindowID
* chrome: Optional
* {Boolean} Force the creation of a chrome target. Gives more privileges to the tab
* actor. Allows chrome execution in the webconsole and see chrome files in
* the debugger. (handy when contributing to firefox)
* {Boolean} Force the creation of a chrome target. Gives more privileges to
* the tab actor. Allows chrome execution in the webconsole and see chrome
* files in the debugger. (handy when contributing to firefox)
*
* If type="process":
* If type == "process":
* id:
* {Number} the process id to debug. Default to 0, which is the parent process.
* {Number} the process id to debug. Default to 0, which is the parent
* process.
*
* If type == "window":
* id:
* {Number} the window outerWindowID
*
* @param {URL} url
* The url to fetch query params from.
@ -93,6 +96,26 @@ exports.targetFromURL = Task.async(function* (url) {
}
throw ex;
}
} else if (type == "window") {
// Fetch target for a remote window actor
DebuggerServer.allowChromeProcess = true;
try {
id = parseInt(id, 10);
if (isNaN(id)) {
throw new Error("targetFromURL, window requires id parameter");
}
let response = yield client.mainRoot.getWindow({
outerWindowID: id,
});
form = response.window;
chrome = true;
} catch (ex) {
if (ex.error == "notFound") {
throw new Error(`targetFromURL, window with id:'${id}' ` +
"doesn't exist");
}
throw ex;
}
} else {
throw new Error("targetFromURL, unsupported type='" + type + "' parameter");
}

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

@ -36,8 +36,19 @@ add_task(function* () {
is(e.message, "targetFromURL, unsupported type='x' parameter");
}
info("Test browser window");
let windowId = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.outerWindowID;
target = yield targetFromURL(new URL("http://foo?type=window&id=" + windowId));
is(target.url, window.location.href);
is(target.isLocalTab, false);
is(target.chrome, true);
is(target.isTabActor, true);
is(target.isRemote, true);
info("Test tab");
let windowId = browser.outerWindowID;
windowId = browser.outerWindowID;
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId));
assertIsTabTarget(target, TEST_URI);

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

@ -2,6 +2,8 @@
* 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/. */
/* eslint-env browser */
"use strict";
// URL constructor doesn't support about: scheme
@ -26,6 +28,23 @@ if (url.search.length > 1) {
.getInterface(Ci.nsIDOMWindowUtils)
.containerElement;
// If there's no containerElement (which happens when loading about:devtools-toolbox as
// a top level document), use the current window.
if (!host) {
host = {
contentWindow: window,
contentDocument: document,
// toolbox-host-manager.js wants to set attributes on the frame that contains it,
// but that is fine to skip and doesn't make sense when using the current window.
setAttribute() {},
ownerDocument: document,
// toolbox-host-manager.js wants to listen for unload events from outside the frame,
// but this is fine to skip since the toolbox code listens inside the frame as well,
// and there is no outer document in this case.
addEventListener() {},
};
}
// Specify the default tool to open
let tool = url.searchParams.get("tool");

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

@ -5,12 +5,29 @@
"use strict";
const {
UPDATE_GRID_COLOR,
UPDATE_GRID_HIGHLIGHTED,
UPDATE_GRIDS,
} = require("./index");
module.exports = {
/**
* Update the color used for the grid's highlighter.
*
* @param {NodeFront} nodeFront
* The NodeFront of the DOM node to toggle the grid highlighter.
* @param {String} color
* The color to use for thie nodeFront's grid highlighter.
*/
updateGridColor(nodeFront, color) {
return {
type: UPDATE_GRID_COLOR,
color,
nodeFront,
};
},
/**
* Update the grid highlighted state.
*
@ -22,8 +39,8 @@ module.exports = {
updateGridHighlighted(nodeFront, highlighted) {
return {
type: UPDATE_GRID_HIGHLIGHTED,
nodeFront,
highlighted,
nodeFront,
};
},

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

@ -8,6 +8,9 @@ const { createEnum } = require("devtools/client/shared/enum");
createEnum([
// Update the color used for the overlay of a grid.
"UPDATE_GRID_COLOR",
// Update the grid highlighted state.
"UPDATE_GRID_HIGHLIGHTED",

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

@ -26,11 +26,13 @@ const App = createClass({
propTypes: {
boxModel: PropTypes.shape(Types.boxModel).isRequired,
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
showBoxModelProperties: PropTypes.bool.isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
onHideBoxModelHighlighter: PropTypes.func.isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onShowBoxModelEditor: PropTypes.func.isRequired,
onShowBoxModelHighlighter: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
onToggleShowGridLineNumbers: PropTypes.func.isRequired,

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

@ -18,8 +18,10 @@ module.exports = createClass({
displayName: "Grid",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
onToggleShowGridLineNumbers: PropTypes.func.isRequired,
onToggleShowInfiniteLines: PropTypes.func.isRequired,
@ -29,8 +31,10 @@ module.exports = createClass({
render() {
let {
getSwatchColorPickerTooltip,
grids,
highlighterSettings,
onSetGridOverlayColor,
onToggleGridHighlighter,
onToggleShowGridLineNumbers,
onToggleShowInfiniteLines,
@ -42,7 +46,9 @@ module.exports = createClass({
id: "layout-grid-container",
},
GridList({
getSwatchColorPickerTooltip,
grids,
onSetGridOverlayColor,
onToggleGridHighlighter,
}),
GridDisplaySettings({

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

@ -0,0 +1,118 @@
/* 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/. */
"use strict";
const { addons, createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
const Types = require("../types");
module.exports = createClass({
displayName: "GridItem",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grid: PropTypes.shape(Types.grid).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
},
mixins: [ addons.PureRenderMixin ],
componentDidMount() {
let tooltip = this.props.getSwatchColorPickerTooltip();
let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch");
let previousColor;
tooltip.addSwatch(swatchEl, {
onCommit: this.setGridColor,
onPreview: this.setGridColor,
onRevert: () => {
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, previousColor);
},
onShow: () => {
previousColor = this.props.grid.color;
},
});
},
componentWillUnmount() {
let tooltip = this.props.getSwatchColorPickerTooltip();
let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch");
tooltip.removeSwatch(swatchEl);
},
setGridColor() {
let color = findDOMNode(this).querySelector(".grid-color-value").textContent;
this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color);
},
onGridCheckboxClick() {
let {
grid,
onToggleGridHighlighter,
} = this.props;
onToggleGridHighlighter(grid.nodeFront);
},
render() {
let { grid } = this.props;
let { nodeFront } = grid;
let { displayName, attributes } = nodeFront;
let gridName = displayName;
let idIndex = attributes.findIndex(({ name }) => name === "id");
if (idIndex > -1 && attributes[idIndex].value) {
gridName += "#" + attributes[idIndex].value;
}
let classIndex = attributes.findIndex(({name}) => name === "class");
if (classIndex > -1 && attributes[classIndex].value) {
gridName += "." + attributes[classIndex].value.split(" ").join(".");
}
return dom.li(
{
key: grid.id,
className: "grid-item",
},
dom.label(
{},
dom.input(
{
type: "checkbox",
value: grid.id,
checked: grid.highlighted,
onChange: this.onGridCheckboxClick,
}
),
gridName
),
dom.div(
{
className: "grid-color-swatch",
style: {
backgroundColor: grid.color,
},
title: grid.color,
}
),
// The SwatchColorPicker relies on the nextSibling of the swatch element to apply
// the selected color. This is why we use a span in display: none for now.
// Ideally we should modify the SwatchColorPickerTooltip to bypass this requirement.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1341578
dom.span(
{
className: "grid-color-value"
},
grid.color
)
);
},
});

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

@ -4,9 +4,11 @@
"use strict";
const { addons, createClass, DOM: dom, PropTypes } =
const { addons, createClass, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const GridItem = createFactory(require("./GridItem"));
const Types = require("../types");
const { getStr } = require("../utils/l10n");
@ -15,24 +17,20 @@ module.exports = createClass({
displayName: "GridList",
propTypes: {
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
onSetGridOverlayColor: PropTypes.func.isRequired,
onToggleGridHighlighter: PropTypes.func.isRequired,
},
mixins: [ addons.PureRenderMixin ],
onGridCheckboxClick({ target }) {
let {
grids,
onToggleGridHighlighter,
} = this.props;
onToggleGridHighlighter(grids[target.value].nodeFront);
},
render() {
let {
getSwatchColorPickerTooltip,
grids,
onSetGridOverlayColor,
onToggleGridHighlighter,
} = this.props;
return dom.div(
@ -45,43 +43,14 @@ module.exports = createClass({
),
dom.ul(
{},
grids.map(grid => {
let { nodeFront } = grid;
let { displayName, attributes } = nodeFront;
let gridName = displayName;
let idIndex = attributes.findIndex(({ name }) => name === "id");
if (idIndex > -1 && attributes[idIndex].value) {
gridName += "#" + attributes[idIndex].value;
}
let classIndex = attributes.findIndex(({name}) => name === "class");
if (classIndex > -1 && attributes[classIndex].value) {
gridName += "." + attributes[classIndex].value.split(" ").join(".");
}
return dom.li(
{
key: grid.id,
},
dom.label(
{},
dom.input(
{
type: "checkbox",
value: grid.id,
checked: grid.highlighted,
onChange: this.onGridCheckboxClick,
}
),
gridName
)
);
})
grids.map(grid => GridItem({
getSwatchColorPickerTooltip,
grid,
onSetGridOverlayColor,
onToggleGridHighlighter,
}))
)
);
},
});

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

@ -16,5 +16,6 @@ DevToolsModules(
'ComputedProperty.js',
'Grid.js',
'GridDisplaySettings.js',
'GridItem.js',
'GridList.js',
)

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

@ -13,10 +13,13 @@ const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
const {
updateLayout,
} = require("./actions/box-model");
const {
updateGridColor,
updateGridHighlighted,
updateGrids,
} = require("./actions/grids");
@ -37,6 +40,18 @@ const NUMERIC = /^-?[\d\.]+$/;
const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
// Default grid colors.
const GRID_COLORS = [
"#05E4EE",
"#BB9DFF",
"#FFB53B",
"#71F362",
"#FF90FF",
"#FF90FF",
"#1B80FF",
"#FF2647"
];
function LayoutView(inspector, window) {
this.document = window.document;
this.highlighters = inspector.highlighters;
@ -74,7 +89,23 @@ LayoutView.prototype = {
this.loadHighlighterSettings();
// Create a shared SwatchColorPicker instance to be reused by all GridItem components.
this.swatchColorPickerTooltip = new SwatchColorPickerTooltip(
this.inspector.toolbox.doc,
this.inspector,
{
supportsCssColor4ColorFunction: () => false
}
);
let app = App({
/**
* Retrieve the shared SwatchColorPicker instance.
*/
getSwatchColorPickerTooltip: () => {
return this.swatchColorPickerTooltip;
},
/**
* Shows the box model properties under the box model if true, otherwise, hidden by
* default.
@ -89,6 +120,29 @@ LayoutView.prototype = {
toolbox.highlighterUtils.unhighlight();
},
/**
* Handler for a change in the grid overlay color picker for a grid container.
*
* @param {NodeFront} node
* The NodeFront of the grid container element for which the grid color is
* being updated.
* @param {String} color
* A hex string representing the color to use.
*/
onSetGridOverlayColor: (node, color) => {
this.store.dispatch(updateGridColor(node, color));
let { grids } = this.store.getState();
// If the grid for which the color was updated currently has a highlighter, update
// the color.
for (let grid of grids) {
if (grid.nodeFront === node && grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(node);
this.highlighters.showGridHighlighter(node, highlighterSettings);
}
}
},
/**
* Shows the inplace editor when a box model editable value is clicked on the
* box model panel.
@ -180,13 +234,13 @@ LayoutView.prototype = {
* highlighter is toggled on/off for.
*/
onToggleGridHighlighter: node => {
let { highlighterSettings } = this.store.getState();
let highlighterSettings = this.getGridHighlighterSettings(node);
this.highlighters.toggleGridHighlighter(node, highlighterSettings);
},
/**
* Handler for a change in the show grid line numbers checkbox in the
* GridDisplaySettings component. TOggles on/off the option to show the grid line
* GridDisplaySettings component. Toggles on/off the option to show the grid line
* numbers in the grid highlighter. Refreshes the shown grid highlighter for the
* grids currently highlighted.
*
@ -197,10 +251,11 @@ LayoutView.prototype = {
this.store.dispatch(updateShowGridLineNumbers(enabled));
Services.prefs.setBoolPref(SHOW_GRID_LINE_NUMBERS, enabled);
let { grids, highlighterSettings } = this.store.getState();
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
}
}
@ -219,14 +274,15 @@ LayoutView.prototype = {
this.store.dispatch(updateShowInfiniteLines(enabled));
Services.prefs.setBoolPref(SHOW_INFINITE_LINES_PREF, enabled);
let { grids, highlighterSettings } = this.store.getState();
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
}
}
},
}
});
let provider = createElement(Provider, {
@ -270,6 +326,43 @@ LayoutView.prototype = {
this.walker = null;
},
/**
* Returns the color set for the grid highlighter associated with the provided
* nodeFront.
*
* @param {NodeFront} nodeFront
* The NodeFront for which we need the color.
*/
getGridColorForNodeFront(nodeFront) {
let { grids } = this.store.getState();
for (let grid of grids) {
if (grid.nodeFront === nodeFront) {
return grid.color;
}
}
return null;
},
/**
* Create a highlighter settings object for the provided nodeFront.
*
* @param {NodeFront} nodeFront
* The NodeFront for which we need highlighter settings.
*/
getGridHighlighterSettings(nodeFront) {
let { highlighterSettings } = this.store.getState();
// Get the grid color for the provided nodeFront.
let color = this.getGridColorForNodeFront(nodeFront);
// Merge the grid color to the generic highlighter settings.
return Object.assign({}, highlighterSettings, {
color
});
},
/**
* Returns true if the layout panel is visible, and false otherwise.
*/
@ -391,8 +484,12 @@ LayoutView.prototype = {
let grid = gridFronts[i];
let nodeFront = yield this.walker.getNodeFromActor(grid.actorID, ["containerEl"]);
let fallbackColor = GRID_COLORS[i % GRID_COLORS.length];
let color = this.getGridColorForNodeFront(nodeFront) || fallbackColor;
grids.push({
id: i,
color,
gridFragments: grid.gridFragments,
highlighted: nodeFront == this.highlighters.gridHighlighterShown,
nodeFront,

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

@ -5,6 +5,7 @@
"use strict";
const {
UPDATE_GRID_COLOR,
UPDATE_GRID_HIGHLIGHTED,
UPDATE_GRIDS,
} = require("../actions/index");
@ -13,12 +14,10 @@ const INITIAL_GRIDS = [];
let reducers = {
[UPDATE_GRID_HIGHLIGHTED](grids, { nodeFront, highlighted }) {
[UPDATE_GRID_COLOR](grids, { nodeFront, color }) {
let newGrids = grids.map(g => {
if (g.nodeFront == nodeFront) {
g.highlighted = highlighted;
} else {
g.highlighted = false;
g.color = color;
}
return g;
@ -27,6 +26,14 @@ let reducers = {
return newGrids;
},
[UPDATE_GRID_HIGHLIGHTED](grids, { nodeFront, highlighted }) {
return grids.map(g => {
return Object.assign({}, g, {
highlighted: g.nodeFront === nodeFront ? highlighted : false
});
});
},
[UPDATE_GRIDS](_, { grids }) {
return grids;
},

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

@ -24,6 +24,9 @@ exports.grid = {
// The id of the grid
id: PropTypes.number,
// The color for the grid overlay highlighter
color: PropTypes.string,
// The grid fragment object of the grid container
gridFragments: PropTypes.array,

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

@ -52,3 +52,29 @@
text-align: center;
padding: 0.5em;
}
/**
* Grid Item
*/
.grid-item {
display: flex;
align-items: center;
}
.grid-item input {
margin: 0 5px;
}
.grid-color-swatch {
width: 12px;
height: 12px;
margin-left: 5px;
border: 1px solid var(--theme-highlight-gray);
border-radius: 50%;
cursor: pointer;
}
.grid-color-value {
display: none;
}

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

@ -21,20 +21,22 @@ const {
const { stringifyGridFragments } = require("devtools/server/actors/utils/css-grid-utils");
const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled";
const DEFAULT_GRID_COLOR = "#4B0082";
const ROWS = "rows";
const COLUMNS = "cols";
const GRID_LINES_PROPERTIES = {
"edge": {
lineDash: [0, 0],
strokeStyle: "#4B0082"
alpha: 1,
},
"explicit": {
lineDash: [5, 3],
strokeStyle: "#8A2BE2"
alpha: 0.75,
},
"implicit": {
lineDash: [2, 2],
strokeStyle: "#9370DB"
alpha: 0.5,
}
};
@ -42,7 +44,7 @@ const GRID_LINES_PROPERTIES = {
const GRID_GAP_PATTERN_WIDTH = 14;
const GRID_GAP_PATTERN_HEIGHT = 14;
const GRID_GAP_PATTERN_LINE_DASH = [5, 3];
const GRID_GAP_PATTERN_STROKE_STYLE = "#9370DB";
const GRID_GAP_ALPHA = 0.5;
/**
* Cached used by `CssGridHighlighter.getGridGapPattern`.
@ -64,6 +66,9 @@ const COLUMN_KEY = {};
* h.destroy();
*
* Available Options:
* - color(colorValue)
* @param {String} colorValue
* The color that should be used to draw the highlighter for this grid.
* - showGridArea(areaName)
* @param {String} areaName
* Shows the grid area highlight for the given area name.
@ -251,6 +256,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
return this.getElement("canvas");
},
get color() {
return this.options.color || DEFAULT_GRID_COLOR;
},
/**
* Gets the grid gap pattern used to render the gap regions.
*
@ -270,6 +279,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
canvas.height = GRID_GAP_PATTERN_HEIGHT;
let ctx = canvas.getContext("2d");
ctx.save();
ctx.setLineDash(GRID_GAP_PATTERN_LINE_DASH);
ctx.beginPath();
ctx.translate(.5, .5);
@ -282,8 +292,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
ctx.lineTo(0, GRID_GAP_PATTERN_HEIGHT);
}
ctx.strokeStyle = GRID_GAP_PATTERN_STROKE_STYLE;
ctx.strokeStyle = this.color;
ctx.globalAlpha = GRID_GAP_ALPHA;
ctx.stroke();
ctx.restore();
let pattern = ctx.createPattern(canvas, "repeat");
gCachedGridPattern.set(dimension, pattern);
@ -295,8 +307,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
* using DeadWrapper objects as gap patterns the next time.
*/
onNavigate() {
gCachedGridPattern.delete(ROW_KEY);
gCachedGridPattern.delete(COLUMN_KEY);
this._clearCache();
},
onWillNavigate({ isTopLevel }) {
@ -311,9 +322,17 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
return false;
}
// The grid pattern cache should be cleared in case the color changed.
this._clearCache();
return this._update();
},
_clearCache() {
gCachedGridPattern.delete(ROW_KEY);
gCachedGridPattern.delete(COLUMN_KEY);
},
/**
* Shows the grid area highlight for the given area name.
*
@ -610,7 +629,9 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
this.ctx.lineTo(endPos, linePos);
}
this.ctx.strokeStyle = GRID_LINES_PROPERTIES[lineType].strokeStyle;
this.ctx.strokeStyle = this.color;
this.ctx.globalAlpha = GRID_LINES_PROPERTIES[lineType].alpha;
this.ctx.stroke();
this.ctx.restore();
},
@ -631,11 +652,16 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
renderGridLineNumber(lineNumber, linePos, startPos, dimensionType) {
this.ctx.save();
let textWidth = this.ctx.measureText(lineNumber).width;
// Guess the font height based on the measured width
let textHeight = textWidth * 2;
if (dimensionType === COLUMNS) {
this.ctx.fillText(lineNumber, linePos, startPos);
let yPos = Math.max(startPos, textHeight);
this.ctx.fillText(lineNumber, linePos, yPos);
} else {
let textWidth = this.ctx.measureText(lineNumber).width;
this.ctx.fillText(lineNumber, startPos - textWidth, linePos);
let xPos = Math.max(startPos, textWidth);
this.ctx.fillText(lineNumber, xPos - textWidth, linePos);
}
this.ctx.restore();

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

@ -66,6 +66,7 @@ DevToolsModules(
'webextension-inspected-window.js',
'webextension.js',
'webgl.js',
'window.js',
'worker-list.js',
'worker.js',
)

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

@ -7,6 +7,7 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const Services = require("Services");
const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
const { DebuggerServer } = require("devtools/server/main");
@ -14,6 +15,8 @@ loader.lazyGetter(this, "ppmm", () => {
return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(
Ci.nsIMessageBroadcaster);
});
loader.lazyRequireGetter(this, "WindowActor",
"devtools/server/actors/window", true);
/* Root actor for the remote debugging protocol. */
@ -167,12 +170,15 @@ RootActor.prototype = {
// Added in Firefox 40. Indicates that the backend supports registering custom
// commands through the WebConsoleCommands API.
webConsoleCommands: true,
// Whether root actor exposes tab actors
// if allowChromeProcess is true, you can fetch a ChromeActor instance
// to debug chrome and any non-content ressource via getProcess request
// if allocChromeProcess is defined, but not true, it means that root actor
// no longer expose tab actors, but also that getProcess forbids
// exposing actors for security reasons
// Whether root actor exposes tab actors and access to any window.
// If allowChromeProcess is true, you can:
// * get a ChromeActor instance to debug chrome and any non-content
// resource via getProcess requests
// * get a WindowActor instance to debug windows which could be chrome,
// like browser windows via getWindow requests
// If allowChromeProcess is defined, but not true, it means that root actor
// no longer expose tab actors, but also that the above requests are
// forbidden for security reasons.
get allowChromeProcess() {
return DebuggerServer.allowChromeProcess;
},
@ -232,6 +238,7 @@ RootActor.prototype = {
this.conn = null;
this._tabActorPool = null;
this._globalActorPool = null;
this._windowActorPool = null;
this._parameters = null;
this._chromeActor = null;
this._processActors.clear();
@ -338,6 +345,38 @@ RootActor.prototype = {
});
},
onGetWindow: function ({ outerWindowID }) {
if (!DebuggerServer.allowChromeProcess) {
return {
from: this.actorID,
error: "forbidden",
message: "You are not allowed to debug windows."
};
}
let window = Services.wm.getOuterWindowWithId(outerWindowID);
if (!window) {
return {
from: this.actorID,
error: "notFound",
message: `No window found with outerWindowID ${outerWindowID}`,
};
}
if (!this._windowActorPool) {
this._windowActorPool = new ActorPool(this.conn);
this.conn.addActorPool(this._windowActorPool);
}
let actor = new WindowActor(this.conn, window);
actor.parentID = this.actorID;
this._windowActorPool.addActor(actor);
return {
from: this.actorID,
window: actor.form(),
};
},
onTabListChanged: function () {
this.conn.send({ from: this.actorID, type: "tabListChanged" });
/* It's a one-shot notification; no need to watch any more. */
@ -539,6 +578,7 @@ RootActor.prototype = {
RootActor.prototype.requestTypes = {
"listTabs": RootActor.prototype.onListTabs,
"getTab": RootActor.prototype.onGetTab,
"getWindow": RootActor.prototype.onGetWindow,
"listAddons": RootActor.prototype.onListAddons,
"listWorkers": RootActor.prototype.onListWorkers,
"listServiceWorkerRegistrations": RootActor.prototype.onListServiceWorkerRegistrations,

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

@ -0,0 +1,83 @@
/* 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/. */
"use strict";
const { Ci } = require("chrome");
const Services = require("Services");
const { TabActor } = require("./tab");
/**
* Creates a WindowActor for debugging a single window, like a browser window in Firefox,
* but it can be used to reach any window in the process. (Currently this is parent
* process only because the root actor's `onGetWindow` doesn't try to cross process
* boundaries.) Both chrome and content windows are supported.
*
* Most of the implementation is inherited from TabActor. WindowActor exposes all tab
* actors via its form() request, like TabActor.
*
* You can request a specific window's actor via RootActor.getWindow().
*
* @param connection DebuggerServerConnection
* The connection to the client.
* @param window DOMWindow
* The window.
*/
function WindowActor(connection, window) {
TabActor.call(this, connection);
let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
Object.defineProperty(this, "docShell", {
value: docShell,
configurable: true
});
}
WindowActor.prototype = Object.create(TabActor.prototype);
// Bug 1266561: This setting is mysteriously named, we should split up the
// functionality that is triggered by it.
WindowActor.prototype.isRootActor = true;
WindowActor.prototype.observe = function (subject, topic, data) {
TabActor.prototype.observe.call(this, subject, topic, data);
if (!this.attached) {
return;
}
if (topic == "chrome-webnavigation-destroy") {
this._onDocShellDestroy(subject);
}
};
WindowActor.prototype._attach = function () {
if (this.attached) {
return false;
}
TabActor.prototype._attach.call(this);
// Listen for chrome docshells in addition to content docshells
if (this.docShell.itemType == Ci.nsIDocShellTreeItem.typeChrome) {
Services.obs.addObserver(this, "chrome-webnavigation-destroy", false);
}
return true;
};
WindowActor.prototype._detach = function () {
if (!this.attached) {
return false;
}
if (this.docShell.itemType == Ci.nsIDocShellTreeItem.typeChrome) {
Services.obs.removeObserver(this, "chrome-webnavigation-destroy");
}
TabActor.prototype._detach.call(this);
return true;
};
exports.WindowActor = WindowActor;

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

@ -7,7 +7,8 @@ once a parent is removed from the pool, its children are removed as well.
The overall hierarchy of actors looks like this:
RootActor: First one, automatically instantiated when we start connecting.
```
RootActor: First one, automatically instantiated when we start connecting.
| Mostly meant to instantiate new actors.
|
|--> Global-scoped actors:
@ -27,6 +28,7 @@ The overall hierarchy of actors looks like this:
worker). Examples include the console and inspector actors.
These actors may extend this hierarchy by having their
own children, like LongStringActor, WalkerActor, etc.
```
## RootActor
@ -36,7 +38,8 @@ All other actors have an `actorID` which is computed dynamically,
so that you need to ask an existing actor to create an Actor
and returns its `actorID`. That's the main role of RootActor.
RootActor (root.js)
```
RootActor (root.js)
|
|-- BrowserTabActor (webbrowser.js)
| Targets tabs living in the parent or child process. Note that this is
@ -60,6 +63,11 @@ and returns its `actorID`. That's the main role of RootActor.
| Returned by "listWorkers" request to a ChildProcessActor to get workers
| for the chrome of the child process.
|
|-- WindowActor (window.js)
| Targets a single window, such as a browser window in Firefox, but it can
| be used to reach any window in the parent process.
| Returned by "getWindow" request to the root actor.
|
|-- ChromeActor (chrome.js)
| Targets all resources in the parent process of firefox
| (chrome documents, JSM, JS XPCOM, etc.).
@ -73,6 +81,7 @@ and returns its `actorID`. That's the main role of RootActor.
\-- BrowserAddonActor (addon.js)
Targets the javascript of add-ons.
Returned by "listAddons" request.
```
## "TabActor"

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

@ -12,8 +12,8 @@
.simple-animation {
display: inline-block;
width: 50px;
height: 50px;
width: 64px;
height: 64px;
border-radius: 50%;
background: red;

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

@ -1741,6 +1741,27 @@ RootClient.prototype = {
return this.request(packet);
},
/**
* Fetch the WindowActor for a specific window, like a browser window in
* Firefox, but it can be used to reach any window in the process.
*
* @param number outerWindowID
* The outerWindowID of the top level window you are looking for.
*/
getWindow: function ({ outerWindowID }) {
if (!outerWindowID) {
throw new Error("Must specify outerWindowID");
}
let packet = {
to: this.actor,
type: "getWindow",
outerWindowID,
};
return this.request(packet);
},
/**
* Description of protocol's actors and methods.
*

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

@ -138,6 +138,12 @@ static const RedirEntry kRedirMap[] = {
{
"webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html",
nsIAboutModule::ALLOW_SCRIPT
},
{
"printpreview", "about:blank",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT |
nsIAboutModule::URI_CAN_LOAD_IN_CHILD
}
};
static const int kRedirTotal = mozilla::ArrayLength(kRedirMap);
@ -173,9 +179,11 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
&isUIResource);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags =
isUIResource ? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
bool isAboutBlank = NS_IsAboutBlank(tempURI);
nsLoadFlags loadFlags = isUIResource || isAboutBlank
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
tempURI,

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

@ -14364,10 +14364,19 @@ nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview)
#if NS_PRINT_PREVIEW
nsCOMPtr<nsIDocumentViewerPrint> print = do_QueryInterface(mContentViewer);
if (!print || !print->IsInitializedForPrintPreview()) {
// XXX: Creating a brand new content viewer to host preview every
// time we enter here seems overwork. We could skip ahead to where
// we QI the mContentViewer if the current URI is either about:blank
// or about:printpreview.
Stop(nsIWebNavigation::STOP_ALL);
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::CreateWithInheritedAttributes(this);
nsresult rv = CreateAboutBlankContentViewer(principal, nullptr);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:printpreview"));
nsresult rv = CreateAboutBlankContentViewer(principal, uri);
NS_ENSURE_SUCCESS(rv, rv);
// Here we manually set current URI since we have just created a
// brand new content viewer (about:blank) to host preview.
SetCurrentURI(uri, nullptr, true, 0);
print = do_QueryInterface(mContentViewer);
NS_ENSURE_STATE(print);
print->InitializeForPrintPreview();

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

@ -189,6 +189,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "printpreview", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
{ NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
{ NS_HANDLERSERVICE_CONTRACTID, &kNS_CONTENTHANDLERSERVICE_CID, mozilla::Module::CONTENT_PROCESS_ONLY },

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

@ -33,13 +33,6 @@ AnimationPerformanceWarning::ToLocalizedString(
const char* key = nullptr;
switch (mType) {
case Type::ContentTooSmall:
MOZ_ASSERT(mParams && mParams->Length() == 2,
"Parameter's length should be 2 for ContentTooSmall");
return NS_SUCCEEDED(
ToLocalizedStringWithIntParams<2>(
"CompositorAnimationWarningContentTooSmall", aLocalizedString));
case Type::ContentTooLarge:
MOZ_ASSERT(mParams && mParams->Length() == 6,
"Parameter's length should be 6 for ContentTooLarge");

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

@ -20,7 +20,6 @@ namespace mozilla {
struct AnimationPerformanceWarning
{
enum class Type : uint8_t {
ContentTooSmall,
ContentTooLarge,
TransformBackfaceVisibilityHidden,
TransformPreserve3D,

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

@ -840,7 +840,7 @@ function testMultipleAnimationsWithGeometricAnimations() {
function testSmallElements() {
[
{
desc: 'opacity on too small element',
desc: 'opacity on small element',
frames: {
opacity: [0, 1]
},
@ -855,13 +855,12 @@ function testSmallElements() {
expected: [
{
property: 'opacity',
runningOnCompositor: false,
warning: /Animation cannot be run on the compositor because frame size \(8, 8\) is smaller than \(16, 16\)/
runningOnCompositor: true
}
]
},
{
desc: 'transform on too small element',
desc: 'transform on small element',
frames: {
transform: ['translate(0px)', 'translate(100px)']
},
@ -869,8 +868,7 @@ function testSmallElements() {
expected: [
{
property: 'transform',
runningOnCompositor: false,
warning: /Animation cannot be run on the compositor because frame size \(8, 8\) is smaller than \(16, 16\)/
runningOnCompositor: true
}
]
},

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

@ -11,9 +11,6 @@ ImageMapPolyOddNumberOfCoords=The “coords” attribute of the <area shape="pol
TablePartRelPosWarning=Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature having no effect.
ScrollLinkedEffectFound2=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!
## LOCALIZATION NOTE(CompositorAnimationWarningContentTooSmall):
## (%1$S, %2$S) is a pair of integer values of the frame size
CompositorAnimationWarningContentTooSmall=Animation cannot be run on the compositor because frame size (%1$S, %2$S) is smaller than (16, 16)
## LOCALIZATION NOTE(CompositorAnimationWarningContentTooLarge2):
## (%1$S, %2$S) is a pair of integer values of the frame size
## (%3$S, %4$S) is a pair of integer values of a limit based on the viewport size

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

@ -90,10 +90,11 @@ private:
DECL_MEDIA_PREF("accessibility.monoaudio.enable", MonoAudio, bool, false);
DECL_MEDIA_PREF("media.resampling.enabled", AudioSinkResampling, bool, false);
DECL_MEDIA_PREF("media.resampling.rate", AudioSinkResampleRate, uint32_t, 48000);
#if defined(ANDROID)
DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, true);
#else
#if defined(XP_WIN) || defined(XP_DARWIN) || defined(MOZ_PULSEAUDIO)
// libcubeb backend implement .get_preferred_channel_layout
DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, false);
#else
DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, true);
#endif
// VideoSink
DECL_MEDIA_PREF("media.ruin-av-sync.enabled", RuinAvSync, bool, false);

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

@ -556,6 +556,7 @@ private:
DECL_GFX_PREF(Live, "layout.display-list.dump-content", LayoutDumpDisplayListContent, bool, false);
DECL_GFX_PREF(Live, "layout.event-regions.enabled", LayoutEventRegionsEnabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Once, "layout.frame_rate", LayoutFrameRate, int32_t, -1);
DECL_GFX_PREF(Live, "layout.min-active-layer-size", LayoutMinActiveLayerSize, int, 64);
DECL_GFX_PREF(Once, "layout.paint_rects_separately", LayoutPaintRectsSeparately, bool, true);
// This and code dependent on it should be removed once containerless scrolling looks stable.

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

@ -0,0 +1,53 @@
// |jit-test| --no-threads
function t1() {
let x = [];
for (let k = 0; k < 100; ++k)
x[k] = () => k; // Lexical capture
try {
eval("k");
throw false;
}
catch (e) {
if (!(e instanceof ReferenceError))
throw "Loop index escaped block";
}
for (var i = 0; i < 100; ++i)
if (x[i]() != i)
throw "Bad let capture";
}
t1();
t1();
t1();
t1();
function t2() {
let x = [];
let y = {};
for (var i = 0; i < 100; ++i)
x[i] = i;
for (const k of x)
y[k] = () => k; // Lexical capture
try {
eval("k");
throw false;
}
catch (e) {
if (!(e instanceof ReferenceError))
throw "Loop index escaped block";
}
for (var i = 0; i < 100; ++i)
if (y[i]() != i)
throw "Bad const capture";
}
t2();
t2();
t2();
t2();

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

@ -0,0 +1,46 @@
// |jit-test| --no-threads
function t1() {
let x = [];
try
{
for (let k = 0; k < 100; ++k)
{
let w = () => k; // Lexical capture
if (w() > 10)
{
throw () => w; // Lexical capture
}
x[k] = w;
}
}
catch (e)
{
// 'w' and 'k' should leave scope as exception unwinds
try {
eval("k");
throw false;
}
catch (e) {
if (!(e instanceof ReferenceError))
throw "Loop index escaped block";
}
try {
eval("w");
throw false;
}
catch (e) {
if (!(e instanceof ReferenceError))
throw "Local name escaped block";
}
}
}
t1();
t1();
t1();
t1();

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

@ -137,6 +137,8 @@ struct BaselineStackBuilder
header_->resumeFramePtr = nullptr;
header_->resumeAddr = nullptr;
header_->resumePC = nullptr;
header_->tryPC = nullptr;
header_->faultPC = nullptr;
header_->monitorStub = nullptr;
header_->numFrames = 0;
header_->checkGlobalDeclarationConflicts = false;
@ -729,14 +731,12 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
Value v = iter.read();
if (v.isObject()) {
envChain = &v.toObject();
if (fun &&
((fun->needsCallObject() && envChain->is<CallObject>()) ||
(fun->needsNamedLambdaEnvironment() &&
!fun->needsCallObject() &&
envChain->is<LexicalEnvironmentObject>() &&
&envChain->as<LexicalEnvironmentObject>().scope() ==
script->maybeNamedLambdaScope())))
{
// If Ion has updated env slot from UndefinedValue, it will be the
// complete initial environment, so we can set the HAS_INITIAL_ENV
// flag if needed.
if (fun && fun->needsFunctionEnvironmentObjects()) {
MOZ_ASSERT(fun->nonLazyScript()->initialEnvironmentShape());
MOZ_ASSERT(!fun->needsExtraBodyVarEnvironment());
flags |= BaselineFrame::HAS_INITIAL_ENV;
}
@ -1822,6 +1822,8 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
BaselineFrame* topFrame = GetTopBaselineFrame(cx);
topFrame->setOverridePc(bailoutInfo->resumePC);
jsbytecode* faultPC = bailoutInfo->faultPC;
jsbytecode* tryPC = bailoutInfo->tryPC;
uint32_t numFrames = bailoutInfo->numFrames;
MOZ_ASSERT(numFrames > 0);
BailoutKind bailoutKind = bailoutInfo->bailoutKind;
@ -1939,6 +1941,13 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
return false;
}
// If we are catching an exception, we need to unwind scopes.
// See |SettleOnTryNote|
if (cx->isExceptionPending() && faultPC) {
EnvironmentIter ei(cx, topFrame, faultPC);
UnwindEnvironment(cx, ei, tryPC);
}
JitSpew(JitSpew_BaselineBailouts,
" Restored outerScript=(%s:%" PRIuSIZE ",%u) innerScript=(%s:%" PRIuSIZE ",%u) (bailoutKind=%u)",
outerScript->filename(), outerScript->lineno(), outerScript->getWarmUpCount(),

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

@ -592,6 +592,10 @@ struct BaselineBailoutInfo
// The bytecode pc where we will resume.
jsbytecode* resumePC;
// The bytecode pc of try block and fault block.
jsbytecode* tryPC;
jsbytecode* faultPC;
// If resuming into a TypeMonitor IC chain, this field holds the
// address of the first stub in that chain. If this field is
// set, then the actual jitcode resumed into is the jitcode for

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

@ -168,6 +168,8 @@ BytecodeAnalysis::init(TempAllocator& alloc, GSNCache& gsn)
case JSOP_LAMBDA_ARROW:
case JSOP_DEFFUN:
case JSOP_DEFVAR:
case JSOP_PUSHLEXICALENV:
case JSOP_POPLEXICALENV:
usesEnvironmentChain_ = true;
break;

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

@ -3433,6 +3433,35 @@ CodeGenerator::visitFunctionEnvironment(LFunctionEnvironment* lir)
masm.loadPtr(environment, ToRegister(lir->output()));
}
typedef LexicalEnvironmentObject* (*NewLexicalEnvironmentObjectFn)(JSContext*,
Handle<LexicalScope*>,
HandleObject, gc::InitialHeap);
static const VMFunction NewLexicalEnvironmentObjectInfo =
FunctionInfo<NewLexicalEnvironmentObjectFn>(LexicalEnvironmentObject::create,
"LexicalEnvironmentObject::create");
void
CodeGenerator::visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir)
{
pushArg(Imm32(gc::DefaultHeap));
pushArg(ToRegister(lir->enclosing()));
pushArg(ImmGCPtr(lir->mir()->scope()));
callVM(NewLexicalEnvironmentObjectInfo, lir);
}
typedef JSObject* (*CopyLexicalEnvironmentObjectFn)(JSContext*, HandleObject, bool);
static const VMFunction CopyLexicalEnvironmentObjectInfo =
FunctionInfo<CopyLexicalEnvironmentObjectFn>(js::jit::CopyLexicalEnvironmentObject,
"js::jit::CopyLexicalEnvironmentObject");
void
CodeGenerator::visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir)
{
pushArg(Imm32(lir->mir()->copySlots()));
pushArg(ToRegister(lir->env()));
callVM(CopyLexicalEnvironmentObjectInfo, lir);
}
void
CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity* guard)
{

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

@ -287,6 +287,8 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitSinCos(LSinCos *lir);
void visitStringSplit(LStringSplit* lir);
void visitFunctionEnvironment(LFunctionEnvironment* lir);
void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir);
void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir);
void visitCallGetProperty(LCallGetProperty* lir);
void visitCallGetElement(LCallGetElement* lir);
void visitCallSetElement(LCallSetElement* lir);

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

@ -1175,6 +1175,9 @@ IonBuilder::initEnvironmentChain(MDefinition* callee)
env = constant(ObjectValue(script()->global().lexicalEnvironment()));
}
// Update the environment slot from UndefinedValue only after initial
// environment is created so that bailout doesn't see a partial env.
// See: |InitFromBailout|
current->setEnvironmentChain(env);
return Ok();
}
@ -2207,6 +2210,19 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_SETFUNNAME:
return jsop_setfunname(GET_UINT8(pc));
case JSOP_PUSHLEXICALENV:
return jsop_pushlexicalenv(GET_UINT32_INDEX(pc));
case JSOP_POPLEXICALENV:
current->setEnvironmentChain(walkEnvironmentChain(1));
return Ok();
case JSOP_FRESHENLEXICALENV:
return jsop_copylexicalenv(true);
case JSOP_RECREATELEXICALENV:
return jsop_copylexicalenv(false);
case JSOP_ITER:
return jsop_iter(GET_INT8(pc));
@ -2269,18 +2285,6 @@ IonBuilder::inspectOpcode(JSOp op)
pushConstant(MagicValue(JS_IS_CONSTRUCTING));
return Ok();
#ifdef DEBUG
case JSOP_PUSHLEXICALENV:
case JSOP_FRESHENLEXICALENV:
case JSOP_RECREATELEXICALENV:
case JSOP_POPLEXICALENV:
// These opcodes are currently unhandled by Ion, but in principle
// there's no reason they couldn't be. Whenever this happens, OSR
// will have to consider that JSOP_{FRESHEN,RECREATE}LEXICALENV
// mutates the env chain -- right now MBasicBlock::environmentChain()
// caches the env chain. JSOP_{FRESHEN,RECREATE}LEXICALENV must
// update that stale value.
#endif
default:
break;
}
@ -11849,6 +11853,35 @@ IonBuilder::jsop_setfunname(uint8_t prefixKind)
return resumeAfter(ins);
}
AbortReasonOr<Ok>
IonBuilder::jsop_pushlexicalenv(uint32_t index)
{
MOZ_ASSERT(analysis().usesEnvironmentChain());
LexicalScope* scope = &script()->getScope(index)->as<LexicalScope>();
MNewLexicalEnvironmentObject* ins =
MNewLexicalEnvironmentObject::New(alloc(), current->environmentChain(), scope);
current->add(ins);
current->setEnvironmentChain(ins);
return resumeAfter(ins);
}
AbortReasonOr<Ok>
IonBuilder::jsop_copylexicalenv(bool copySlots)
{
MOZ_ASSERT(analysis().usesEnvironmentChain());
MCopyLexicalEnvironmentObject* ins =
MCopyLexicalEnvironmentObject::New(alloc(), current->environmentChain(), copySlots);
current->add(ins);
current->setEnvironmentChain(ins);
return resumeAfter(ins);
}
AbortReasonOr<Ok>
IonBuilder::jsop_setarg(uint32_t arg)
{

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

@ -561,6 +561,8 @@ class IonBuilder
AbortReasonOr<Ok> jsop_lambda(JSFunction* fun);
AbortReasonOr<Ok> jsop_lambda_arrow(JSFunction* fun);
AbortReasonOr<Ok> jsop_setfunname(uint8_t prefixKind);
AbortReasonOr<Ok> jsop_pushlexicalenv(uint32_t index);
AbortReasonOr<Ok> jsop_copylexicalenv(bool copySlots);
AbortReasonOr<Ok> jsop_functionthis();
AbortReasonOr<Ok> jsop_globalthis();
AbortReasonOr<Ok> jsop_typeof();

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

@ -464,8 +464,14 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx
jsbytecode* catchPC = script->main() + tn->start + tn->length;
ExceptionBailoutInfo excInfo(frame.frameNo(), catchPC, tn->stackDepth);
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed);
if (retval == BAILOUT_RETURN_OK)
if (retval == BAILOUT_RETURN_OK) {
// Record exception locations to allow scope unwinding in
// |FinishBailoutToBaseline|
MOZ_ASSERT(cx->isExceptionPending());
rfe->bailoutInfo->tryPC = UnwindEnvironmentToTryPc(frame.script(), tn);
rfe->bailoutInfo->faultPC = frame.pc();
return;
}
// Error on bailout clears pending exception.
MOZ_ASSERT(!cx->isExceptionPending());

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

@ -2517,6 +2517,32 @@ LIRGenerator::visitSetFunName(MSetFunName* ins)
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins)
{
MDefinition* enclosing = ins->enclosing();
MOZ_ASSERT(enclosing->type() == MIRType::Object);
LNewLexicalEnvironmentObject* lir =
new(alloc()) LNewLexicalEnvironmentObject(useRegisterAtStart(enclosing));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitCopyLexicalEnvironmentObject(MCopyLexicalEnvironmentObject* ins)
{
MDefinition* env = ins->env();
MOZ_ASSERT(env->type() == MIRType::Object);
LCopyLexicalEnvironmentObject* lir =
new(alloc()) LCopyLexicalEnvironmentObject(useRegisterAtStart(env));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins)
{

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

@ -186,6 +186,8 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitLambda(MLambda* ins);
void visitLambdaArrow(MLambdaArrow* ins);
void visitSetFunName(MSetFunName* ins);
void visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins);
void visitCopyLexicalEnvironmentObject(MCopyLexicalEnvironmentObject* ins);
void visitKeepAliveObject(MKeepAliveObject* ins);
void visitSlots(MSlots* ins);
void visitElements(MElements* ins);

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

@ -11530,6 +11530,63 @@ class MFunctionEnvironment
}
};
// Allocate a new LexicalEnvironmentObject.
class MNewLexicalEnvironmentObject
: public MUnaryInstruction,
public SingleObjectPolicy::Data
{
CompilerGCPointer<LexicalScope*> scope_;
MNewLexicalEnvironmentObject(MDefinition* enclosing, LexicalScope* scope)
: MUnaryInstruction(enclosing),
scope_(scope)
{
setResultType(MIRType::Object);
}
public:
INSTRUCTION_HEADER(NewLexicalEnvironmentObject)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, enclosing))
LexicalScope* scope() const {
return scope_;
}
bool possiblyCalls() const override {
return true;
}
bool appendRoots(MRootList& roots) const override {
return roots.append(scope_);
}
};
// Allocate a new LexicalEnvironmentObject from existing one
class MCopyLexicalEnvironmentObject
: public MUnaryInstruction,
public SingleObjectPolicy::Data
{
bool copySlots_;
MCopyLexicalEnvironmentObject(MDefinition* env, bool copySlots)
: MUnaryInstruction(env),
copySlots_(copySlots)
{
setResultType(MIRType::Object);
}
public:
INSTRUCTION_HEADER(CopyLexicalEnvironmentObject)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, env))
bool copySlots() const {
return copySlots_;
}
bool possiblyCalls() const override {
return true;
}
};
// Store to vp[slot] (slots that are not inline in an object).
class MStoreSlot
: public MBinaryInstruction,

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

@ -172,6 +172,8 @@ namespace jit {
_(LoadSlot) \
_(StoreSlot) \
_(FunctionEnvironment) \
_(NewLexicalEnvironmentObject) \
_(CopyLexicalEnvironmentObject) \
_(FilterTypeSet) \
_(TypeBarrier) \
_(MonitorTypes) \

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

@ -956,6 +956,17 @@ NewArgumentsObject(JSContext* cx, BaselineFrame* frame, MutableHandleValue res)
return true;
}
JSObject*
CopyLexicalEnvironmentObject(JSContext* cx, HandleObject env, bool copySlots)
{
Handle<LexicalEnvironmentObject*> lexicalEnv = env.as<LexicalEnvironmentObject>();
if (copySlots)
return LexicalEnvironmentObject::clone(cx, lexicalEnv);
return LexicalEnvironmentObject::recreate(cx, lexicalEnv);
}
JSObject*
InitRestParameter(JSContext* cx, uint32_t length, Value* rest, HandleObject templateObj,
HandleObject objRes)

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

@ -278,6 +278,7 @@ template <> struct TypeToDataType<NativeObject*> { static const DataType result
template <> struct TypeToDataType<PlainObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<InlineTypedObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<NamedLambdaObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<LexicalEnvironmentObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<ArrayObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<TypedArrayObject*> { static const DataType result = Type_Object; };
template <> struct TypeToDataType<JSString*> { static const DataType result = Type_Object; };
@ -715,6 +716,8 @@ InitFunctionEnvironmentObjects(JSContext* cx, BaselineFrame* frame);
MOZ_MUST_USE bool
NewArgumentsObject(JSContext* cx, BaselineFrame* frame, MutableHandleValue res);
JSObject* CopyLexicalEnvironmentObject(JSContext* cx, HandleObject env, bool copySlots);
JSObject* InitRestParameter(JSContext* cx, uint32_t length, Value* rest, HandleObject templateObj,
HandleObject res);

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

@ -7050,6 +7050,42 @@ class LFunctionEnvironment : public LInstructionHelper<1, 1, 0>
}
};
// Allocate a new LexicalEnvironmentObject.
class LNewLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(NewLexicalEnvironmentObject)
explicit LNewLexicalEnvironmentObject(const LAllocation& enclosing) {
setOperand(0, enclosing);
}
const LAllocation* enclosing() {
return getOperand(0);
}
MNewLexicalEnvironmentObject* mir() const {
return mir_->toNewLexicalEnvironmentObject();
}
};
// Copy a LexicalEnvironmentObject.
class LCopyLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(CopyLexicalEnvironmentObject)
explicit LCopyLexicalEnvironmentObject(const LAllocation& env) {
setOperand(0, env);
}
const LAllocation* env() {
return getOperand(0);
}
MCopyLexicalEnvironmentObject* mir() const {
return mir_->toCopyLexicalEnvironmentObject();
}
};
class LCallGetProperty : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
{
public:

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

@ -319,6 +319,8 @@
_(StoreFixedSlotV) \
_(StoreFixedSlotT) \
_(FunctionEnvironment) \
_(NewLexicalEnvironmentObject) \
_(CopyLexicalEnvironmentObject) \
_(GetPropertyCacheV) \
_(GetPropertyCacheT) \
_(GetPropertyPolymorphicV) \

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

@ -889,8 +889,8 @@ LexicalEnvironmentObject::createTemplateObject(JSContext* cx, HandleShape shape,
}
/* static */ LexicalEnvironmentObject*
LexicalEnvironmentObject::createTemplateObject(JSContext* cx, Handle<LexicalScope*> scope,
HandleObject enclosing, gc::InitialHeap heap)
LexicalEnvironmentObject::create(JSContext* cx, Handle<LexicalScope*> scope,
HandleObject enclosing, gc::InitialHeap heap)
{
assertSameCompartment(cx, enclosing);
MOZ_ASSERT(scope->hasEnvironment());
@ -915,7 +915,7 @@ LexicalEnvironmentObject::create(JSContext* cx, Handle<LexicalScope*> scope,
AbstractFramePtr frame)
{
RootedObject enclosing(cx, frame.environmentChain());
return createTemplateObject(cx, scope, enclosing, gc::DefaultHeap);
return create(cx, scope, enclosing, gc::DefaultHeap);
}
/* static */ LexicalEnvironmentObject*
@ -997,8 +997,7 @@ LexicalEnvironmentObject::clone(JSContext* cx, Handle<LexicalEnvironmentObject*>
{
Rooted<LexicalScope*> scope(cx, &env->scope());
RootedObject enclosing(cx, &env->enclosingEnvironment());
Rooted<LexicalEnvironmentObject*> copy(cx, createTemplateObject(cx, scope, enclosing,
gc::TenuredHeap));
Rooted<LexicalEnvironmentObject*> copy(cx, create(cx, scope, enclosing, gc::TenuredHeap));
if (!copy)
return nullptr;
@ -1016,7 +1015,7 @@ LexicalEnvironmentObject::recreate(JSContext* cx, Handle<LexicalEnvironmentObjec
{
Rooted<LexicalScope*> scope(cx, &env->scope());
RootedObject enclosing(cx, &env->enclosingEnvironment());
return createTemplateObject(cx, scope, enclosing, gc::TenuredHeap);
return create(cx, scope, enclosing, gc::TenuredHeap);
}
bool
@ -1071,8 +1070,7 @@ NamedLambdaObject::create(JSContext* cx, HandleFunction callee,
#endif
LexicalEnvironmentObject* obj =
LexicalEnvironmentObject::createTemplateObject(cx, scope.as<LexicalScope>(),
enclosing, heap);
LexicalEnvironmentObject::create(cx, scope.as<LexicalScope>(), enclosing, heap);
if (!obj)
return nullptr;

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

@ -477,11 +477,8 @@ class LexicalEnvironmentObject : public EnvironmentObject
}
public:
static LexicalEnvironmentObject* createTemplateObject(JSContext* cx,
Handle<LexicalScope*> scope,
HandleObject enclosing,
gc::InitialHeap heap);
static LexicalEnvironmentObject* create(JSContext* cx, Handle<LexicalScope*> scope,
HandleObject enclosing, gc::InitialHeap heap);
static LexicalEnvironmentObject* create(JSContext* cx, Handle<LexicalScope*> scope,
AbstractFramePtr frame);
static LexicalEnvironmentObject* createGlobal(JSContext* cx, Handle<GlobalObject*> global);

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

@ -5212,43 +5212,20 @@ IsItemTooSmallForActiveLayer(nsIFrame* aFrame)
{
nsIntRect visibleDevPixels = aFrame->GetVisualOverflowRectRelativeToSelf().ToOutsidePixels(
aFrame->PresContext()->AppUnitsPerDevPixel());
static const int MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS = 16;
return visibleDevPixels.Size() <
nsIntSize(MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS, MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS);
}
static void
SetAnimationPerformanceWarningForTooSmallItem(nsIFrame* aFrame,
nsCSSPropertyID aProperty)
{
// We use ToNearestPixels() here since ToOutsidePixels causes some sort of
// errors. See https://bugzilla.mozilla.org/show_bug.cgi?id=1258904#c19
nsIntRect visibleDevPixels = aFrame->GetVisualOverflowRectRelativeToSelf().ToNearestPixels(
aFrame->PresContext()->AppUnitsPerDevPixel());
// Set performance warning only if the visible dev pixels is not empty
// because dev pixels is empty if the frame has 'preserve-3d' style.
if (visibleDevPixels.IsEmpty()) {
return;
}
EffectCompositor::SetPerformanceWarning(aFrame, aProperty,
AnimationPerformanceWarning(
AnimationPerformanceWarning::Type::ContentTooSmall,
{ visibleDevPixels.Width(), visibleDevPixels.Height() }));
nsIntSize(gfxPrefs::LayoutMinActiveLayerSize(),
gfxPrefs::LayoutMinActiveLayerSize());
}
/* static */ bool
nsDisplayOpacity::NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
{
if (ActiveLayerTracker::IsStyleAnimated(aBuilder, aFrame,
eCSSProperty_opacity) ||
EffectCompositor::HasAnimationsForCompositor(aFrame,
eCSSProperty_opacity)) {
if (!IsItemTooSmallForActiveLayer(aFrame)) {
return true;
}
SetAnimationPerformanceWarningForTooSmallItem(aFrame, eCSSProperty_opacity);
if (EffectCompositor::HasAnimationsForCompositor(aFrame,
eCSSProperty_opacity) ||
(ActiveLayerTracker::IsStyleAnimated(aBuilder, aFrame,
eCSSProperty_opacity) &&
!IsItemTooSmallForActiveLayer(aFrame))) {
return true;
}
return false;
}
@ -6881,17 +6858,20 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
bool
nsDisplayTransform::MayBeAnimated(nsDisplayListBuilder* aBuilder)
{
// Here we check if the *post-transform* bounds of this item are big enough
// to justify an active layer.
if (ActiveLayerTracker::IsStyleAnimated(aBuilder,
mFrame,
eCSSProperty_transform) ||
EffectCompositor::HasAnimationsForCompositor(mFrame,
eCSSProperty_transform)) {
if (!IsItemTooSmallForActiveLayer(mFrame)) {
return true;
}
SetAnimationPerformanceWarningForTooSmallItem(mFrame, eCSSProperty_transform);
// If EffectCompositor::HasAnimationsForCompositor() is true then we can
// completely bypass the main thread for this animation, so it is always
// worthwhile.
// For ActiveLayerTracker::IsStyleAnimated() cases the main thread is
// already involved so there is less to be gained.
// Therefore we check that the *post-transform* bounds of this item are
// big enough to justify an active layer.
if (EffectCompositor::HasAnimationsForCompositor(mFrame,
eCSSProperty_transform) ||
(ActiveLayerTracker::IsStyleAnimated(aBuilder,
mFrame,
eCSSProperty_transform) &&
!IsItemTooSmallForActiveLayer(mFrame))) {
return true;
}
return false;
}

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

@ -55,12 +55,10 @@ public:
*/
PreEffectsVisualOverflowCollector(nsIFrame* aFirstContinuation,
nsIFrame* aCurrentFrame,
const nsRect& aCurrentFrameOverflowArea,
bool aCheckPreEffectsBBoxPropCache)
const nsRect& aCurrentFrameOverflowArea)
: mFirstContinuation(aFirstContinuation)
, mCurrentFrame(aCurrentFrame)
, mCurrentFrameOverflowArea(aCurrentFrameOverflowArea)
, mCheckPreEffectsBBoxPropCache(aCheckPreEffectsBBoxPropCache)
{
NS_ASSERTION(!mFirstContinuation->GetPrevContinuation(),
"We want the first continuation here");
@ -69,7 +67,7 @@ public:
virtual void AddBox(nsIFrame* aFrame) override {
nsRect overflow = (aFrame == mCurrentFrame)
? mCurrentFrameOverflowArea
: GetPreEffectsVisualOverflowRect(aFrame, mCheckPreEffectsBBoxPropCache);
: GetPreEffectsVisualOverflowRect(aFrame);
mResult.UnionRect(mResult, overflow + aFrame->GetOffsetTo(mFirstContinuation));
}
@ -79,72 +77,25 @@ public:
private:
static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame,
bool aCheckPropCache) {
static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) {
nsRect* r = aFrame->Properties().Get(nsIFrame::PreEffectsBBoxProperty());
if (r) {
return *r;
}
// Despite the fact that we're invoked for frames with SVG effects applied,
// we can actually get here. All continuations and IB split siblings of a
// frame with SVG effects applied will have the PreEffectsBBoxProperty
// property set on them. Therefore, the frames that are passed to us will
// always have that property set...well, with one exception. If the frames
// for an element with SVG effects applied have been subject to an "IB
// split", then the block frame(s) that caused the split will have been
// wrapped in anonymous, inline-block, nsBlockFrames of pseudo-type
// nsCSSAnonBoxes::mozAnonymousBlock. These "IB split sibling" anonymous
// blocks will have the PreEffectsBBoxProperty property set on them, but
// they will never be passed to us. Instead, we'll be passed the block
// children that they wrap, which don't have the PreEffectsBBoxProperty
// property set on them. This is actually okay. What we care about is
// collecting the _pre_ effects visual overflow rects of the frames to
// which the SVG effects have been applied. Since the IB split results in
// any overflow rect adjustments for transforms, effects, etc. taking
// place on the anonymous block wrappers, the wrapped children are left
// with their overflow rects unaffected. In other words, calling
// GetVisualOverflowRect() on the children will return their pre-effects
// visual overflow rects, just as we need.
//
// A couple of tests that demonstrate the IB split and cause us to get here
// are:
//
// * reftests/svg/svg-integration/clipPath-html-06.xhtml
// * reftests/svg/svg-integration/clipPath-html-06-extref.xhtml
//
// If we ever got passed a frame with the PreTransformOverflowAreasProperty
// property set, that would be bad, since then our GetVisualOverflowRect()
// call would give us the post-effects, and post-transform, overflow rect.
//
// There is one more exceptions, in
// nsStyleImageLayers::Layer::CalcDifference, we do not add
// nsChangeHint_UpdateOverflow hint when image mask(not SVG mask) property
// value changed, since replace image mask does not cause layout change.
// So even if we apply a new mask image to this frame,
// PreEffectsBBoxProperty might still left empty.
#ifdef DEBUG
if (aCheckPropCache) {
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
bool mightHaveNoneSVGMask =
nsSVGEffects::GetEffectProperties(firstFrame).MightHaveNoneSVGMask();
// Having PreTransformOverflowAreasProperty cached means
// GetVisualOverflowRect() will return post-effect rect, which is not what
// we want. This function intentional reports pre-effect rect. But it does
// not matter if there is no SVG effect on this frame, since no effect
// means post-effect rect matches pre-effect rect.
if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) {
nsOverflowAreas* preTransformOverflows =
aFrame->Properties().Get(aFrame->PreTransformOverflowAreasProperty());
NS_ASSERTION(mightHaveNoneSVGMask ||
aFrame->GetParent()->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::mozAnonymousBlock,
"How did we getting here, then?");
MOZ_ASSERT(!preTransformOverflows,
"GetVisualOverflowRect() won't return the pre-effects rect!");
}
bool hasEffect = nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame);
nsOverflowAreas* preTransformOverflows =
aFrame->Properties().Get(aFrame->PreTransformOverflowAreasProperty());
// Having PreTransformOverflowAreasProperty means GetVisualOverflowRect()
// will return post-effect rect, which is not what we want, this function
// intentional reports pre-effect rect. But it does not matter if there is
// no SVG effect on this frame, since no effect means post-effect rect
// matches pre-effect rect.
MOZ_ASSERT(!hasEffect || !preTransformOverflows,
"GetVisualOverflowRect() won't return the pre-effects rect!");
#endif
return aFrame->GetVisualOverflowRect();
}
@ -153,7 +104,6 @@ private:
nsIFrame* mCurrentFrame;
const nsRect& mCurrentFrameOverflowArea;
nsRect mResult;
bool mCheckPreEffectsBBoxPropCache;
};
/**
@ -164,15 +114,13 @@ static nsRect
GetPreEffectsVisualOverflowUnion(nsIFrame* aFirstContinuation,
nsIFrame* aCurrentFrame,
const nsRect& aCurrentFramePreEffectsOverflow,
const nsPoint& aFirstContinuationToUserSpace,
bool aCheckPreEffectsBBoxPropCache)
const nsPoint& aFirstContinuationToUserSpace)
{
NS_ASSERTION(!aFirstContinuation->GetPrevContinuation(),
"Need first continuation here");
PreEffectsVisualOverflowCollector collector(aFirstContinuation,
aCurrentFrame,
aCurrentFramePreEffectsOverflow,
aCheckPreEffectsBBoxPropCache);
aCurrentFramePreEffectsOverflow);
// Compute union of all overflow areas relative to aFirstContinuation:
nsLayoutUtils::GetAllInFlowBoxes(aFirstContinuation, &collector);
// Return the result in user space:
@ -250,8 +198,7 @@ nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame)
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame);
// 'r' is in "user space":
nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(),
GetOffsetToBoundingBox(firstFrame),
true);
GetOffsetToBoundingBox(firstFrame));
return nsLayoutUtils::RectToGfxRect(r,
aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel());
}
@ -313,11 +260,7 @@ nsRect
nsLayoutUtils::RectToGfxRect(
GetPreEffectsVisualOverflowUnion(firstFrame, aFrame,
aPreEffectsOverflowRect,
firstFrameToBoundingBox,
false /* See the beginning of the
comment above this function to
know why we skip this
checking. */),
firstFrameToBoundingBox),
aFrame->PresContext()->AppUnitsPerCSSPixel());
overrideBBox.RoundOut();

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

@ -471,10 +471,6 @@ public class FxAccountStatusFragment
accountProfileInformationReceiver = new FxAccountProfileInformationReceiver();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(accountProfileInformationReceiver, intentFilter);
// profilePreference is set during onCreate, so it's definitely not null here.
final float cornerRadius = getResources().getDimension(R.dimen.fxaccount_profile_image_width) / 2;
profileAvatarTarget = new PicassoPreferenceIconTarget(getResources(), profilePreference, cornerRadius);
refresh();
}
@ -518,6 +514,10 @@ public class FxAccountStatusFragment
throw new IllegalArgumentException("fxAccount must not be null");
}
// profilePreference is set during onCreate, so it's definitely not null here.
final float cornerRadius = getResources().getDimension(R.dimen.fxaccount_profile_image_width) / 2;
profileAvatarTarget = new PicassoPreferenceIconTarget(getResources(), profilePreference, cornerRadius);
updateProfileInformation();
updateAuthServerPreference();
updateSyncServerPreference();

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

@ -1283,6 +1283,7 @@ GatherTelemetryForSingleSCT(const ct::VerifiedSCT& verifiedSct)
void
GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList,
bool isEV,
const CertificateTransparencyInfo& info)
{
if (!info.enabled) {
@ -1306,6 +1307,59 @@ GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList,
// Note that sctsCount can also be 0 in case we've received SCT binary data,
// but it failed to parse (e.g. due to unsupported CT protocol version).
Telemetry::Accumulate(Telemetry::SSL_SCTS_PER_CONNECTION, sctsCount);
// Report CT Policy compliance of EV certificates.
if (isEV) {
uint32_t evCompliance = 0;
switch (info.policyCompliance) {
case ct::CTPolicyCompliance::Compliant:
evCompliance = 1;
break;
case ct::CTPolicyCompliance::NotEnoughScts:
evCompliance = 2;
break;
case ct::CTPolicyCompliance::NotDiverseScts:
evCompliance = 3;
break;
case ct::CTPolicyCompliance::Unknown:
default:
MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
}
Telemetry::Accumulate(Telemetry::SSL_CT_POLICY_COMPLIANCE_OF_EV_CERTS,
evCompliance);
}
// Get the root cert.
CERTCertListNode* rootNode = CERT_LIST_TAIL(certList);
MOZ_ASSERT(rootNode);
if (!rootNode) {
return;
}
MOZ_ASSERT(!CERT_LIST_END(rootNode, certList));
if (CERT_LIST_END(rootNode, certList)) {
return;
}
CERTCertificate* rootCert = rootNode->cert;
MOZ_ASSERT(rootCert);
if (!rootCert) {
return;
}
// Report CT Policy compliance by CA.
switch (info.policyCompliance) {
case ct::CTPolicyCompliance::Compliant:
AccumulateTelemetryForRootCA(
Telemetry::SSL_CT_POLICY_COMPLIANT_CONNECTIONS_BY_CA, rootCert);
break;
case ct::CTPolicyCompliance::NotEnoughScts:
case ct::CTPolicyCompliance::NotDiverseScts:
AccumulateTelemetryForRootCA(
Telemetry::SSL_CT_POLICY_NON_COMPLIANT_CONNECTIONS_BY_CA, rootCert);
break;
case ct::CTPolicyCompliance::Unknown:
default:
MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
}
}
// Note: Takes ownership of |peerCertChain| if SECSuccess is not returned.
@ -1390,6 +1444,7 @@ AuthCertificate(CertVerifier& certVerifier,
SECSuccess);
GatherSuccessfulValidationTelemetry(certList);
GatherCertificateTransparencyTelemetry(certList,
/*isEV*/ evOidPolicy != SEC_OID_UNKNOWN,
certificateTransparencyInfo);
// The connection may get terminated, for example, if the server requires

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

@ -1157,4 +1157,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1496157927859000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1496246555187000);

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

@ -16,7 +16,7 @@
123plons.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
123test.de: did not receive HSTS header
126ium.moe: could not connect to host
127011-networks.ch: could not connect to host
127011-networks.ch: did not receive HSTS header
12vpnchina.com: could not connect to host
16packets.com: could not connect to host
1a-jva.de: did not receive HSTS header
@ -157,7 +157,7 @@ ajmahal.com: could not connect to host
akclinics.org: did not receive HSTS header
akombakom.net: did not receive HSTS header
akselimedia.fi: did not receive HSTS header
akutun.cl: did not receive HSTS header
akutun.cl: could not connect to host
al-shami.net: could not connect to host
aladdin.ie: did not receive HSTS header
alainwolf.net: could not connect to host
@ -197,6 +197,7 @@ altmv.com: max-age too low: 7776000
amaforums.org: could not connect to host
amandaonishi.com: could not connect to host
amavis.org: did not receive HSTS header
amazingfloridagulfhomes.com: could not connect to host
ameho.me: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
american-truck-simulator.de: could not connect to host
american-truck-simulator.net: could not connect to host
@ -263,7 +264,7 @@ apmg-certified.com: did not receive HSTS header
apmg-cyber.com: did not receive HSTS header
apnakliyat.com: did not receive HSTS header
aponkralsunucu.com: could not connect to host
app.lookout.com: could not connect to host
app.lookout.com: did not receive HSTS header
app.manilla.com: could not connect to host
appart.ninja: could not connect to host
appengine.google.com: did not receive HSTS header (error ignored - included regardless)
@ -279,6 +280,7 @@ appson.co.uk: did not receive HSTS header
arabdigitalexpression.org: did not receive HSTS header
aradulconteaza.ro: could not connect to host
aran.me.uk: could not connect to host
arbeitskreis-asyl-eningen.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
arboineuropa.nl: did not receive HSTS header
arbu.eu: could not connect to host
arlen.se: could not connect to host
@ -325,6 +327,7 @@ athaliasoft.com: did not receive HSTS header
athenelive.com: could not connect to host
athul.xyz: did not receive HSTS header
atlex.nl: did not receive HSTS header
atlseccon.com: did not receive HSTS header
atomik.pro: could not connect to host
atop.io: could not connect to host
attimidesigns.com: did not receive HSTS header
@ -333,6 +336,7 @@ aubiosales.com: did not receive HSTS header
aucubin.moe: could not connect to host
audiovisualdevices.com.au: did not receive HSTS header
aufmerksamkeitsstudie.com: could not connect to host
augiero.it: could not connect to host
aujapan.ru: could not connect to host
aurainfosec.com: did not receive HSTS header
aurainfosec.com.au: could not connect to host
@ -347,6 +351,7 @@ authentication.io: could not connect to host
authoritynutrition.com: did not receive HSTS header
auto-serwis.zgorzelec.pl: did not receive HSTS header
auto4trade.nl: could not connect to host
autodeploy.it: could not connect to host
autoepc.ro: did not receive HSTS header
autojuhos.sk: could not connect to host
autokovrik-diskont.ru: did not receive HSTS header
@ -372,6 +377,7 @@ azuxul.fr: could not connect to host
b303.me: did not receive HSTS header
b3orion.com: max-age too low: 0
b64.club: could not connect to host
babelfisch.eu: could not connect to host
baby-click.de: did not receive HSTS header
babybic.hu: did not receive HSTS header
babyhouse.xyz: could not connect to host
@ -403,6 +409,7 @@ baumstark.ca: could not connect to host
baysse.eu: could not connect to host
bazarstupava.sk: could not connect to host
bcbsmagentprofile.com: could not connect to host
bcchack.com: could not connect to host
bccx.com: could not connect to host
bckp.de: did not receive HSTS header
bcm.com.au: max-age too low: 0
@ -497,6 +504,7 @@ bizcms.com: did not receive HSTS header
bizon.sk: did not receive HSTS header
black-armada.com.pl: could not connect to host
black-armada.pl: could not connect to host
black-octopus.ru: could not connect to host
blackburn.link: could not connect to host
blacklane.com: did not receive HSTS header
blackly.uk: max-age too low: 0
@ -540,7 +548,7 @@ bonigo.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_
bonitabrazilian.co.nz: did not receive HSTS header
bookcelerator.com: did not receive HSTS header
booked.holiday: could not connect to host
bookourdjs.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
bookourdjs.com: could not connect to host
boomerang.com: could not connect to host
boosterlearnpro.com: did not receive HSTS header
bootjp.me: did not receive HSTS header
@ -554,7 +562,6 @@ boxcryptor.com: did not receive HSTS header
br3in.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
braineet.com: did not receive HSTS header
brainfork.ml: could not connect to host
brainster.co: could not connect to host
braintreegateway.com: did not receive HSTS header
braintreepayments.com: did not receive HSTS header
brainvation.de: did not receive HSTS header
@ -609,6 +616,7 @@ buttercoin.com: could not connect to host
butterfieldstraining.com: did not receive HSTS header
buybaby.eu: did not receive HSTS header
buyfox.de: did not receive HSTS header
buzzconcert.com: could not connect to host
bws16.de: did not receive HSTS header
by4cqb.cn: could not connect to host
bypassed.press: could not connect to host
@ -634,6 +642,7 @@ cake.care: could not connect to host
calendarr.com: did not receive HSTS header
calgaryconstructionjobs.com: did not receive HSTS header
calix.com: max-age too low: 0
call.me: did not receive HSTS header
calltrackingreports.com: could not connect to host
calvin.me: max-age too low: 2592000
calvinallen.net: did not receive HSTS header
@ -725,6 +734,7 @@ cheesetart.my: could not connect to host
cheetah85.de: could not connect to host
chejianer.cn: did not receive HSTS header
chensir.net: could not connect to host
chepaofen.com: could not connect to host
cherysunzhang.com: max-age too low: 7776000
chihiro.xyz: could not connect to host
chijiokeindustries.co.uk: could not connect to host
@ -738,7 +748,6 @@ chopperforums.com: did not receive HSTS header
chotu.net: could not connect to host
chris-web.info: could not connect to host
chrisandsarahinasia.com: did not receive HSTS header
chrisbrown.id.au: could not connect to host
chrisfaber.com: could not connect to host
chriskyrouac.com: could not connect to host
christiaandruif.nl: could not connect to host
@ -778,6 +787,7 @@ clemovementlaw.com: could not connect to host
clerkendweller.uk: could not connect to host
clickandgo.com: did not receive HSTS header
clickandshoot.nl: did not receive HSTS header
clickgram.biz: could not connect to host
clientsecure.me: could not connect to host
clint.id.au: max-age too low: 0
clintonbloodworth.com: could not connect to host
@ -791,6 +801,7 @@ cloudcy.net: could not connect to host
clouddesktop.co.nz: could not connect to host
cloudey.net: did not receive HSTS header
cloudflare.com: did not receive HSTS header
cloudily.com: could not connect to host
cloudimag.es: could not connect to host
cloudlink.club: could not connect to host
cloudns.com.au: could not connect to host
@ -813,8 +824,6 @@ cmsbattle.com: could not connect to host
cmscafe.ru: did not receive HSTS header
cn.search.yahoo.com: did not receive HSTS header
cni-certing.it: max-age too low: 0
cnwage.com: could not connect to host
cnwarn.com: could not connect to host
co50.com: did not receive HSTS header
cocaine-import.agency: could not connect to host
cocktailfuture.fr: could not connect to host
@ -828,6 +837,7 @@ codeforce.io: could not connect to host
codelayer.ca: could not connect to host
codemonkeyrawks.net: did not receive HSTS header
codepoet.de: could not connect to host
codepult.com: could not connect to host
codepx.com: did not receive HSTS header
codewiththepros.org: could not connect to host
codiva.io: max-age too low: 2592000
@ -866,6 +876,7 @@ consciousandglamorous.com: could not connect to host
console.python.org: did not receive HSTS header
constructionjobs.com: did not receive HSTS header
contactbig.com: did not receive HSTS header
containerstatistics.com: could not connect to host
contarkos.xyz: could not connect to host
content-api-dev.azurewebsites.net: could not connect to host
continuumgaming.com: could not connect to host
@ -878,7 +889,8 @@ cordial-restaurant.com: did not receive HSTS header
core.mx: could not connect to host
core4system.de: could not connect to host
corenetworking.de: could not connect to host
corgicloud.com: could not connect to host
corgicloud.com: did not receive HSTS header
cormactagging.ie: could not connect to host
cormilu.com.br: did not receive HSTS header
correctpaardbatterijnietje.nl: did not receive HSTS header
corruption-mc.net: could not connect to host
@ -888,7 +900,6 @@ count.sh: could not connect to host
couragewhispers.ca: did not receive HSTS header
coursdeprogrammation.com: could not connect to host
coursella.com: did not receive HSTS header
cousincouples.com: did not receive HSTS header
covenantbank.net: could not connect to host
coverduck.ru: could not connect to host
cpuvinf.eu.org: could not connect to host
@ -937,8 +948,10 @@ csgodicegame.com: did not receive HSTS header
csgoelemental.com: could not connect to host
csgokings.eu: could not connect to host
csohack.tk: could not connect to host
csokolade.hu: could not connect to host
cspbuilder.info: could not connect to host
cspvalidator.org: did not receive HSTS header
csru.net: could not connect to host
csvape.com: did not receive HSTS header
ct-status.org: could not connect to host
ct.search.yahoo.com: did not receive HSTS header
@ -1081,6 +1094,7 @@ diamante.ro: could not connect to host
diarbag.us: did not receive HSTS header
diasp.cz: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
dick.red: could not connect to host
die-partei-reutlingen.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
diedrich.co: did not receive HSTS header
digidroom.be: did not receive HSTS header
digioccumss.ddns.net: could not connect to host
@ -1161,26 +1175,30 @@ drtroyhendrickson.com: could not connect to host
drumbandesperanto.nl: could not connect to host
ds-christiansen.de: did not receive HSTS header
dshiv.io: could not connect to host
dubrovskiy.net: could not connect to host
dubrovskiy.pro: could not connect to host
duesee.org: could not connect to host
dullsir.com: did not receive HSTS header
duria.de: max-age too low: 3600
dustri.org: did not receive HSTS header
dutchessuganda.com: did not receive HSTS header
dutchrank.com: could not connect to host
dwhd.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
dworzak.ch: could not connect to host
dycontrol.de: could not connect to host
dylanscott.com.au: did not receive HSTS header
dymersion.com: did not receive HSTS header
dynamic-innovations.net: could not connect to host
dzimejl.sk: did not receive HSTS header
dzlibs.io: could not connect to host
dzndk.net: could not connect to host
dzndk.org: could not connect to host
e-aut.net: did not receive HSTS header
e-deca2.org: did not receive HSTS header
e-sa.com: did not receive HSTS header
e3amn2l.com: could not connect to host
earlybirdsnacks.com: could not connect to host
earthrise16.com: could not connect to host
easez.net: did not receive HSTS header
eason-yang.com: could not connect to host
easychiller.org: could not connect to host
easyhaul.com: did not receive HSTS header
eatlowcarb.de: did not receive HSTS header
@ -1260,6 +1278,7 @@ encode.space: did not receive HSTS header
encoder.pw: could not connect to host
encontrebarato.com.br: did not receive HSTS header
encrypted.google.com: did not receive HSTS header (error ignored - included regardless)
encryptedaudience.com: could not connect to host
end.pp.ua: could not connect to host
endlessdark.net: max-age too low: 600
endlessdiy.ca: could not connect to host
@ -1293,6 +1312,7 @@ equilibre-yoga-jennifer-will.com: could not connect to host
erawanarifnugroho.com: did not receive HSTS header
eressea.xyz: could not connect to host
eridanus.uk: could not connect to host
erikhubers.nl: could not connect to host
ernaehrungsberatung-rapperswil.ch: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
ernaehrungsberatung-zurich.ch: could not connect to host
ernesto.at: could not connect to host
@ -1341,6 +1361,7 @@ exfiles.cz: did not receive HSTS header
exgravitus.com: could not connect to host
exitus.jp: max-age too low: 0
exno.co: could not connect to host
expatads.com: could not connect to host
expertmile.com: did not receive HSTS header
expoundite.net: did not receive HSTS header
expressfinance.co.za: did not receive HSTS header
@ -1384,8 +1405,6 @@ fatgeekflix.net: could not connect to host
fatherhood.gov: did not receive HSTS header
fatlossguide.xyz: could not connect to host
fatox.de: could not connect to host
fatzebra.com.au: could not connect to host
fawkex.me: could not connect to host
fayolle.info: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
fbox.li: could not connect to host
fdj.im: could not connect to host
@ -1406,13 +1425,14 @@ fexmen.com: could not connect to host
ffmradio.de: did not receive HSTS header
fhdhelp.de: could not connect to host
fhdhilft.de: could not connect to host
fierman.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
fifieldtech.com: could not connect to host
fiftyshadesofluca.ml: could not connect to host
fig.co: did not receive HSTS header
fightr.co: could not connect to host
fikt.space: could not connect to host
filmipop.com: max-age too low: 0
finalgear.com: could not connect to host
finalgear.com: did not receive HSTS header
financieringsportaal.nl: did not receive HSTS header
finanzkontor.net: could not connect to host
findtutorsnearme.com: did not receive HSTS header
@ -1452,6 +1472,7 @@ florianlillpopp.de: max-age too low: 10
floridaescapes.co.uk: did not receive HSTS header
flouartistique.ch: could not connect to host
flow.pe: could not connect to host
flow.su: could not connect to host
flowersandclouds.com: could not connect to host
flowlo.me: could not connect to host
flushstudios.com: did not receive HSTS header
@ -1465,6 +1486,7 @@ foodievenues.com: could not connect to host
footballmapped.com: could not connect to host
foraje-profesionale.ro: did not receive HSTS header
forbook.net: could not connect to host
fordbydesign.com: could not connect to host
foreignexchangeresource.com: did not receive HSTS header
foreveralone.io: could not connect to host
forex-dan.com: did not receive HSTS header
@ -1520,7 +1542,6 @@ ftctele.com: did not receive HSTS header
fuckbilibili.com: did not receive HSTS header
fuckgfw233.org: could not connect to host
fukushima-web.com: did not receive HSTS header
fumo.se: could not connect to host
fundacionhijosdelsol.org: could not connect to host
funkyweddingideas.com.au: could not connect to host
funnyang.com: could not connect to host
@ -1624,7 +1645,6 @@ gh16.com.ar: could not connect to host
gheorghesarcov.ga: could not connect to host
gheorghesarcov.tk: could not connect to host
gietvloergarant.nl: did not receive HSTS header
gifzilla.net: could not connect to host
gigacloud.org: max-age too low: 0
gilgaz.com: did not receive HSTS header
gilly.berlin: did not receive HSTS header
@ -1693,6 +1713,7 @@ gpsfix.cz: could not connect to host
gpstuner.com: did not receive HSTS header
gracesofgrief.com: max-age too low: 86400
gradienthosting.co.uk: did not receive HSTS header
graffen.dk: did not receive HSTS header
grandmascookieblog.com: did not receive HSTS header
grantedby.me: could not connect to host
graph.no: did not receive HSTS header
@ -1749,6 +1770,7 @@ gyboche.science: could not connect to host
gycis.me: could not connect to host
gypthecat.com: max-age too low: 604800
gyz.io: could not connect to host
gzitech.com: could not connect to host
h2check.org: could not connect to host
haarkliniek.com: did not receive HSTS header
habanaavenue.com: did not receive HSTS header
@ -1788,6 +1810,7 @@ hardfalcon.net: could not connect to host
hardline.xyz: could not connect to host
haribosupermix.com: could not connect to host
harmonycosmetic.com: max-age too low: 300
harrisonsand.com: could not connect to host
harristony.com: could not connect to host
hartmancpa.com: did not receive HSTS header
harvestrenewal.org: did not receive HSTS header
@ -1824,6 +1847,7 @@ helpmebuild.com: did not receive HSTS header
hemdal.se: could not connect to host
hencagon.com: could not connect to host
henriknoerr.com: could not connect to host
heritagedentistry.ca: could not connect to host
hermes-net.de: could not connect to host
herrenfahrt.com: did not receive HSTS header
herzbotschaft.de: did not receive HSTS header
@ -1834,6 +1858,7 @@ hicn.gq: could not connect to host
hiddendepth.ie: max-age too low: 0
hiddenmail.xyz: could not connect to host
hiddenrefuge.eu.org: could not connect to host
hideftv.deals: did not receive HSTS header
highseer.com: did not receive HSTS header
highsurf-miyazaki.com: did not receive HSTS header
highvelocitydesign.com: could not connect to host
@ -1888,12 +1913,14 @@ http418.xyz: could not connect to host
httpstatuscode418.xyz: could not connect to host
hu.search.yahoo.com: did not receive HSTS header
huarongdao.com: max-age too low: 1
huffduffer.com: could not connect to host
hugocollignon.fr: could not connect to host
hugosleep.com.au: did not receive HSTS header
humblefinances.com: could not connect to host
humeurs.net: could not connect to host
humpteedumptee.in: did not receive HSTS header
huntshomeinspections.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
hupp.se: could not connect to host
hurricanelabs.com: did not receive HSTS header
huskybutt.dog: could not connect to host
hydra.ws: could not connect to host
@ -1943,6 +1970,7 @@ ihrnationalrat.ch: could not connect to host
ihsbsd.me: could not connect to host
ihsbsd.tk: could not connect to host
ihuanmeng.com: did not receive HSTS header
ikkatsu-satei.jp: did not receive HSTS header
ikujii.com: max-age too low: 0
ikwilguidobellen.nl: did not receive HSTS header
ilbuongiorno.it: did not receive HSTS header
@ -1953,7 +1981,7 @@ ilona.graphics: max-age too low: 3600
iluvscotland.co.uk: did not receive HSTS header
imakepoems.net: could not connect to host
ime.moe: could not connect to host
imguoguo.com: could not connect to host
imguoguo.com: did not receive HSTS header
imim.pw: did not receive HSTS header
immersionwealth.com: could not connect to host
immoprotect.ca: did not receive HSTS header
@ -1977,6 +2005,7 @@ incendiary-arts.com: could not connect to host
inchomatic.com: did not receive HSTS header
indoorskiassen.nl: did not receive HSTS header
indust.me: did not receive HSTS header
inexpensivecomputers.net: could not connect to host
infcof.com: max-age too low: 0
infilock.com: could not connect to host
infinitude.xyz: could not connect to host
@ -2046,7 +2075,7 @@ ishillaryclintoninprisonyet.com: could not connect to host
isitamor.pm: could not connect to host
iskaz.rs: did not receive HSTS header
isogram.nl: could not connect to host
israkurort.com: did not receive HSTS header
israkurort.com: could not connect to host
isslshop.com: could not connect to host
istaspirtslietas.lv: did not receive HSTS header
it-go.net: did not receive HSTS header
@ -2101,10 +2130,10 @@ jardins-utopie.net: [Exception... "Component returned failure code: 0x80004005 (
jaredeberle.org: did not receive HSTS header
jaroslavtrsek.cz: did not receive HSTS header
jartza.org: could not connect to host
jasmineconseil.com: did not receive HSTS header
jasmineconseil.com: could not connect to host
jasonrobinson.me: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
jasonroe.me: did not receive HSTS header
jasonsansone.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
jasonsansone.com: could not connect to host
jastoria.pl: could not connect to host
jayblock.com: did not receive HSTS header
jayschulman.com: did not receive HSTS header
@ -2124,7 +2153,7 @@ jeremye77.com: could not connect to host
jesorsenville.com: did not receive HSTS header
jessicabenedictus.nl: could not connect to host
jesuisformidable.nl: could not connect to host
jetaprices.com: could not connect to host
jetaprices.com: max-age too low: 0
jetsetcharge.com: could not connect to host
jetsetpay.com: could not connect to host
jettshome.org: could not connect to host
@ -2162,6 +2191,7 @@ jonn.me: could not connect to host
joostbovee.nl: did not receive HSTS header
jordanhamilton.me: could not connect to host
joretapo.fr: did not receive HSTS header
jornadasciberdefensa2016.es: did not receive HSTS header
josahrens.me: could not connect to host
joshi.su: could not connect to host
joshstroup.me: could not connect to host
@ -2195,7 +2225,6 @@ jznet.org: max-age too low: 86400
k-dev.de: could not connect to host
ka-clan.com: could not connect to host
kabuabc.com: did not receive HSTS header
kabus.org: could not connect to host
kadioglumakina.com.tr: did not receive HSTS header
kaela.design: could not connect to host
kahopoon.net: could not connect to host
@ -2303,7 +2332,6 @@ krayx.com: could not connect to host
kreavis.com: did not receive HSTS header
kredite.sale: could not connect to host
kriegt.es: could not connect to host
kristikala.nl: could not connect to host
krmela.com: could not connect to host
kroetenfuchs.de: could not connect to host
kropkait.pl: could not connect to host
@ -2354,6 +2382,7 @@ langenbach.rocks: could not connect to host
langhun.me: did not receive HSTS header
laobox.fr: could not connect to host
laozhu.me: did not receive HSTS header
laquack.com: did not receive HSTS header
laserfuchs.de: did not receive HSTS header
lashstuff.com: did not receive HSTS header
lask.in: did not receive HSTS header
@ -2408,6 +2437,7 @@ lgrs.com.au: did not receive HSTS header
lgts.se: could not connect to host
li.search.yahoo.com: did not receive HSTS header
liaillustr.at: did not receive HSTS header
liam-w.com: did not receive HSTS header
liamjack.fr: could not connect to host
lianye.in: could not connect to host
lianye1.cc: could not connect to host
@ -2443,6 +2473,7 @@ limiteddata.co.uk: could not connect to host
limpido.it: could not connect to host
lincolnwayflorist.com: could not connect to host
lindberg.io: did not receive HSTS header
lingerie.com.br: could not connect to host
lingotaxi.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
lingros-test.tk: could not connect to host
linguaquote.com: did not receive HSTS header
@ -2536,6 +2567,7 @@ maarten.nyc: did not receive HSTS header
maartenvandekamp.nl: did not receive HSTS header
mac-torrents.me: did not receive HSTS header
macchaberrycream.com: could not connect to host
macchedil.com: did not receive HSTS header
macdj.tk: could not connect to host
macgeneral.de: did not receive HSTS header
machon.biz: could not connect to host
@ -2548,7 +2580,6 @@ mafamane.com: could not connect to host
maff.scot: did not receive HSTS header
mafiareturns.com: max-age too low: 2592000
magenx.com: did not receive HSTS header
magicbroccoli.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
mahamed91.pw: could not connect to host
mail-settings.google.com: did not receive HSTS header (error ignored - included regardless)
mail.google.com: did not receive HSTS header (error ignored - included regardless)
@ -2584,6 +2615,7 @@ mario.party: did not receive HSTS header
markaconnor.com: could not connect to host
markayapilandirma.com: could not connect to host
market.android.com: did not receive HSTS header (error ignored - included regardless)
markprof.ru: could not connect to host
markrego.com: could not connect to host
marktboten.de: did not receive HSTS header
markus-dev.com: did not receive HSTS header
@ -2608,6 +2640,7 @@ matsuz.com: could not connect to host
mattberryman.com: did not receive HSTS header
mattcoles.io: did not receive HSTS header
mattfin.ch: could not connect to host
matthewkenny.co.uk: could not connect to host
matthewprenger.com: could not connect to host
matthiassteen.be: max-age too low: 0
mattressinsider.com: max-age too low: 3153600
@ -2645,7 +2678,6 @@ medwayindia.com: could not connect to host
meedoenzaanstad.nl: did not receive HSTS header
meetings2.com: did not receive HSTS header
meetscompany.jp: did not receive HSTS header
megablogging.org: could not connect to host
megakiste.de: could not connect to host
megashur.se: did not receive HSTS header
megaxchange.com: did not receive HSTS header
@ -2681,7 +2713,7 @@ mfiles.pl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_
mh-bloemen.co.jp: could not connect to host
mhdsyarif.com: did not receive HSTS header
mhealthdemocamp.com: could not connect to host
mhertel.com: could not connect to host
mhertel.com: did not receive HSTS header
mhict.nl: max-age too low: 0
mhx.pw: could not connect to host
mia.to: could not connect to host
@ -2763,7 +2795,6 @@ moneytoday.com: max-age too low: 0
monitman.com: could not connect to host
montenero.pl: could not connect to host
moon.lc: could not connect to host
moonless.net: could not connect to host
moov.is: could not connect to host
moparisthebest.biz: could not connect to host
moparisthebest.info: could not connect to host
@ -2783,10 +2814,12 @@ motoryz.com: max-age too low: 300
mottvd.com: could not connect to host
moula.com.au: did not receive HSTS header
mountainmusicpromotions.com: did not receive HSTS header
movepin.com: did not receive HSTS header
moviesabout.net: could not connect to host
moy-gorod.od.ua: did not receive HSTS header
moy.cat: did not receive HSTS header
mp3juices.is: could not connect to host
mpintaamalabanna.it: could not connect to host
mqas.net: could not connect to host
mrdani.net: could not connect to host
mrettich.org: did not receive HSTS header
@ -2908,6 +2941,7 @@ netloanusa.com: max-age too low: 0
netmagik.com: did not receive HSTS header
nettefoundation.com: could not connect to host
netulo.com: could not connect to host
networx-online.de: could not connect to host
netzbit.de: could not connect to host
netzpolitik.org: did not receive HSTS header
netztest.at: did not receive HSTS header
@ -2944,6 +2978,7 @@ nien.chat: could not connect to host
nightwinds.tk: could not connect to host
nightx.uk: could not connect to host
niho.jp: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
niklas.pw: could not connect to host
nikomo.fi: could not connect to host
ninchisho-online.com: did not receive HSTS header
ninhs.org: did not receive HSTS header
@ -2957,6 +2992,7 @@ nmctest.net: could not connect to host
nnya.cat: could not connect to host
no17sifangjie.cc: could not connect to host
nocallaghan.com: could not connect to host
noclegi-online.pl: did not receive HSTS header
noctinus.tk: could not connect to host
nodebrewery.com: could not connect to host
nodetemple.com: could not connect to host
@ -3006,6 +3042,7 @@ nullpoint.at: did not receive HSTS header
number.me: did not receive HSTS header
numericacu.com: did not receive HSTS header
numero-di-telefono.it: could not connect to host
numista.com: did not receive HSTS header
nuos.org: could not connect to host
nurserybook.co: did not receive HSTS header
nutleyeducationalfoundation.org: did not receive HSTS header
@ -3017,6 +3054,7 @@ nwa.xyz: could not connect to host
nwgh.org: max-age too low: 86400
nwork.media: could not connect to host
nyantec.com: did not receive HSTS header
nys-hk.com: could not connect to host
nysepho.pw: could not connect to host
nystart.no: did not receive HSTS header
nz.search.yahoo.com: max-age too low: 172800
@ -3254,6 +3292,7 @@ piggott.me.uk: did not receive HSTS header
pilgermaske.org: did not receive HSTS header
piligrimname.com: could not connect to host
pillowandpepper.com: did not receive HSTS header
pincodeit.com: could not connect to host
pippen.io: could not connect to host
piratedb.com: could not connect to host
piratedot.com: could not connect to host
@ -3264,7 +3303,6 @@ pirati.cz: max-age too low: 604800
pirlitu.com: did not receive HSTS header
pisexy.me: did not receive HSTS header
pisidia.de: could not connect to host
pittaya.com: could not connect to host
pittonpreschool.com: did not receive HSTS header
pixel.google.com: did not receive HSTS header (error ignored - included regardless)
pixelcode.com.au: could not connect to host
@ -3345,12 +3383,14 @@ pro-zone.com: could not connect to host
prodpad.com: did not receive HSTS header
professionalboundaries.com: did not receive HSTS header
profi-durchgangsmelder.de: did not receive HSTS header
profpay.com: could not connect to host
profundr.com: could not connect to host
progblog.net: could not connect to host
progg.no: could not connect to host
progress-technologies.com: could not connect to host
prohostonline.fi: could not connect to host
projectdp.net: could not connect to host
projectmercury.space: could not connect to host
promecon-gmbh.de: did not receive HSTS header
prontocleaners.co.uk: could not connect to host
prontolight.com: did not receive HSTS header
@ -3364,8 +3404,10 @@ proximato.com: could not connect to host
proxybay.al: could not connect to host
proxybay.club: could not connect to host
proxybay.info: did not receive HSTS header
proxybay.top: could not connect to host
prxio.site: did not receive HSTS header
prytkov.com: did not receive HSTS header
psicologia.co.ve: could not connect to host
psw.academy: did not receive HSTS header
psw.consulting: did not receive HSTS header
ptn.moscow: could not connect to host
@ -3419,7 +3461,6 @@ raajheshkannaa.com: could not connect to host
radicaleducation.net: could not connect to host
rafaelcz.de: could not connect to host
railgun.com.cn: could not connect to host
railjob.cn: could not connect to host
rainbowbarracuda.com: could not connect to host
ramonj.nl: could not connect to host
randomcage.com: did not receive HSTS header
@ -3498,6 +3539,7 @@ respostas.com.br: did not receive HSTS header
restchart.com: did not receive HSTS header
retcor.net: could not connect to host
retrotracks.net: max-age too low: 0
reulitz.de: could not connect to host
revealdata.com: did not receive HSTS header
revello.org: did not receive HSTS header
reverie.pw: could not connect to host
@ -3518,7 +3560,6 @@ rideworks.com: did not receive HSTS header
riesenweber.id.au: did not receive HSTS header
right2.org: could not connect to host
righttoknow.ie: did not receive HSTS header
rigolitch.fr: did not receive HSTS header
riiconnect24.net: could not connect to host
rijndael.xyz: could not connect to host
rika.me: could not connect to host
@ -3540,6 +3581,7 @@ robteix.com: did not receive HSTS header
robtex.net: did not receive HSTS header
robtex.org: did not receive HSTS header
rochman.id: could not connect to host
rocketr.net: did not receive HSTS header
rocksberg.net: could not connect to host
rockstarloan.com: max-age too low: 0
roddis.net: did not receive HSTS header
@ -3548,6 +3590,7 @@ rodosto.com: did not receive HSTS header
roeper.party: could not connect to host
roesemann.email: could not connect to host
roguelikecenter.fr: did not receive HSTS header
rolandreed.cn: could not connect to host
romans-place.me.uk: did not receive HSTS header
romulusapp.com: could not connect to host
ronvandordt.info: could not connect to host
@ -3619,7 +3662,7 @@ sandrolittke.de: did not receive HSTS header
sandviks.com: did not receive HSTS header
sangwon.org: could not connect to host
sansemea.com: did not receive HSTS header
sansonehowell.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
sansonehowell.com: could not connect to host
sarah-beckett-harpist.com: did not receive HSTS header
sarahsweetlife.com: could not connect to host
sarakas.com: could not connect to host
@ -3810,11 +3853,11 @@ sitesten.com: did not receive HSTS header
sitsy.ru: did not receive HSTS header
sixtwentyten.com: did not receive HSTS header
skhosting.eu: did not receive HSTS header
skidstresser.com: could not connect to host
skile.ru: could not connect to host
skk.io: could not connect to host
skoda-clever-lead.de: could not connect to host
skoda-im-dialog.de: could not connect to host
skotty.io: did not receive HSTS header
skullhouse.nyc: did not receive HSTS header
skyflix.me: could not connect to host
skyoy.com: did not receive HSTS header
@ -3883,7 +3926,7 @@ somethingnew.xyz: could not connect to host
sonicrainboom.rocks: could not connect to host
soobi.org: did not receive HSTS header
soondy.com: did not receive HSTS header
sotiran.com: did not receive HSTS header
sotiran.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
sotor.de: did not receive HSTS header
soulema.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
soulfulglamour.uk: could not connect to host
@ -3896,6 +3939,7 @@ souyar.us: could not connect to host
sovereignshare.com: could not connect to host
sown.dyndns.org: could not connect to host
spacehq.org: max-age too low: 0
spaggel.nl: could not connect to host
sparelib.com: max-age too low: 3650
spark.team: could not connect to host
sparkbase.cn: could not connect to host
@ -3916,7 +3960,7 @@ sperohub.io: could not connect to host
spherenix.org: could not connect to host
spicydog.tk: could not connect to host
spiegels.nl: could not connect to host
spikeykc.me: could not connect to host
spikeykc.me: did not receive HSTS header
spillmaker.no: did not receive HSTS header
spilsbury.io: could not connect to host
spititout.it: could not connect to host
@ -3974,6 +4018,8 @@ stewartremodelingadvantage.com: did not receive HSTS header
stig.io: did not receive HSTS header
stigroom.com: could not connect to host
stillblackhat.id: could not connect to host
stirlingpoon.com: did not receive HSTS header
stirlingpoon.net: did not receive HSTS header
stirlingpoon.xyz: could not connect to host
stkbn.com: did not receive HSTS header
stmbgr.com: could not connect to host
@ -4005,6 +4051,7 @@ student.andover.edu: did not receive HSTS header
studentresearcher.org: did not receive HSTS header
studentskydenik.cz: could not connect to host
studenttravel.cz: did not receive HSTS header
studinf.xyz: did not receive HSTS header
studiozelden.com: did not receive HSTS header
studybay.com: did not receive HSTS header
studydrive.net: did not receive HSTS header
@ -4045,7 +4092,6 @@ suzukikenichi.com: did not receive HSTS header
sv.search.yahoo.com: did not receive HSTS header
svarovani.tk: could not connect to host
svatba-frantovi.cz: did not receive HSTS header
sweetll.me: could not connect to host
sweetstreats.ca: could not connect to host
swimbee.nl: did not receive HSTS header
swimming.ca: did not receive HSTS header
@ -4068,7 +4114,6 @@ syriatalk.org: could not connect to host
sysadmin.xyz: did not receive HSTS header
syso.name: could not connect to host
szaszm.tk: max-age too low: 0
t-shirts4less.nl: did not receive HSTS header
t-tz.com: could not connect to host
ta-65.com: could not connect to host
ta65.com: could not connect to host
@ -4078,7 +4123,6 @@ tadigitalstore.com: could not connect to host
tafoma.com: did not receive HSTS header
tageau.com: could not connect to host
taglondon.org: did not receive HSTS header
tahf.net: could not connect to host
tails.com.ar: did not receive HSTS header
talk.google.com: did not receive HSTS header (error ignored - included regardless)
talktwincities.com: could not connect to host
@ -4113,7 +4157,7 @@ team-teasers.com: could not connect to host
teamsocial.co: did not receive HSTS header
teamzeus.cz: could not connect to host
tech55i.com: did not receive HSTS header
techassist.io: did not receive HSTS header
techassist.io: could not connect to host
techelements.co: could not connect to host
techhipster.net: could not connect to host
techhub.ml: could not connect to host
@ -4123,8 +4167,8 @@ techmatehq.com: could not connect to host
technogroup.cz: did not receive HSTS header
technosavvyport.com: did not receive HSTS header
techpointed.com: could not connect to host
techreview.link: could not connect to host
tedb.us: could not connect to host
teemo.gg: did not receive HSTS header
tegelsensanitaironline.nl: did not receive HSTS header
tekshrek.com: did not receive HSTS header
telefonnummer.online: could not connect to host
@ -4288,6 +4332,7 @@ tonburi.jp: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR
tonyfantjr.com: could not connect to host
tonyw.xyz: could not connect to host
toomanypillows.com: could not connect to host
top-stage.net: could not connect to host
topbargains.com.au: did not receive HSTS header
topdeskdev.net: could not connect to host
topmarine.se: could not connect to host
@ -4446,7 +4491,6 @@ uzmandroid.top: could not connect to host
v2.pw: did not receive HSTS header
v4veedu.com: could not connect to host
vaddder.com: could not connect to host
valasi.eu: could not connect to host
valethound.com: could not connect to host
valis.sx: could not connect to host
valkyrja.xyz: did not receive HSTS header
@ -4514,6 +4558,7 @@ vm0.eu: did not receive HSTS header
vmc.co.id: could not connect to host
vmrdev.com: could not connect to host
voceinveste.com: did not receive HSTS header
vodpay.com: could not connect to host
vodpay.net: could not connect to host
vodpay.org: could not connect to host
voicesuk.co.uk: did not receive HSTS header
@ -4529,7 +4574,7 @@ vpl.me: did not receive HSTS header
vpn-byen.dk: did not receive HSTS header
vratny.space: could not connect to host
vrobert.fr: could not connect to host
vvl.me: could not connect to host
vvl.me: did not receive HSTS header
vxstream-sandbox.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
vyncke.org: max-age too low: 2678400
vzk.io: could not connect to host
@ -4588,7 +4633,7 @@ webtechgadgetry.com: did not receive HSTS header
webtiles.co.uk: could not connect to host
webwork.pw: could not connect to host
weddingenvelopes.co.uk: did not receive HSTS header
weicn.org: did not receive HSTS header
weiyuz.com: could not connect to host
weizenke.im: could not connect to host
wellastore.ru: did not receive HSTS header
wellsolveit.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
@ -4762,7 +4807,7 @@ xtream-hosting.eu: could not connect to host
xtreamhosting.eu: could not connect to host
xuri.me: max-age too low: 2592000
xuwei.de: could not connect to host
xuyh0120.win: could not connect to host
xuyh0120.win: did not receive HSTS header
xxbase.com: could not connect to host
xyndrac.net: did not receive HSTS header
y-o-w.com: did not receive HSTS header
@ -4788,16 +4833,15 @@ yetcore.io: could not connect to host
yhaupenthal.org: could not connect to host
yingyj.com: could not connect to host
yippie.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
yizhu.com: could not connect to host
yjsoft.me: did not receive HSTS header
yjsw.sh.cn: could not connect to host
ynode.co: did not receive HSTS header
ynsn.nl: did not receive HSTS header
yoga.is-an-engineer.com: could not connect to host
yokeepo.com: max-age too low: 0
yoloboatrentals.com: did not receive HSTS header
yoloprod.fr: could not connect to host
yoloseo.com: could not connect to host
yombo.net: could not connect to host
youcontrol.ru: could not connect to host
youngandunited.nl: did not receive HSTS header
yourbapp.ch: could not connect to host
@ -4845,6 +4889,7 @@ zeytin.pro: could not connect to host
zh.search.yahoo.com: did not receive HSTS header
zhaojin97.cn: did not receive HSTS header
zhendingresources.com: could not connect to host
zinenapse.info: could not connect to host
zirtue.io: could not connect to host
ziyuanabc.xyz: could not connect to host
zkillboard.com: did not receive HSTS header
@ -4866,4 +4911,3 @@ zvncloud.com: did not receive HSTS header
zwollemagazine.nl: did not receive HSTS header
zwy.me: did not receive HSTS header
zyf.pw: could not connect to host
zymbit.com: could not connect to host

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -0,0 +1,15 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
FINAL_TARGET_FILES.defaults.blocklists += ['addons.json',
'certificates.json',
'gfx.json',
'plugins.json']
FINAL_TARGET_FILES.defaults.pinning += ['pins.json']
if CONFIG['MOZ_BUILD_APP'] == 'browser':
DIST_SUBDIR = 'browser'

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

@ -0,0 +1 @@
{"data":[]}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -0,0 +1,29 @@
# Blocklist
The blocklist entries are synchronized locally from the Firefox Settings service.
https://firefox.settings.services.mozilla.com
In order to reduce the amount of data to be downloaded on first synchronization,
a JSON dump from the records present on the remote server is shipped with the
release.
## How to update the JSON files ?
Even though it is not a problem if the dumps are not up-to-date when shipped, here
are the commands to update them:
```
SERVICE_URL="https://firefox.settings.services.mozilla.com/v1"
curl "$SERVICE_URL/buckets/blocklists/collections/certificates/records?" > services/blocklists/certificates.json
curl "$SERVICE_URL/buckets/blocklists/collections/gfx/records?" > services/blocklists/gfx.json
curl "$SERVICE_URL/buckets/blocklists/collections/plugins/records?" > services/blocklists/plugins.json
curl "$SERVICE_URL/buckets/blocklists/collections/addons/records?" > services/blocklists/addons.json
curl "$SERVICE_URL/buckets/pinning/collections/pins/records?" > services/blocklists/pins.json
```
## TODO
- Setup a bot to update it regularly.

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

@ -7,15 +7,13 @@
this.EXPORTED_SYMBOLS = ["AddonBlocklistClient",
"GfxBlocklistClient",
"OneCRLBlocklistClient",
"PluginBlocklistClient",
"PinningBlocklistClient",
"FILENAME_ADDONS_JSON",
"FILENAME_GFX_JSON",
"FILENAME_PLUGINS_JSON"];
"PluginBlocklistClient"];
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
Cu.importGlobalProperties(["fetch"]);
@ -25,6 +23,9 @@ const { KintoHttpClient } = Cu.import("resource://services-common/kinto-http-cli
const { FirefoxAdapter } = Cu.import("resource://services-common/kinto-storage-adapter.js", {});
const { CanonicalJSON } = Components.utils.import("resource://gre/modules/CanonicalJSON.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
const KEY_APPDIR = "XCurProcD";
const PREF_SETTINGS_SERVER = "services.settings.server";
const PREF_BLOCKLIST_BUCKET = "services.blocklist.bucket";
const PREF_BLOCKLIST_ONECRL_COLLECTION = "services.blocklist.onecrl.collection";
@ -48,9 +49,6 @@ const INVALID_SIGNATURE = "Invalid content/signature";
// filename, even though it isn't descriptive of who is using it.
this.KINTO_STORAGE_PATH = "kinto.sqlite";
this.FILENAME_ADDONS_JSON = "blocklist-addons.json";
this.FILENAME_GFX_JSON = "blocklist-gfx.json";
this.FILENAME_PLUGINS_JSON = "blocklist-plugins.json";
function mergeChanges(collection, localRecords, changes) {
@ -104,6 +102,29 @@ class BlocklistClient {
});
}
get filename() {
return `${this.bucketName}/${this.collectionName}.json`;
}
/**
* Load the the JSON file distributed with the release for this blocklist.
*
* For Bug 1257565 this method will have to try to load the file from the profile,
* in order to leverage the updateJSONBlocklist() below, which writes a new
* dump each time the collection changes.
*/
loadDumpFile() {
const fileURI = `resource://app/defaults/${this.filename}`;
return Task.spawn(function* loadFile() {
const response = yield fetch(fileURI);
if (!response.ok) {
throw new Error(`Could not read from '${fileURI}'`);
}
// Will be rejected if JSON is invalid.
return yield response.json();
});
}
validateCollectionSignature(remote, payload, collection, options = {}) {
const {ignoreLocal} = options;
@ -145,14 +166,17 @@ class BlocklistClient {
/**
* Synchronize from Kinto server, if necessary.
*
* @param {int} lastModified the lastModified date (on the server) for
the remote collection.
* @param {Date} serverTime the current date return by the server.
* @return {Promise} which rejects on sync or process failure.
* @param {int} lastModified the lastModified date (on the server) for
the remote collection.
* @param {Date} serverTime the current date return by the server.
* @param {Object} options additional advanced options.
* @param {bool} options.loadDump load initial dump from disk on first sync (default: true)
* @return {Promise} which rejects on sync or process failure.
*/
maybeSync(lastModified, serverTime) {
maybeSync(lastModified, serverTime, options = {loadDump: true}) {
const {loadDump} = options;
const remote = Services.prefs.getCharPref(PREF_SETTINGS_SERVER);
let enforceCollectionSigning =
const enforceCollectionSigning =
Services.prefs.getBoolPref(PREF_BLOCKLIST_ENFORCE_SIGNING);
// if there is a signerName and collection signing is enforced, add a
@ -177,13 +201,30 @@ class BlocklistClient {
};
const collection = this._kinto.collection(this.collectionName, options);
const collectionLastModified = yield collection.db.getLastModified();
let collectionLastModified = yield collection.db.getLastModified();
// If there is no data currently in the collection, attempt to import
// initial data from the application defaults.
// This allows to avoid synchronizing the whole collection content on
// cold start.
if (!collectionLastModified && loadDump) {
try {
const initialData = yield this.loadDumpFile();
yield collection.db.loadDump(initialData.data);
collectionLastModified = yield collection.db.getLastModified();
} catch (e) {
// Report but go-on.
Cu.reportError(e);
}
}
// If the data is up to date, there's no need to sync. We still need
// to record the fact that a check happened.
if (lastModified <= collectionLastModified) {
this.updateLastCheck(serverTime);
return;
}
// Fetch changes from server.
try {
const {ok} = yield collection.sync({remote});
@ -315,10 +356,13 @@ function* updatePinningList(records) {
function* updateJSONBlocklist(filename, records) {
// Write JSON dump for synchronous load at startup.
const path = OS.Path.join(OS.Constants.Path.profileDir, filename);
const blocklistFolder = OS.Path.dirname(path);
yield OS.File.makeDir(blocklistFolder, {from: OS.Constants.Path.profileDir});
const serialized = JSON.stringify({data: records}, null, 2);
try {
yield OS.File.writeAtomic(path, serialized, {tmpPath: path + ".tmp"});
// Notify change to `nsBlocklistService`
const eventData = {filename};
Services.cpmm.sendAsyncMessage("Blocklist:reload-from-disk", eventData);
@ -338,21 +382,21 @@ this.OneCRLBlocklistClient = new BlocklistClient(
this.AddonBlocklistClient = new BlocklistClient(
Services.prefs.getCharPref(PREF_BLOCKLIST_ADDONS_COLLECTION),
PREF_BLOCKLIST_ADDONS_CHECKED_SECONDS,
updateJSONBlocklist.bind(undefined, FILENAME_ADDONS_JSON),
(records) => updateJSONBlocklist(this.AddonBlocklistClient.filename, records),
Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET)
);
this.GfxBlocklistClient = new BlocklistClient(
Services.prefs.getCharPref(PREF_BLOCKLIST_GFX_COLLECTION),
PREF_BLOCKLIST_GFX_CHECKED_SECONDS,
updateJSONBlocklist.bind(undefined, FILENAME_GFX_JSON),
(records) => updateJSONBlocklist(this.GfxBlocklistClient.filename, records),
Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET)
);
this.PluginBlocklistClient = new BlocklistClient(
Services.prefs.getCharPref(PREF_BLOCKLIST_PLUGINS_COLLECTION),
PREF_BLOCKLIST_PLUGINS_CHECKED_SECONDS,
updateJSONBlocklist.bind(undefined, FILENAME_PLUGINS_JSON),
(records) => updateJSONBlocklist(this.PluginBlocklistClient.filename, records),
Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET)
);

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

@ -12,9 +12,10 @@ const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
let server;
// set up what we need to make storage adapters
const kintoFilename = "kinto.sqlite";
let sqliteHandle;
const KINTO_FILENAME = "kinto.sqlite";
function do_get_kinto_collection(collectionName, sqliteHandle) {
function do_get_kinto_collection(collectionName) {
let config = {
// Set the remote to be some server that will cause test failure when
// hit since we should never hit the server directly, only via maybeSync()
@ -35,8 +36,8 @@ add_task(function* test_something() {
const configPath = "/v1/";
const recordsPath = "/v1/buckets/blocklists/collections/certificates/records";
Services.prefs.setCharPref("services.settings.server",
`http://localhost:${server.identity.primaryPort}/v1`);
const dummyServerURL = `http://localhost:${server.identity.primaryPort}/v1`;
Services.prefs.setCharPref("services.settings.server", dummyServerURL);
// register a handler
function handleResponse(request, response) {
@ -66,24 +67,45 @@ add_task(function* test_something() {
// Test an empty db populates
yield OneCRLBlocklistClient.maybeSync(2000, Date.now());
sqliteHandle = yield FirefoxAdapter.openConnection({path: KINTO_FILENAME});
const collection = do_get_kinto_collection("certificates");
// Open the collection, verify it's been populated:
// Our test data has a single record; it should be in the local collection
let sqliteHandle = yield FirefoxAdapter.openConnection({path: kintoFilename});
let collection = do_get_kinto_collection("certificates", sqliteHandle);
let list = yield collection.list();
// We know there will be initial values from the JSON dump.
// (at least as many as in the dump shipped when this test was written).
do_check_true(list.data.length >= 363);
// No sync will be intented if maybeSync() is up-to-date.
Services.prefs.clearUserPref("services.settings.server");
Services.prefs.setIntPref("services.blocklist.onecrl.checked", 0);
// Use any last_modified older than highest shipped in JSON dump.
yield OneCRLBlocklistClient.maybeSync(123456, Date.now());
// Last check value was updated.
do_check_neq(0, Services.prefs.getIntPref("services.blocklist.onecrl.checked"));
// Restore server pref.
Services.prefs.setCharPref("services.settings.server", dummyServerURL);
// clear the collection, save a non-zero lastModified so we don't do
// import of initial data when we sync again.
yield collection.clear();
// a lastModified value of 1000 means we get a remote collection with a
// single record
yield collection.db.saveLastModified(1000);
yield OneCRLBlocklistClient.maybeSync(2000, Date.now());
// Open the collection, verify it's been updated:
// Our test data now has two records; both should be in the local collection
list = yield collection.list();
do_check_eq(list.data.length, 1);
yield sqliteHandle.close();
// Test the db is updated when we call again with a later lastModified value
yield OneCRLBlocklistClient.maybeSync(4000, Date.now());
// Open the collection, verify it's been updated:
// Our test data now has two records; both should be in the local collection
sqliteHandle = yield FirefoxAdapter.openConnection({path: kintoFilename});
collection = do_get_kinto_collection("certificates", sqliteHandle);
list = yield collection.list();
do_check_eq(list.data.length, 3);
yield sqliteHandle.close();
// Try to maybeSync with the current lastModified value - no connection
// should be attempted.
@ -104,8 +126,7 @@ add_task(function* test_something() {
// Check that a sync completes even when there's bad data in the
// collection. This will throw on fail, so just calling maybeSync is an
// acceptible test.
Services.prefs.setCharPref("services.settings.server",
`http://localhost:${server.identity.primaryPort}/v1`);
Services.prefs.setCharPref("services.settings.server", dummyServerURL);
yield OneCRLBlocklistClient.maybeSync(5000, Date.now());
});
@ -122,6 +143,7 @@ function run_test() {
do_register_cleanup(function() {
server.stop(() => { });
return sqliteHandle.close();
});
}
@ -150,6 +172,17 @@ function getSampleResponse(req, port) {
"responseBody": JSON.stringify({"settings":{"batch_max_requests":25}, "url":`http://localhost:${port}/v1/`, "documentation":"https://kinto.readthedocs.org/", "version":"1.5.1", "commit":"cbc6f58", "hello":"kinto"})
},
"GET:/v1/buckets/blocklists/collections/certificates/records?_sort=-last_modified": {
"sampleHeaders": [
"Access-Control-Allow-Origin: *",
"Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
"Content-Type: application/json; charset=UTF-8",
"Server: waitress",
"Etag: \"1000\""
],
"status": {status: 200, statusText: "OK"},
"responseBody": JSON.stringify({"data":[{}]})
},
"GET:/v1/buckets/blocklists/collections/certificates/records?_sort=-last_modified&_since=1000": {
"sampleHeaders": [
"Access-Control-Allow-Origin: *",
"Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",

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

@ -17,9 +17,9 @@ const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
const kintoFilename = "kinto.sqlite";
const gBlocklistClients = [
{client: BlocklistClients.AddonBlocklistClient, filename: BlocklistClients.FILENAME_ADDONS_JSON, testData: ["i808", "i720", "i539"]},
{client: BlocklistClients.PluginBlocklistClient, filename: BlocklistClients.FILENAME_PLUGINS_JSON, testData: ["p1044", "p32", "p28"]},
{client: BlocklistClients.GfxBlocklistClient, filename: BlocklistClients.FILENAME_GFX_JSON, testData: ["g204", "g200", "g36"]},
{client: BlocklistClients.AddonBlocklistClient, testData: ["i808", "i720", "i539"]},
{client: BlocklistClients.PluginBlocklistClient, testData: ["p1044", "p32", "p28"]},
{client: BlocklistClients.GfxBlocklistClient, testData: ["g204", "g200", "g36"]},
];
@ -57,14 +57,10 @@ function* clear_state() {
} finally {
yield sqliteHandle.close();
}
}
// Remove profile data.
for (let {filename} of gBlocklistClients) {
const blocklist = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
if (blocklist.exists()) {
blocklist.remove(true);
}
// Remove profile data.
const path = OS.Path.join(OS.Constants.Path.profileDir, client.filename);
yield OS.File.remove(path, { ignoreAbsent: true });
}
}
@ -121,7 +117,7 @@ function run_test() {
add_task(function* test_records_obtained_from_server_are_stored_in_db() {
for (let {client} of gBlocklistClients) {
// Test an empty db populates
yield client.maybeSync(2000, Date.now());
yield client.maybeSync(2000, Date.now(), {loadDump: false});
// Open the collection, verify it's been populated:
// Our test data has a single record; it should be in the local collection
@ -135,11 +131,11 @@ add_task(function* test_records_obtained_from_server_are_stored_in_db() {
add_task(clear_state);
add_task(function* test_list_is_written_to_file_in_profile() {
for (let {client, filename, testData} of gBlocklistClients) {
const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
for (let {client, testData} of gBlocklistClients) {
const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/"));
strictEqual(profFile.exists(), false);
yield client.maybeSync(2000, Date.now());
yield client.maybeSync(2000, Date.now(), {loadDump: false});
strictEqual(profFile.exists(), true);
const content = yield readJSON(profFile.path);
@ -159,9 +155,9 @@ add_task(function* test_current_server_time_is_saved_in_pref() {
add_task(clear_state);
add_task(function* test_update_json_file_when_addons_has_changes() {
for (let {client, filename, testData} of gBlocklistClients) {
yield client.maybeSync(2000, Date.now() - 1000);
const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
for (let {client, testData} of gBlocklistClients) {
yield client.maybeSync(2000, Date.now() - 1000, {loadDump: false});
const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/"));
const fileLastModified = profFile.lastModifiedTime = profFile.lastModifiedTime - 1000;
const serverTime = Date.now();
@ -179,24 +175,24 @@ add_task(function* test_update_json_file_when_addons_has_changes() {
add_task(clear_state);
add_task(function* test_sends_reload_message_when_blocklist_has_changes() {
for (let {client, filename} of gBlocklistClients) {
for (let {client} of gBlocklistClients) {
let received = yield new Promise((resolve, reject) => {
Services.ppmm.addMessageListener("Blocklist:reload-from-disk", {
receiveMessage(aMsg) { resolve(aMsg) }
});
client.maybeSync(2000, Date.now() - 1000);
client.maybeSync(2000, Date.now() - 1000, {loadDump: false});
});
equal(received.data.filename, filename);
equal(received.data.filename, client.filename);
}
});
add_task(clear_state);
add_task(function* test_do_nothing_when_blocklist_is_up_to_date() {
for (let {client, filename} of gBlocklistClients) {
yield client.maybeSync(2000, Date.now() - 1000);
const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]);
for (let {client} of gBlocklistClients) {
yield client.maybeSync(2000, Date.now() - 1000, {loadDump: false});
const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/"));
const fileLastModified = profFile.lastModifiedTime = profFile.lastModifiedTime - 1000;
const serverTime = Date.now();

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

@ -294,7 +294,8 @@ add_task(function* test_check_signatures() {
// With all of this set up, we attempt a sync. This will resolve if all is
// well and throw if something goes wrong.
yield OneCRLBlocklistClient.maybeSync(1000, startTime);
// We don't want to load initial json dumps in this test suite.
yield OneCRLBlocklistClient.maybeSync(1000, startTime, {loadDump: false});
// Check that some additions (2 records) to the collection have a valid
// signature.

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

@ -9,6 +9,8 @@ support-files =
[test_load_modules.js]
[test_blocklist_certificates.js]
# Initial JSON data for blocklists are not shipped on Android.
skip-if = os == "android"
[test_blocklist_clients.js]
[test_blocklist_updater.js]
[test_blocklist_pinning.js]

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

@ -10,7 +10,10 @@ DIRS += [
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
DIRS += ['fxaccounts']
DIRS += [
'fxaccounts',
'blocklists',
]
if CONFIG['MOZ_SERVICES_SYNC']:
DIRS += ['sync']

22
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -602,7 +602,7 @@ dependencies = [
"devtools_traits 0.0.1",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@ -620,7 +620,7 @@ dependencies = [
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1165,13 +1165,14 @@ dependencies = [
[[package]]
name = "hyper_serde"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1638,7 +1639,7 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1652,6 +1653,9 @@ dependencies = [
"openssl-verify 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"profile_traits 0.0.1",
"rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"servo_config 0.0.1",
"servo_url 0.0.1",
"threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1685,7 +1689,7 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net 0.0.1",
@ -1706,7 +1710,7 @@ dependencies = [
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2209,7 +2213,7 @@ dependencies = [
"html5ever 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever-atoms 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"js 0.1.4 (git+https://github.com/servo/rust-mozjs)",
@ -2312,7 +2316,7 @@ dependencies = [
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
@ -3416,7 +3420,7 @@ dependencies = [
"checksum html5ever-atoms 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9bd86e3b6a5a7933a272cc0a854f24e371f31576e585c0b41e8f857270c5134"
"checksum httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7a63e511f9edffbab707141fbb8707d1a3098615fb2adbd5769cdfcc9b17d"
"checksum hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3"
"checksum hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19065fedb73b4d5c617482cedfb3cfb092fc379870a7e3aadd16fd491838129a"
"checksum hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d602a93073c250f49b2e2d931cc1755a5f447824154dc3c711716dee29bd7486"
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
"checksum image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "979bad0502082fd60053a490282e87d6c89650942e3a270e0d4c83569c7f5899"
"checksum immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e76ecb1d64979a91c7fc5b7c0495ef1467e3cbff759044f2b88878a5a845ef7"

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

@ -30,6 +30,9 @@ openssl = "0.7.6"
openssl-verify = "0.1"
profile_traits = {path = "../profile_traits"}
rustc-serialize = "0.3"
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"
servo_config = {path = "../config"}
servo_url = {path = "../url"}
threadpool = "1.0"

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

@ -6,6 +6,7 @@
//! http://tools.ietf.org/html/rfc6265
use cookie_rs;
use hyper_serde::{self, Serde};
use net_traits::CookieSource;
use net_traits::pub_domains::is_pub_domain;
use servo_url::ServoUrl;
@ -16,14 +17,20 @@ use time::{Tm, now, at, Duration};
/// A stored cookie that wraps the definition in cookie-rs. This is used to implement
/// various behaviours defined in the spec that rely on an associated request URL,
/// which cookie-rs and hyper's header parsing do not support.
#[derive(Clone, Debug, RustcDecodable, RustcEncodable)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Cookie {
#[serde(deserialize_with = "hyper_serde::deserialize",
serialize_with = "hyper_serde::serialize")]
pub cookie: cookie_rs::Cookie,
pub host_only: bool,
pub persistent: bool,
#[serde(deserialize_with = "hyper_serde::deserialize",
serialize_with = "hyper_serde::serialize")]
pub creation_time: Tm,
#[serde(deserialize_with = "hyper_serde::deserialize",
serialize_with = "hyper_serde::serialize")]
pub last_access: Tm,
pub expiry_time: Option<Tm>,
pub expiry_time: Option<Serde<Tm>>,
}
impl Cookie {
@ -85,7 +92,7 @@ impl Cookie {
persistent: persistent,
creation_time: now(),
last_access: now(),
expiry_time: expiry_time,
expiry_time: expiry_time.map(Serde),
})
}

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

@ -16,7 +16,7 @@ use time::Tm;
extern crate time;
#[derive(Clone, Debug, RustcDecodable, RustcEncodable)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CookieStorage {
version: u32,
cookies_map: HashMap<String, Vec<Cookie>>,
@ -192,7 +192,7 @@ fn reg_host<'a>(url: &'a str) -> String {
fn is_cookie_expired(cookie: &Cookie) -> bool {
match cookie.expiry_time {
Some(t) => t.to_timespec() <= time::get_time(),
Some(ref t) => t.to_timespec() <= time::get_time(),
None => false,
}
}

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

@ -4,7 +4,7 @@
use net_traits::IncludeSubdomains;
use net_traits::pub_domains::reg_suffix;
use rustc_serialize::json::decode;
use serde_json;
use servo_config::resource_files::read_resource_file;
use std::collections::HashMap;
use std::net::{Ipv4Addr, Ipv6Addr};
@ -12,7 +12,7 @@ use std::str::from_utf8;
use time;
use url::Url;
#[derive(RustcDecodable, RustcEncodable, Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct HstsEntry {
pub host: String,
pub include_subdomains: bool,
@ -53,7 +53,7 @@ impl HstsEntry {
}
}
#[derive(RustcDecodable, RustcEncodable, Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct HstsList {
pub entries_map: HashMap<String, Vec<HstsEntry>>,
}
@ -65,14 +65,14 @@ impl HstsList {
/// Create an `HstsList` from the bytes of a JSON preload file.
pub fn from_preload(preload_content: &[u8]) -> Option<HstsList> {
#[derive(RustcDecodable)]
#[derive(Deserialize)]
struct HstsEntries {
entries: Vec<HstsEntry>,
}
let hsts_entries: Option<HstsEntries> = from_utf8(&preload_content)
.ok()
.and_then(|c| decode(c).ok());
.and_then(|c| serde_json::from_str(c).ok());
hsts_entries.map_or(None, |hsts_entries| {
let mut hsts_list: HstsList = HstsList::new();

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

@ -27,6 +27,10 @@ extern crate openssl;
extern crate openssl_verify;
extern crate profile_traits;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate servo_config;
extern crate servo_url;
extern crate threadpool;

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

@ -23,8 +23,8 @@ use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData};
use net_traits::request::{Request, RequestInit};
use net_traits::storage_thread::StorageThreadMsg;
use profile_traits::time::ProfilerChan;
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::json;
use serde::{Deserialize, Serialize};
use serde_json;
use servo_url::ServoUrl;
use std::borrow::{Cow, ToOwned};
use std::collections::HashMap;
@ -211,7 +211,7 @@ impl ResourceChannelManager {
}
pub fn read_json_from_file<T>(data: &mut T, config_dir: &Path, filename: &str)
where T: Decodable
where T: Deserialize
{
let path = config_dir.join(filename);
let display = path.display();
@ -233,17 +233,17 @@ pub fn read_json_from_file<T>(data: &mut T, config_dir: &Path, filename: &str)
Ok(_) => println!("successfully read from {}", display),
}
match json::decode(&string_buffer) {
match serde_json::from_str(&string_buffer) {
Ok(decoded_buffer) => *data = decoded_buffer,
Err(why) => warn!("Could not decode buffer{}", why),
}
}
pub fn write_json_to_file<T>(data: &T, config_dir: &Path, filename: &str)
where T: Encodable
where T: Serialize
{
let json_encoded: String;
match json::encode(&data) {
match serde_json::to_string_pretty(&data) {
Ok(d) => json_encoded = d,
Err(_) => return,
}
@ -266,7 +266,7 @@ pub fn write_json_to_file<T>(data: &T, config_dir: &Path, filename: &str)
}
}
#[derive(RustcDecodable, RustcEncodable, Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct AuthCacheEntry {
pub user_name: String,
pub password: String,
@ -281,7 +281,7 @@ impl AuthCache {
}
}
#[derive(RustcDecodable, RustcEncodable, Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct AuthCache {
pub version: u32,
pub entries: HashMap<String, AuthCacheEntry>,

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

@ -15,6 +15,7 @@ use properties::{PropertyDeclarationId, LonghandId, DeclaredValue};
use properties::PropertyDeclarationParseResult;
use properties::animated_properties::TransitionProperty;
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
use properties::property_bit_field::PropertyBitField;
use std::fmt;
use std::sync::Arc;
use style_traits::ToCss;
@ -244,21 +245,23 @@ pub struct KeyframesAnimation {
pub properties_changed: Vec<TransitionProperty>,
}
/// Get all the animated properties in a keyframes animation. Note that it's not
/// defined what happens when a property is not on a keyframe, so we only peek
/// the props of the first one.
///
/// In practice, browsers seem to try to do their best job at it, so we might
/// want to go through all the actual keyframes and deduplicate properties.
fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
/// Get all the animated properties in a keyframes animation.
fn get_animated_properties(keyframes: &[Arc<RwLock<Keyframe>>]) -> Vec<TransitionProperty> {
let mut ret = vec![];
let mut seen = PropertyBitField::new();
// NB: declarations are already deduplicated, so we don't have to check for
// it here.
for &(ref declaration, importance) in keyframe.block.read().declarations.iter() {
assert!(!importance.important());
for keyframe in keyframes {
let keyframe = keyframe.read();
for &(ref declaration, importance) in keyframe.block.read().declarations.iter() {
assert!(!importance.important());
if let Some(property) = TransitionProperty::from_declaration(declaration) {
ret.push(property);
if let Some(property) = TransitionProperty::from_declaration(declaration) {
if !seen.has_transition_property_bit(&property) {
ret.push(property);
seen.set_transition_property_bit(&property);
}
}
}
}
@ -284,7 +287,7 @@ impl KeyframesAnimation {
return result;
}
result.properties_changed = get_animated_properties(&keyframes[0].read());
result.properties_changed = get_animated_properties(keyframes);
if result.properties_changed.is_empty() {
return result;
}

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

@ -43,7 +43,7 @@ use values::specified::Angle as SpecifiedAngle;
/// property.
// NB: This needs to be here because it needs all the longhands generated
// beforehand.
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum TransitionProperty {
/// All, any animatable property changing should generate a transition.

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

@ -181,8 +181,10 @@ pub mod animated_properties {
// TODO(SimonSapin): Convert this to a syntax extension rather than a Mako template.
// Maybe submit for inclusion in libstd?
mod property_bit_field {
#[allow(missing_docs)]
pub mod property_bit_field {
use logical_geometry::WritingMode;
use properties::animated_properties::TransitionProperty;
/// A bitfield for all longhand properties, in order to quickly test whether
/// we've seen one of them.
@ -213,7 +215,7 @@ mod property_bit_field {
pub fn get_${property.ident}(&self) -> bool {
self.get(${i})
}
#[allow(non_snake_case)]
#[allow(non_snake_case, missing_docs)]
#[inline]
pub fn set_${property.ident}(&mut self) {
self.set(${i})
@ -238,6 +240,32 @@ mod property_bit_field {
}
% endif
% endfor
/// Set the corresponding bit of TransitionProperty.
/// This function will panic if TransitionProperty::All is given.
pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) {
match *property {
% for i, prop in enumerate(data.longhands):
% if prop.animatable:
TransitionProperty::${prop.camel_case} => self.set(${i}),
% endif
% endfor
TransitionProperty::All => unreachable!("Tried to set TransitionProperty::All in a PropertyBitfield"),
}
}
/// Return true if the corresponding bit of TransitionProperty is set.
/// This function will panic if TransitionProperty::All is given.
pub fn has_transition_property_bit(&self, property: &TransitionProperty) -> bool {
match *property {
% for i, prop in enumerate(data.longhands):
% if prop.animatable:
TransitionProperty::${prop.camel_case} => self.get(${i}),
% endif
% endfor
TransitionProperty::All => unreachable!("Tried to get TransitionProperty::All in a PropertyBitfield"),
}
}
}
}

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

@ -1435,6 +1435,9 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
timing_function: *const nsTimingFunction,
style: ServoComputedValuesBorrowed,
keyframes: RawGeckoKeyframeListBorrowedMut) -> bool {
use style::gecko_bindings::structs::Keyframe;
use style::properties::property_bit_field::PropertyBitField;
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) };
let style_timing_function = unsafe { timing_function.as_ref().unwrap() };
@ -1455,16 +1458,25 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
&timing_function)
};
fn add_computed_property_value(keyframe: *mut Keyframe,
index: usize,
style: &ComputedValues,
property: &TransitionProperty) {
let block = style.to_declaration_block(property.clone().into());
unsafe {
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty = property.clone().into();
// FIXME. Do not set computed values once we handles missing keyframes
// with additive composition.
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new(block)));
}
}
match step.value {
KeyframesStepValue::ComputedValues => {
for (index, property) in animation.properties_changed.iter().enumerate() {
let block = style.to_declaration_block(property.clone().into());
unsafe {
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty = property.clone().into();
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new(block)));
}
add_computed_property_value(keyframe, index, style, property);
}
},
KeyframesStepValue::Declarations { ref block } => {
@ -1476,16 +1488,33 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet
.filter(|&&(ref declaration, _)| {
declaration.is_animatable()
});
let mut seen = PropertyBitField::new();
for (index, &(ref declaration, _)) in animatable.enumerate() {
unsafe {
let property = TransitionProperty::from_declaration(declaration).unwrap();
(*keyframe).mPropertyValues.set_len((index + 1) as u32);
(*keyframe).mPropertyValues[index].mProperty =
TransitionProperty::from_declaration(declaration).unwrap().into();
(*keyframe).mPropertyValues[index].mProperty = property.into();
(*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky(
Arc::new(RwLock::new(
PropertyDeclarationBlock { declarations: vec![ (declaration.clone(),
Importance::Normal) ],
important_count: 0 })));
if step.start_percentage.0 == 0. ||
step.start_percentage.0 == 1. {
seen.set_transition_property_bit(&property);
}
}
}
// Append missing property values in the initial or the finial keyframes.
if step.start_percentage.0 == 0. ||
step.start_percentage.0 == 1. {
for (index, property) in animation.properties_changed.iter().enumerate() {
if !seen.has_transition_property_bit(&property) {
add_computed_property_value(keyframe, index, style, property);
}
}
}
},

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

@ -232,7 +232,7 @@ class MachCommands(CommandBase):
test_patterns.append(test)
if not packages:
packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit")))
packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit"))) - set(['.DS_Store'])
packages.discard('stylo')
@ -345,7 +345,7 @@ class MachCommands(CommandBase):
test_patterns.append(test)
if not packages:
packages = set(os.listdir(path.join(self.context.topdir, "tests", "compiletest")))
packages = set(os.listdir(path.join(self.context.topdir, "tests", "compiletest"))) - set(['.DS_Store'])
packages.remove("helper")

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

@ -5,7 +5,10 @@
use parking_lot::RwLock;
use std::sync::Arc;
use style::keyframes::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector};
use style::properties::PropertyDeclarationBlock;
use style::keyframes::{KeyframesStep, KeyframesStepValue};
use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance};
use style::properties::animated_properties::TransitionProperty;
use style::values::specified::{LengthOrPercentageOrAuto, NoCalcLength};
#[test]
fn test_empty_keyframe() {
@ -38,3 +41,177 @@ fn test_no_property_in_keyframe() {
assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected));
}
#[test]
fn test_missing_property_in_initial_keyframe() {
let declarations_on_initial_keyframe =
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![
(PropertyDeclaration::Width(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
],
important_count: 0,
}));
let declarations_on_final_keyframe =
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![
(PropertyDeclaration::Width(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
(PropertyDeclaration::Height(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
],
important_count: 0,
}));
let keyframes = vec![
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]),
block: declarations_on_initial_keyframe.clone(),
})),
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]),
block: declarations_on_final_keyframe.clone(),
})),
];
let animation = KeyframesAnimation::from_keyframes(&keyframes);
let expected = KeyframesAnimation {
steps: vec![
KeyframesStep {
start_percentage: KeyframePercentage(0.),
value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe },
declared_timing_function: false,
},
KeyframesStep {
start_percentage: KeyframePercentage(1.),
value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe },
declared_timing_function: false,
},
],
properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height],
};
assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected));
}
#[test]
fn test_missing_property_in_final_keyframe() {
let declarations_on_initial_keyframe =
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![
(PropertyDeclaration::Width(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
(PropertyDeclaration::Height(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
],
important_count: 0,
}));
let declarations_on_final_keyframe =
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![
(PropertyDeclaration::Height(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
],
important_count: 0,
}));
let keyframes = vec![
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]),
block: declarations_on_initial_keyframe.clone(),
})),
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]),
block: declarations_on_final_keyframe.clone(),
})),
];
let animation = KeyframesAnimation::from_keyframes(&keyframes);
let expected = KeyframesAnimation {
steps: vec![
KeyframesStep {
start_percentage: KeyframePercentage(0.),
value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe },
declared_timing_function: false,
},
KeyframesStep {
start_percentage: KeyframePercentage(1.),
value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe },
declared_timing_function: false,
},
],
properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height],
};
assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected));
}
#[test]
fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() {
let declarations =
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![
(PropertyDeclaration::Width(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
(PropertyDeclaration::Height(
DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))),
Importance::Normal),
],
important_count: 0,
}));
let keyframes = vec![
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]),
block: Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![],
important_count: 0,
}))
})),
Arc::new(RwLock::new(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]),
block: declarations.clone(),
})),
];
let animation = KeyframesAnimation::from_keyframes(&keyframes);
let expected = KeyframesAnimation {
steps: vec![
KeyframesStep {
start_percentage: KeyframePercentage(0.),
value: KeyframesStepValue::Declarations {
block: Arc::new(RwLock::new(PropertyDeclarationBlock {
// XXX: Should we use ComputedValues in this case?
declarations: vec![],
important_count: 0,
}))
},
declared_timing_function: false,
},
KeyframesStep {
start_percentage: KeyframePercentage(0.5),
value: KeyframesStepValue::Declarations { block: declarations },
declared_timing_function: false,
},
KeyframesStep {
start_percentage: KeyframePercentage(1.),
value: KeyframesStepValue::ComputedValues,
declared_timing_function: false,
}
],
properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height],
};
assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected));
}

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

@ -22,6 +22,8 @@ from mach.decorators import (
from mozbuild.base import MachCommandBase
ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}'
class ShowTaskGraphSubCommand(SubCommand):
"""A SubCommand with TaskGraph-specific arguments"""

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

@ -1,7 +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/.
import os
GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))

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

@ -6,17 +6,18 @@
from __future__ import absolute_import, print_function, unicode_literals
import json
import logging
import requests
import yaml
from .create import create_tasks
from .decision import write_artifact
from .optimize import optimize_task_graph
from .taskgraph import TaskGraph
from .util.taskcluster import get_artifact
logger = logging.getLogger(__name__)
TASKCLUSTER_QUEUE_URL = "https://queue.taskcluster.net/v1/task"
TREEHERDER_URL = "https://treeherder.mozilla.org/api"
# We set this to 5 for now because this is what SETA sets the
@ -62,6 +63,15 @@ def add_tasks(decision_task_id, task_labels, prefix=''):
create_tasks(optimized_graph, label_to_taskid, decision_params)
def get_artifact(task_id, path):
resp = requests.get(url="{}/{}/artifacts/{}".format(TASKCLUSTER_QUEUE_URL, task_id, path))
if path.endswith('.json'):
artifact = json.loads(resp.text)
elif path.endswith('.yml'):
artifact = yaml.load(resp.text)
return artifact
def backfill(project, job_id):
"""
Run the backfill task. This function implements `mach taskgraph backfill-task`,

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

@ -21,7 +21,6 @@ from .util import (
calculate_head_rev
)
from ..create import create_task
from .. import GECKO
from taskgraph.util.attributes import match_run_on_projects
from taskgraph.util.schema import resolve_keyed_by
@ -33,6 +32,7 @@ JOB_TYPES = {
'decision-task': decision.run_decision_task,
}
GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..'))
logger = logging.getLogger(__name__)
_session = None

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

@ -18,7 +18,6 @@ from .create import create_tasks
from .parameters import Parameters
from .taskgraph import TaskGraph
from actions import render_actions_json
from . import GECKO
from taskgraph.util.templates import Templates
from taskgraph.util.time import (
@ -29,6 +28,7 @@ from taskgraph.util.time import (
logger = logging.getLogger(__name__)
ARTIFACTS_DIR = 'artifacts'
GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))
# For each project, this gives a set of parameters specific to the project.
# See `taskcluster/docs/parameters.rst` for information on parameters.

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

@ -12,32 +12,31 @@ import sys
import subprocess
import tarfile
import tempfile
import urllib2
import which
from subprocess import Popen, PIPE
from io import BytesIO
from taskgraph.util import docker
from taskgraph.util.taskcluster import (
find_task_id,
get_artifact_url,
)
from . import GECKO
DOCKER_INDEX = docker.INDEX_PREFIX + '.{}.{}.hash.{}'
GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))
INDEX_URL = 'https://index.taskcluster.net/v1/task/' + docker.INDEX_PREFIX + '.{}.{}.hash.{}'
ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}'
def load_image_by_name(image_name, tag=None):
context_path = os.path.join(GECKO, 'taskcluster', 'docker', image_name)
context_hash = docker.generate_context_hash(GECKO, context_path, image_name)
index_path = DOCKER_INDEX.format('level-3', image_name, context_hash)
task_id = find_task_id(index_path)
image_index_url = INDEX_URL.format('level-3', image_name, context_hash)
print("Fetching", image_index_url)
task = json.load(urllib2.urlopen(image_index_url))
return load_image_by_task_id(task_id, tag)
return load_image_by_task_id(task['taskId'], tag)
def load_image_by_task_id(task_id, tag=None):
artifact_url = get_artifact_url(task_id, 'public/image.tar.zst')
artifact_url = ARTIFACT_URL.format(task_id, 'public/image.tar.zst')
result = load_image(artifact_url, tag)
print("Found docker image: {}:{}".format(result['image'], result['tag']))
if tag:

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

@ -5,6 +5,7 @@
from __future__ import absolute_import, unicode_literals
import logging
import os
from . import (
target_tasks,
@ -12,6 +13,8 @@ from . import (
logger = logging.getLogger(__name__)
GECKO = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))
filter_task_functions = {}

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

@ -62,7 +62,9 @@ def load_parameters_file(options):
Load parameters from the --parameters option
"""
import urllib
from taskgraph.util.taskcluster import get_artifact_url
url_prefix = "https://queue.taskcluster.net/v1/task/"
url_postfix = "/artifacts/public/parameters.yml"
filename = options['parameters']
@ -76,7 +78,7 @@ def load_parameters_file(options):
# fetching parameters.yml using task task-id or supplied url
if filename.startswith("task-id="):
task_id = filename.split("=")[1]
filename = get_artifact_url(task_id, 'public/parameters.yml')
filename = url_prefix + task_id + url_postfix
f = urllib.urlopen(filename)
if filename.endswith('.yml'):

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