зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central r=merge a=merge
This commit is contained in:
Коммит
f7400ad72e
|
@ -19,10 +19,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "ViewPopup",
|
||||
"resource:///modules/ExtensionPopups.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
|
||||
"@mozilla.org/inspector/dom-utils;1",
|
||||
"inIDOMUtils");
|
||||
|
||||
var {
|
||||
DefaultWeakMap,
|
||||
} = ExtensionUtils;
|
||||
|
@ -34,6 +30,8 @@ var {
|
|||
StartupCache,
|
||||
} = ExtensionParent;
|
||||
|
||||
Cu.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
const POPUP_PRELOAD_TIMEOUT_MS = 200;
|
||||
const POPUP_OPEN_MS_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_OPEN_MS";
|
||||
const POPUP_RESULT_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT";
|
||||
|
@ -673,7 +671,7 @@ this.browserAction = class extends ExtensionAPI {
|
|||
let tab = getTab(details.tabId);
|
||||
let color = details.color;
|
||||
if (!Array.isArray(color)) {
|
||||
let col = DOMUtils.colorToRGBA(color);
|
||||
let col = InspectorUtils.colorToRGBA(color);
|
||||
color = col && [col.r, col.g, col.b, Math.round(col.a * 255)];
|
||||
}
|
||||
browserAction.setProperty(tab, "badgeBackgroundColor", color);
|
||||
|
|
|
@ -26,6 +26,7 @@ skip-if = (os == 'win' && ccov) # Bug 1423667
|
|||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
[browser_bookmarkProperties_addLivemark.js]
|
||||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
[browser_bookmarkProperties_addTags.js]
|
||||
[browser_bookmarkProperties_bookmarkAllTabs.js]
|
||||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
[browser_bookmarkProperties_cancel.js]
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Test that tags can be added to bookmarks using the star-shaped button.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
let bookmarkPanel = document.getElementById("editBookmarkPanel");
|
||||
let doneButton = document.getElementById("editBookmarkPanelDoneButton");
|
||||
let bookmarkStar = BookmarkingUI.star;
|
||||
let bookmarkPanelTitle = document.getElementById("editBookmarkPanelTitle");
|
||||
let TEST_URL = "about:buildconfig";
|
||||
|
||||
async function clickBookmarkStar() {
|
||||
let shownPromise = promisePopupShown(bookmarkPanel);
|
||||
bookmarkStar.click();
|
||||
await shownPromise;
|
||||
}
|
||||
|
||||
async function hideBookmarksPanel(callback) {
|
||||
let hiddenPromise = promisePopupHidden(bookmarkPanel);
|
||||
callback();
|
||||
await hiddenPromise;
|
||||
}
|
||||
|
||||
add_task(async function test_add_tags() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
opening: TEST_URL,
|
||||
waitForStateStop: true
|
||||
});
|
||||
|
||||
// The bookmarks panel is expected to auto-close after this step.
|
||||
await hideBookmarksPanel(async () => {
|
||||
// Click the bookmark star to bookmark the page.
|
||||
await clickBookmarkStar();
|
||||
Assert.equal(bookmarkPanelTitle.value, gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle"), "Bookmark title is correct");
|
||||
Assert.equal(bookmarkStar.getAttribute("starred"), "true", "Page is starred");
|
||||
});
|
||||
|
||||
// Click the bookmark star again to add tags.
|
||||
await clickBookmarkStar();
|
||||
Assert.equal(bookmarkPanelTitle.value, gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle"), "Bookmark title is correct");
|
||||
let promiseNotification = PlacesTestUtils.waitForNotification("onItemAdded", (id, parentId, index, type, itemUrl) => {
|
||||
if (itemUrl !== null) {
|
||||
return itemUrl.equals(Services.io.newURI(TEST_URL));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
await fillBookmarkTextField("editBMPanel_tagsField", "tag1", window);
|
||||
await promiseNotification;
|
||||
let bookmarks = [];
|
||||
await PlacesUtils.bookmarks.fetch({ url: TEST_URL }, bm => bookmarks.push(bm));
|
||||
Assert.equal(PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL)).length, 1, "Found the right number of tags");
|
||||
Assert.deepEqual(PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL)), ["tag1"]);
|
||||
await hideBookmarksPanel(() => doneButton.click());
|
||||
|
||||
// Click the bookmark star again, add more tags.
|
||||
await clickBookmarkStar();
|
||||
promiseNotification = PlacesTestUtils.waitForNotification("onItemChanged", (id, property) => property == "tags");
|
||||
await fillBookmarkTextField("editBMPanel_tagsField", "tag1, tag2, tag3", window);
|
||||
await promiseNotification;
|
||||
await hideBookmarksPanel(() => doneButton.click());
|
||||
|
||||
bookmarks = [];
|
||||
await PlacesUtils.bookmarks.fetch({ url: TEST_URL }, bm => bookmarks.push(bm));
|
||||
Assert.equal(bookmarks.length, 1, "Only one bookmark should exist");
|
||||
Assert.equal(PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL)).length, 3, "Found the right number of tags");
|
||||
Assert.deepEqual(PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL)), ["tag1", "tag2", "tag3"]);
|
||||
|
||||
// Cleanup.
|
||||
registerCleanupFunction(async function() {
|
||||
await PlacesUtils.bookmarks.eraseEverything();
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
|
@ -445,3 +445,29 @@ function promisePlacesInitComplete() {
|
|||
|
||||
return placesInitCompleteObserved;
|
||||
}
|
||||
|
||||
// Function copied from browser/base/content/test/general/head.js.
|
||||
function promisePopupShown(popup) {
|
||||
return new Promise(resolve => {
|
||||
if (popup.state == "open") {
|
||||
resolve();
|
||||
} else {
|
||||
let onPopupShown = event => {
|
||||
popup.removeEventListener("popupshown", onPopupShown);
|
||||
resolve();
|
||||
};
|
||||
popup.addEventListener("popupshown", onPopupShown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function copied from browser/base/content/test/general/head.js.
|
||||
function promisePopupHidden(popup) {
|
||||
return new Promise(resolve => {
|
||||
let onPopupHidden = event => {
|
||||
popup.removeEventListener("popuphidden", onPopupHidden);
|
||||
resolve();
|
||||
};
|
||||
popup.addEventListener("popuphidden", onPopupHidden);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ let setupTest = async function(options, testFunction) {
|
|||
let private = options.private || false;
|
||||
let newWin = await promiseNewWindowLoaded({ private });
|
||||
|
||||
injectTestTabs(newWin);
|
||||
await injectTestTabs(newWin);
|
||||
|
||||
await testFunction(newWin, observing);
|
||||
|
||||
|
@ -163,9 +163,9 @@ let setupTest = async function(options, testFunction) {
|
|||
* The browser window to load the tabs in
|
||||
*/
|
||||
function injectTestTabs(win) {
|
||||
TEST_URLS.forEach(function(url) {
|
||||
win.gBrowser.addTab(url);
|
||||
});
|
||||
let promises = TEST_URLS.map(url => win.gBrowser.addTab(url))
|
||||
.map(tab => BrowserTestUtils.browserLoaded(tab.linkedBrowser));
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,8 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/Timer.jsm");
|
||||
Cu.import("resource://gre/modules/BrowserUtils.jsm");
|
||||
|
||||
Cu.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
|
||||
const url = "chrome://browser/locale/browser.properties";
|
||||
return Services.strings.createBundle(url);
|
||||
|
@ -519,10 +521,8 @@ PluginContent.prototype = {
|
|||
plugin.removeAttribute("href");
|
||||
let overlay = this.getPluginUI(plugin, "main");
|
||||
this.setVisibility(plugin, overlay, OVERLAY_DISPLAY.FULL);
|
||||
let inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
// Add psuedo class so our styling will take effect
|
||||
inIDOMUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
|
||||
// Add pseudo class so our styling will take effect
|
||||
InspectorUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
|
||||
overlay.addEventListener("click", this, true);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
.prefwindow {
|
||||
padding: 0;
|
||||
font: -moz-dialog !important;
|
||||
}
|
||||
|
||||
.prefwindow[type="child"] {
|
||||
|
|
|
@ -17,6 +17,8 @@ Cu.import("resource://gre/modules/Timer.jsm");
|
|||
Cu.import("resource://testing-common/TestUtils.jsm");
|
||||
Cu.import("resource://testing-common/BrowserTestUtils.jsm");
|
||||
|
||||
Cu.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
this.Tabs = {
|
||||
init(libDir) {},
|
||||
|
||||
|
@ -189,11 +191,10 @@ function closeAllButOneTab(url = "about:blank") {
|
|||
}
|
||||
|
||||
function hoverTab(tab, hover = true) {
|
||||
const inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
if (hover) {
|
||||
inIDOMUtils.addPseudoClassLock(tab, ":hover");
|
||||
InspectorUtils.addPseudoClassLock(tab, ":hover");
|
||||
} else {
|
||||
inIDOMUtils.clearPseudoClassLocks(tab);
|
||||
InspectorUtils.clearPseudoClassLocks(tab);
|
||||
}
|
||||
// XXX TODO: this isn't necessarily testing what we ship
|
||||
if (tab.nextElementSibling)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# -*- Mode: python; 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/.
|
||||
|
||||
gn_vars = {}
|
||||
|
||||
if CONFIG['MOZ_DEBUG']:
|
||||
gn_vars['is_debug'] = True
|
||||
else:
|
||||
gn_vars['is_debug'] = False
|
||||
|
||||
os = CONFIG['OS_TARGET']
|
||||
|
||||
flavors = {
|
||||
'WINNT': 'win',
|
||||
'Android': 'android',
|
||||
'Linux': 'linux',
|
||||
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
|
||||
'SunOS': 'solaris',
|
||||
'GNU/kFreeBSD': 'freebsd',
|
||||
'DragonFly': 'dragonfly',
|
||||
'FreeBSD': 'freebsd',
|
||||
'NetBSD': 'netbsd',
|
||||
'OpenBSD': 'openbsd',
|
||||
}
|
||||
gn_vars['target_os'] = flavors.get(os)
|
||||
|
||||
arches = {
|
||||
'x86_64': 'x64',
|
||||
'aarch64': 'arm64',
|
||||
}
|
||||
|
||||
gn_vars['host_cpu'] = arches.get(CONFIG['HOST_CPU_ARCH'], CONFIG['HOST_CPU_ARCH'])
|
||||
gn_vars['target_cpu'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
|
|
@ -518,6 +518,12 @@ def check_compiler(compiler, language, target):
|
|||
if not info.cpu or info.cpu != target.cpu:
|
||||
if info.type == 'clang':
|
||||
append_flag('--target=%s' % target.toolchain)
|
||||
elif info.type == 'clang-cl':
|
||||
# Ideally this would share the 'clang' branch above, but on Windows
|
||||
# the --target needs additional data like ms-compatibility-version.
|
||||
if (info.cpu, target.cpu) == ('x86_64', 'x86'):
|
||||
# -m32 does not use -Xclang, so add it directly.
|
||||
flags.append('-m32')
|
||||
elif info.type == 'gcc':
|
||||
same_arch_different_bits = (
|
||||
('x86', 'x86_64'),
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
// Tests that the Filter Editor Widget parses filter values correctly (setCssValue)
|
||||
|
||||
const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget");
|
||||
const DOMUtils =
|
||||
Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const TEST_URI = CHROME_URL_ROOT + "doc_filter-editor-01.html";
|
||||
const {getClientCssProperties} = require("devtools/shared/fronts/css-properties");
|
||||
|
@ -15,7 +14,7 @@ const {getClientCssProperties} = require("devtools/shared/fronts/css-properties"
|
|||
// Verify that the given string consists of a valid CSS URL token.
|
||||
// Return true on success, false on error.
|
||||
function verifyURL(string) {
|
||||
let lexer = DOMUtils.getCSSLexer(string);
|
||||
let lexer = InspectorUtils.getCSSLexer(string);
|
||||
|
||||
let token = lexer.nextToken();
|
||||
if (!token || token.tokenType !== "url") {
|
||||
|
|
|
@ -18,9 +18,9 @@ const {
|
|||
isContentStylesheet,
|
||||
getCSSStyleRules
|
||||
} = require("devtools/shared/inspector/css-logic");
|
||||
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Ci.mozIJSSubScriptLoader);
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
// Set up a dummy environment so that EventUtils works. We need to be careful to
|
||||
// pass a window object into each EventUtils method we call rather than having
|
||||
|
@ -546,7 +546,7 @@ var TestActor = exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
|
|||
*/
|
||||
hasPseudoClassLock: function (selector, pseudo) {
|
||||
let node = this._querySelector(selector);
|
||||
return DOMUtils.hasPseudoClassLock(node, pseudo);
|
||||
return InspectorUtils.hasPseudoClassLock(node, pseudo);
|
||||
},
|
||||
|
||||
loadAndWaitForCustomEvent: function (url) {
|
||||
|
@ -784,8 +784,8 @@ var TestActor = exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
|
|||
|
||||
let sheets = [];
|
||||
|
||||
for (let i = 0, n = domRules.Count(); i < n; i++) {
|
||||
let sheet = domRules.GetElementAt(i).parentStyleSheet;
|
||||
for (let i = 0, n = domRules.length; i < n; i++) {
|
||||
let sheet = domRules[i].parentStyleSheet;
|
||||
sheets.push({
|
||||
href: sheet.href,
|
||||
isContentSheet: isContentStylesheet(sheet)
|
||||
|
|
|
@ -6,15 +6,10 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
|
||||
var {require, loader} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {colorUtils} = require("devtools/shared/css/color");
|
||||
|
||||
loader.lazyGetter(this, "DOMUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const CLASSIFY_TESTS = [
|
||||
{ input: "rgb(255,0,192)", output: "rgb" },
|
||||
|
@ -34,10 +29,10 @@ const CLASSIFY_TESTS = [
|
|||
{ input: "orange", output: "name" }
|
||||
];
|
||||
|
||||
function compareWithDomutils(input, isColor) {
|
||||
function compareWithInspectorUtils(input, isColor) {
|
||||
let ours = colorUtils.colorToRGBA(input);
|
||||
let platform = DOMUtils.colorToRGBA(input);
|
||||
deepEqual(ours, platform, "color " + input + " matches DOMUtils");
|
||||
let platform = InspectorUtils.colorToRGBA(input);
|
||||
deepEqual(ours, platform, "color " + input + " matches InspectorUtils");
|
||||
if (isColor) {
|
||||
ok(ours !== null, "'" + input + "' is a color");
|
||||
} else {
|
||||
|
@ -55,12 +50,12 @@ function run_test() {
|
|||
equal(obj.colorUnit, test.output,
|
||||
"test setAuthoredUnitFromColor(" + test.input + ")");
|
||||
|
||||
// Check that our implementation matches DOMUtils.
|
||||
compareWithDomutils(test.input, true);
|
||||
// Check that our implementation matches InspectorUtils.
|
||||
compareWithInspectorUtils(test.input, true);
|
||||
|
||||
// And check some obvious errors.
|
||||
compareWithDomutils("mumble" + test.input, false);
|
||||
compareWithDomutils(test.input + "trailingstuff", false);
|
||||
compareWithInspectorUtils("mumble" + test.input, false);
|
||||
compareWithInspectorUtils(test.input + "trailingstuff", false);
|
||||
}
|
||||
|
||||
// Regression test for bug 1303826.
|
||||
|
|
|
@ -6,15 +6,10 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
|
||||
var {require, loader} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {colorUtils} = require("devtools/shared/css/color");
|
||||
|
||||
loader.lazyGetter(this, "DOMUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const OLD_STYLE_TESTS = [
|
||||
"rgb(255,0,192)",
|
||||
|
@ -43,19 +38,20 @@ const CSS_COLOR_4_TESTS = [
|
|||
function run_test() {
|
||||
for (let test of OLD_STYLE_TESTS) {
|
||||
let ours = colorUtils.colorToRGBA(test, false);
|
||||
let platform = DOMUtils.colorToRGBA(test);
|
||||
deepEqual(ours, platform, "color " + test + " matches DOMUtils");
|
||||
let platform = InspectorUtils.colorToRGBA(test);
|
||||
deepEqual(ours, platform, "color " + test + " matches InspectorUtils");
|
||||
ok(ours !== null, "'" + test + "' is a color");
|
||||
}
|
||||
|
||||
for (let test of CSS_COLOR_4_TESTS) {
|
||||
let oursOld = colorUtils.colorToRGBA(test, false);
|
||||
let oursNew = colorUtils.colorToRGBA(test, true);
|
||||
let platform = DOMUtils.colorToRGBA(test);
|
||||
let platform = InspectorUtils.colorToRGBA(test);
|
||||
notEqual(oursOld, platform, "old style parser for color " + test +
|
||||
" should not match DOMUtils");
|
||||
" should not match InspectorUtils");
|
||||
ok(oursOld === null, "'" + test + "' is not a color with old parser");
|
||||
deepEqual(oursNew, platform, `css-color-4 parser for color ${test} matches DOMUtils`);
|
||||
deepEqual(oursNew, platform,
|
||||
`css-color-4 parser for color ${test} matches InspectorUtils`);
|
||||
ok(oursNew !== null, "'" + test + "' is a color with css-color-4 parser");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,27 +6,24 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
|
||||
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
|
||||
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
|
||||
const {colorUtils} = require("devtools/shared/css/color");
|
||||
const {cssColors} = require("devtools/shared/css/color-db");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
function isValid(colorName) {
|
||||
ok(colorUtils.isValidCSSColor(colorName),
|
||||
colorName + " is valid in database");
|
||||
ok(DOMUtils.isValidCSSColor(colorName),
|
||||
colorName + " is valid in DOMUtils");
|
||||
ok(InspectorUtils.isValidCSSColor(colorName),
|
||||
colorName + " is valid in InspectorUtils");
|
||||
}
|
||||
|
||||
function checkOne(colorName, checkName) {
|
||||
let ours = colorUtils.colorToRGBA(colorName);
|
||||
let fromDom = DOMUtils.colorToRGBA(colorName);
|
||||
deepEqual(ours, fromDom, colorName + " agrees with DOMUtils");
|
||||
let fromDom = InspectorUtils.colorToRGBA(colorName);
|
||||
deepEqual(ours, fromDom, colorName + " agrees with InspectorUtils");
|
||||
|
||||
isValid(colorName);
|
||||
|
||||
|
@ -34,13 +31,13 @@ function checkOne(colorName, checkName) {
|
|||
let {r, g, b} = ours;
|
||||
|
||||
// The color we got might not map back to the same name; but our
|
||||
// implementation should agree with DOMUtils about which name is
|
||||
// implementation should agree with InspectorUtils about which name is
|
||||
// canonical.
|
||||
let ourName = colorUtils.rgbToColorName(r, g, b);
|
||||
let domName = DOMUtils.rgbToColorName(r, g, b);
|
||||
let domName = InspectorUtils.rgbToColorName(r, g, b);
|
||||
|
||||
equal(ourName, domName,
|
||||
colorName + " canonical name agrees with DOMUtils");
|
||||
colorName + " canonical name agrees with InspectorUtils");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +49,7 @@ function run_test() {
|
|||
|
||||
// Now check that platform didn't add a new name when we weren't
|
||||
// looking.
|
||||
let names = DOMUtils.getCSSValuesForProperty("background-color");
|
||||
let names = InspectorUtils.getCSSValuesForProperty("background-color");
|
||||
for (let name of names) {
|
||||
if (name !== "hsl" && name !== "hsla" &&
|
||||
name !== "rgb" && name !== "rgba" &&
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
*/
|
||||
|
||||
const EventEmitter = require("devtools/shared/old-event-emitter");
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
@ -21,10 +20,6 @@ const {cssTokenizer} = require("devtools/shared/css/parsing-utils");
|
|||
|
||||
const asyncStorage = require("devtools/shared/async-storage");
|
||||
|
||||
loader.lazyGetter(this, "DOMUtils", () => {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
|
||||
const DEFAULT_FILTER_TYPE = "length";
|
||||
const UNIT_MAPPING = {
|
||||
percentage: "%",
|
||||
|
|
|
@ -82,8 +82,6 @@ function pushPrefEnv() {
|
|||
const prefs = [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
["security.mixed_content.block_display_content", true],
|
||||
["security.mixed_content.use_hsts", false],
|
||||
["security.mixed_content.send_hsts_priming", false],
|
||||
];
|
||||
|
||||
return Promise.all(prefs.map(([pref, value]) => pushPref(pref, value)));
|
||||
|
|
|
@ -61,8 +61,6 @@ function pushPrefEnv() {
|
|||
"set": [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
["security.mixed_content.block_display_content", true],
|
||||
["security.mixed_content.use_hsts", false],
|
||||
["security.mixed_content.send_hsts_priming", false],
|
||||
]
|
||||
};
|
||||
SpecialPowers.pushPrefEnv(options, deferred.resolve);
|
||||
|
|
|
@ -95,10 +95,6 @@ function testXhrWarn() {
|
|||
|
||||
let lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE);
|
||||
if (lastRequest.request.method == "HEAD") {
|
||||
// in non-e10s, we get the HEAD request that priming sends, so make sure
|
||||
// a priming request should be sent, and then get the actual request
|
||||
is(Services.prefs.getBoolPref("security.mixed_content.send_hsts_priming"),
|
||||
true, "Found HSTS Priming Request");
|
||||
lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
loader.lazyServiceGetter(this, "DOMUtils",
|
||||
"@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
|
||||
loader.lazyRequireGetter(this, "CSS_TYPES",
|
||||
"devtools/shared/css/properties-db", true);
|
||||
|
||||
|
@ -13,6 +11,7 @@ const protocol = require("devtools/shared/protocol");
|
|||
const { ActorClassWithSpec, Actor } = protocol;
|
||||
const { cssPropertiesSpec } = require("devtools/shared/specs/css-properties");
|
||||
const { cssColors } = require("devtools/shared/css/color-db");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
exports.CssPropertiesActor = ActorClassWithSpec(cssPropertiesSpec, {
|
||||
typeName: "cssProperties",
|
||||
|
@ -27,10 +26,10 @@ exports.CssPropertiesActor = ActorClassWithSpec(cssPropertiesSpec, {
|
|||
|
||||
getCSSDatabase() {
|
||||
const properties = generateCssProperties();
|
||||
const pseudoElements = DOMUtils.getCSSPseudoElementNames();
|
||||
const pseudoElements = InspectorUtils.getCSSPseudoElementNames();
|
||||
const supportedFeature = {
|
||||
// checking for css-color-4 color function support.
|
||||
"css-color-4-color-function": DOMUtils.isValidCSSColor("rgb(1 1 1 / 100%)"),
|
||||
"css-color-4-color-function": InspectorUtils.isValidCSSColor("rgb(1 1 1 / 100%)"),
|
||||
};
|
||||
|
||||
return { properties, pseudoElements, supportedFeature };
|
||||
|
@ -45,29 +44,29 @@ exports.CssPropertiesActor = ActorClassWithSpec(cssPropertiesSpec, {
|
|||
*/
|
||||
function generateCssProperties() {
|
||||
const properties = {};
|
||||
const propertyNames = DOMUtils.getCSSPropertyNames(DOMUtils.INCLUDE_ALIASES);
|
||||
const propertyNames = InspectorUtils.getCSSPropertyNames({ includeAliases: true });
|
||||
const colors = Object.keys(cssColors);
|
||||
|
||||
propertyNames.forEach(name => {
|
||||
// Get the list of CSS types this property supports.
|
||||
let supports = [];
|
||||
for (let type in CSS_TYPES) {
|
||||
if (safeCssPropertySupportsType(name, DOMUtils["TYPE_" + type])) {
|
||||
if (safeCssPropertySupportsType(name, InspectorUtils["TYPE_" + type])) {
|
||||
supports.push(CSS_TYPES[type]);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't send colors over RDP, these will be re-attached by the front.
|
||||
let values = DOMUtils.getCSSValuesForProperty(name);
|
||||
let values = InspectorUtils.getCSSValuesForProperty(name);
|
||||
if (values.includes("aliceblue")) {
|
||||
values = values.filter(x => !colors.includes(x));
|
||||
values.unshift("COLOR");
|
||||
}
|
||||
|
||||
let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name);
|
||||
let subproperties = InspectorUtils.getSubpropertiesForCSSProperty(name);
|
||||
|
||||
properties[name] = {
|
||||
isInherited: DOMUtils.isInheritedProperty(name),
|
||||
isInherited: InspectorUtils.isInheritedProperty(name),
|
||||
values,
|
||||
supports,
|
||||
subproperties,
|
||||
|
@ -89,7 +88,7 @@ function isCssPropertyKnown(name) {
|
|||
// If the property name is unknown, the cssPropertyIsShorthand
|
||||
// will throw an exception. But if it is known, no exception will
|
||||
// be thrown; so we just ignore the return value.
|
||||
DOMUtils.cssPropertyIsShorthand(name);
|
||||
InspectorUtils.cssPropertyIsShorthand(name);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
@ -99,7 +98,7 @@ function isCssPropertyKnown(name) {
|
|||
exports.isCssPropertyKnown = isCssPropertyKnown;
|
||||
|
||||
/**
|
||||
* A wrapper for DOMUtils.cssPropertySupportsType that ignores invalid
|
||||
* A wrapper for InspectorUtils.cssPropertySupportsType that ignores invalid
|
||||
* properties.
|
||||
*
|
||||
* @param {String} name The property name.
|
||||
|
@ -109,7 +108,7 @@ exports.isCssPropertyKnown = isCssPropertyKnown;
|
|||
*/
|
||||
function safeCssPropertySupportsType(name, type) {
|
||||
try {
|
||||
return DOMUtils.cssPropertySupportsType(name, type);
|
||||
return InspectorUtils.cssPropertySupportsType(name, type);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,17 +4,15 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const { Ci } = require("chrome");
|
||||
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
const Services = require("Services");
|
||||
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const { cssUsageSpec } = require("devtools/shared/specs/csscoverage");
|
||||
|
||||
loader.lazyGetter(this, "DOMUtils", () => {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
loader.lazyRequireGetter(this, "stylesheets", "devtools/server/actors/stylesheets");
|
||||
loader.lazyRequireGetter(this, "prettifyCSS", "devtools/shared/inspector/css-logic", true);
|
||||
|
||||
|
@ -541,8 +539,8 @@ function getImportedSheets(stylesheet) {
|
|||
* @see deconstructRuleId(ruleId)
|
||||
*/
|
||||
function ruleToId(rule) {
|
||||
let line = DOMUtils.getRelativeRuleLine(rule);
|
||||
let column = DOMUtils.getRuleColumn(rule);
|
||||
let line = InspectorUtils.getRelativeRuleLine(rule);
|
||||
let column = InspectorUtils.getRuleColumn(rule);
|
||||
return sheetToUrl(rule.parentStyleSheet) + "|" + line + "|" + column;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
let doc = this.win.document;
|
||||
|
||||
let highlighterContainer = doc.createElement("div");
|
||||
highlighterContainer.setAttribute("role", "presentation");
|
||||
highlighterContainer.className = "highlighter-container box-model";
|
||||
|
||||
// Build the root wrapper, used to adapt to the page zoom.
|
||||
|
@ -126,7 +127,8 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
parent: highlighterContainer,
|
||||
attributes: {
|
||||
"id": "root",
|
||||
"class": "root"
|
||||
"class": "root",
|
||||
"role": "presentation"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
@ -140,7 +142,8 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
"id": "elements",
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
"hidden": "true"
|
||||
"hidden": "true",
|
||||
"role": "presentation"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
@ -149,7 +152,8 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
nodeType: "g",
|
||||
parent: svg,
|
||||
attributes: {
|
||||
"class": "regions"
|
||||
"class": "regions",
|
||||
"role": "presentation"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
@ -160,7 +164,8 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
parent: regions,
|
||||
attributes: {
|
||||
"class": region,
|
||||
"id": region
|
||||
"id": region,
|
||||
"role": "presentation"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
@ -173,7 +178,8 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
|
|||
attributes: {
|
||||
"class": "guide-" + side,
|
||||
"id": "guide-" + side,
|
||||
"stroke-width": GUIDE_STROKE_WIDTH
|
||||
"stroke-width": GUIDE_STROKE_WIDTH,
|
||||
"role": "presentation"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
|
|
@ -131,8 +131,8 @@ function getDefinedGeometryProperties(node) {
|
|||
|
||||
// Get the list of css rules applying to the current node.
|
||||
let cssRules = getCSSStyleRules(node);
|
||||
for (let i = 0; i < cssRules.Count(); i++) {
|
||||
let rule = cssRules.GetElementAt(i);
|
||||
for (let i = 0; i < cssRules.length; i++) {
|
||||
let rule = cssRules[i];
|
||||
for (let name of GeoProp.allProps()) {
|
||||
let value = rule.style.getPropertyValue(name);
|
||||
if (value && value !== "auto") {
|
||||
|
|
|
@ -2517,8 +2517,8 @@ function getDefinedShapeProperties(node, property) {
|
|||
}
|
||||
|
||||
let cssRules = getCSSStyleRules(node);
|
||||
for (let i = 0; i < cssRules.Count(); i++) {
|
||||
let rule = cssRules.GetElementAt(i);
|
||||
for (let i = 0; i < cssRules.length; i++) {
|
||||
let rule = cssRules[i];
|
||||
let value = rule.style.getPropertyValue(property);
|
||||
if (value && value !== "auto") {
|
||||
prop = value;
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { Cc, Ci, Cu, Cr } = require("chrome");
|
||||
const { Ci, Cu, Cr } = require("chrome");
|
||||
const { getCurrentZoom, getWindowDimensions, getViewportDimensions,
|
||||
getRootBindingParent, loadSheet } = require("devtools/shared/layout/utils");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const lazyContainer = {};
|
||||
|
||||
|
@ -19,16 +20,14 @@ exports.getComputedStyle = (node) =>
|
|||
exports.getBindingElementAndPseudo = (node) =>
|
||||
lazyContainer.CssLogic.getBindingElementAndPseudo(node);
|
||||
|
||||
loader.lazyGetter(lazyContainer, "DOMUtils", () =>
|
||||
Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils));
|
||||
exports.hasPseudoClassLock = (...args) =>
|
||||
lazyContainer.DOMUtils.hasPseudoClassLock(...args);
|
||||
InspectorUtils.hasPseudoClassLock(...args);
|
||||
|
||||
exports.addPseudoClassLock = (...args) =>
|
||||
lazyContainer.DOMUtils.addPseudoClassLock(...args);
|
||||
InspectorUtils.addPseudoClassLock(...args);
|
||||
|
||||
exports.removePseudoClassLock = (...args) =>
|
||||
lazyContainer.DOMUtils.removePseudoClassLock(...args);
|
||||
InspectorUtils.removePseudoClassLock(...args);
|
||||
|
||||
const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
|
|
@ -58,6 +58,7 @@ const promise = require("promise");
|
|||
const defer = require("devtools/shared/defer");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const {walkerSpec, inspectorSpec} = require("devtools/shared/specs/inspector");
|
||||
const {nodeSpec, nodeListSpec} = require("devtools/shared/specs/node");
|
||||
|
@ -427,7 +428,7 @@ var NodeActor = exports.NodeActor = protocol.ActorClassWithSpec(nodeSpec, {
|
|||
}
|
||||
let ret = undefined;
|
||||
for (let pseudo of PSEUDO_CLASSES) {
|
||||
if (DOMUtils.hasPseudoClassLock(this.rawNode, pseudo)) {
|
||||
if (InspectorUtils.hasPseudoClassLock(this.rawNode, pseudo)) {
|
||||
ret = ret || [];
|
||||
ret.push(pseudo);
|
||||
}
|
||||
|
@ -1843,7 +1844,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
// There can be only one node locked per pseudo, so dismiss all existing
|
||||
// ones
|
||||
for (let locked of this._activePseudoClassLocks) {
|
||||
if (DOMUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
|
||||
if (InspectorUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
|
||||
this._removePseudoClassLock(locked, pseudo);
|
||||
}
|
||||
}
|
||||
|
@ -1876,7 +1877,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
if (node.rawNode.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
|
||||
return false;
|
||||
}
|
||||
DOMUtils.addPseudoClassLock(node.rawNode, pseudo, enabled);
|
||||
InspectorUtils.addPseudoClassLock(node.rawNode, pseudo, enabled);
|
||||
this._activePseudoClassLocks.add(node);
|
||||
this._queuePseudoClassMutation(node);
|
||||
return true;
|
||||
|
@ -1924,7 +1925,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
// turning it on for some childs without setting it on some parents
|
||||
for (let locked of this._activePseudoClassLocks) {
|
||||
if (node.rawNode.contains(locked.rawNode) &&
|
||||
DOMUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
|
||||
InspectorUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
|
||||
this._removePseudoClassLock(locked, pseudo);
|
||||
}
|
||||
}
|
||||
|
@ -1945,7 +1946,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
if (node.rawNode.nodeType != Ci.nsIDOMNode.ELEMENT_NODE) {
|
||||
return false;
|
||||
}
|
||||
DOMUtils.removePseudoClassLock(node.rawNode, pseudo);
|
||||
InspectorUtils.removePseudoClassLock(node.rawNode, pseudo);
|
||||
if (!node.writePseudoClassLocks()) {
|
||||
this._activePseudoClassLocks.delete(node);
|
||||
}
|
||||
|
@ -1964,12 +1965,12 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
}
|
||||
|
||||
if (node) {
|
||||
DOMUtils.clearPseudoClassLocks(node.rawNode);
|
||||
InspectorUtils.clearPseudoClassLocks(node.rawNode);
|
||||
this._activePseudoClassLocks.delete(node);
|
||||
this._queuePseudoClassMutation(node);
|
||||
} else {
|
||||
for (let locked of this._activePseudoClassLocks) {
|
||||
DOMUtils.clearPseudoClassLocks(locked.rawNode);
|
||||
InspectorUtils.clearPseudoClassLocks(locked.rawNode);
|
||||
this._activePseudoClassLocks.delete(locked);
|
||||
this._queuePseudoClassMutation(locked);
|
||||
}
|
||||
|
@ -3401,7 +3402,3 @@ var imageToImageData = Task.async(function* (node, maxDim) {
|
|||
}
|
||||
};
|
||||
});
|
||||
|
||||
loader.lazyGetter(this, "DOMUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
|
|
|
@ -1770,7 +1770,6 @@ DebuggerServer.ObjectActorPreviewers.Object = [
|
|||
rawObj instanceof Ci.nsIDOMCSSRuleList ||
|
||||
rawObj instanceof Ci.nsIDOMCSSValueList ||
|
||||
rawObj instanceof Ci.nsIDOMFileList ||
|
||||
rawObj instanceof Ci.nsIDOMFontFaceList ||
|
||||
rawObj instanceof Ci.nsIDOMMediaList ||
|
||||
rawObj instanceof Ci.nsIDOMNodeList ||
|
||||
rawObj instanceof Ci.nsIDOMStyleSheetList)) {
|
||||
|
|
|
@ -9,6 +9,7 @@ const promise = require("promise");
|
|||
const protocol = require("devtools/shared/protocol");
|
||||
const {LongStringActor} = require("devtools/server/actors/string");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
// This will also add the "stylesheet" actor type for protocol.js to recognize
|
||||
|
||||
|
@ -27,10 +28,8 @@ loader.lazyRequireGetter(this, "UPDATE_PRESERVING_RULES",
|
|||
loader.lazyRequireGetter(this, "UPDATE_GENERAL",
|
||||
"devtools/server/actors/stylesheets", true);
|
||||
|
||||
loader.lazyServiceGetter(this, "DOMUtils", "@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
|
||||
|
||||
loader.lazyGetter(this, "PSEUDO_ELEMENTS", () => {
|
||||
return DOMUtils.getCSSPseudoElementNames();
|
||||
return InspectorUtils.getCSSPseudoElementNames();
|
||||
});
|
||||
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
@ -63,7 +62,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
"creating a PageStyleActor.");
|
||||
}
|
||||
this.walker = inspector.walker;
|
||||
this.cssLogic = new CssLogic(DOMUtils.isInheritedProperty);
|
||||
this.cssLogic = new CssLogic(InspectorUtils.isInheritedProperty);
|
||||
|
||||
// Stores the association of DOM objects -> actors
|
||||
this.refMap = new Map();
|
||||
|
@ -271,11 +270,11 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
// We don't get fonts for a node, but for a range
|
||||
let rng = contentDocument.createRange();
|
||||
rng.selectNodeContents(actualNode);
|
||||
let fonts = DOMUtils.getUsedFontFaces(rng);
|
||||
let fonts = InspectorUtils.getUsedFontFaces(rng);
|
||||
let fontsArray = [];
|
||||
|
||||
for (let i = 0; i < fonts.length; i++) {
|
||||
let font = fonts.item(i);
|
||||
let font = fonts[i];
|
||||
let fontFace = {
|
||||
name: font.name,
|
||||
CSSFamilyName: font.CSSFamilyName,
|
||||
|
@ -466,7 +465,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
|
||||
_hasInheritedProps: function (style) {
|
||||
return Array.prototype.some.call(style, prop => {
|
||||
return DOMUtils.isInheritedProperty(prop);
|
||||
return InspectorUtils.isInheritedProperty(prop);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -568,7 +567,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
* @returns Array
|
||||
*/
|
||||
_getElementRules: function (node, pseudo, inherited, options) {
|
||||
let domRules = DOMUtils.getCSSStyleRules(node, pseudo);
|
||||
let domRules = InspectorUtils.getCSSStyleRules(node, pseudo);
|
||||
if (!domRules) {
|
||||
return [];
|
||||
}
|
||||
|
@ -577,8 +576,8 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
|
||||
// getCSSStyleRules returns ordered from least-specific to
|
||||
// most-specific.
|
||||
for (let i = domRules.Count() - 1; i >= 0; i--) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
for (let i = domRules.length - 1; i >= 0; i--) {
|
||||
let domRule = domRules[i];
|
||||
|
||||
let isSystem = !SharedCssLogic.isContentStylesheet(domRule.parentStyleSheet);
|
||||
|
||||
|
@ -590,7 +589,7 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
// Don't include inherited rules if none of its properties
|
||||
// are inheritable.
|
||||
let hasInherited = [...domRule.style].some(
|
||||
prop => DOMUtils.isInheritedProperty(prop)
|
||||
prop => InspectorUtils.isInheritedProperty(prop)
|
||||
);
|
||||
if (!hasInherited) {
|
||||
continue;
|
||||
|
@ -678,8 +677,8 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
|
|||
CssLogic.getBindingElementAndPseudo(element);
|
||||
entry.matchedSelectors = [];
|
||||
for (let i = 0; i < selectors.length; i++) {
|
||||
if (DOMUtils.selectorMatchesElement(bindingElement, domRule, i,
|
||||
pseudo)) {
|
||||
if (InspectorUtils.selectorMatchesElement(bindingElement, domRule, i,
|
||||
pseudo)) {
|
||||
entry.matchedSelectors.push(selectors[i]);
|
||||
}
|
||||
}
|
||||
|
@ -954,8 +953,8 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
|
|||
if ((this.type === Ci.nsIDOMCSSRule.STYLE_RULE ||
|
||||
this.type === Ci.nsIDOMCSSRule.KEYFRAME_RULE) &&
|
||||
this.rawRule.parentStyleSheet) {
|
||||
this.line = DOMUtils.getRelativeRuleLine(this.rawRule);
|
||||
this.column = DOMUtils.getRuleColumn(this.rawRule);
|
||||
this.line = InspectorUtils.getRelativeRuleLine(this.rawRule);
|
||||
this.column = InspectorUtils.getRuleColumn(this.rawRule);
|
||||
this._parentSheet = this.rawRule.parentStyleSheet;
|
||||
this._computeRuleIndex();
|
||||
this.sheetActor = this.pageStyle._sheetRef(this._parentSheet);
|
||||
|
@ -1216,8 +1215,8 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
|
|||
// Also tell the page style so that future calls to _styleRef
|
||||
// return the same StyleRuleActor.
|
||||
this.pageStyle.updateStyleRef(oldRule, this.rawRule, this);
|
||||
let line = DOMUtils.getRelativeRuleLine(this.rawRule);
|
||||
let column = DOMUtils.getRuleColumn(this.rawRule);
|
||||
let line = InspectorUtils.getRelativeRuleLine(this.rawRule);
|
||||
let column = InspectorUtils.getRuleColumn(this.rawRule);
|
||||
if (line !== this.line || column !== this.column) {
|
||||
this._notifyLocationChanged(line, column);
|
||||
}
|
||||
|
@ -1583,7 +1582,7 @@ function getRuleText(initialText, line, column) {
|
|||
|
||||
let {offset: textOffset, text} =
|
||||
getTextAtLineColumn(initialText, line, column);
|
||||
let lexer = DOMUtils.getCSSLexer(text);
|
||||
let lexer = InspectorUtils.getCSSLexer(text);
|
||||
|
||||
// Search forward for the opening brace.
|
||||
while (true) {
|
||||
|
@ -1657,7 +1656,7 @@ function getSelectorOffsets(initialText, line, column) {
|
|||
|
||||
let {offset: textOffset, text} =
|
||||
getTextAtLineColumn(initialText, line, column);
|
||||
let lexer = DOMUtils.getCSSLexer(text);
|
||||
let lexer = InspectorUtils.getCSSLexer(text);
|
||||
|
||||
// Search forward for the opening brace.
|
||||
let endOffset;
|
||||
|
|
|
@ -16,6 +16,7 @@ const {mediaRuleSpec, styleSheetSpec,
|
|||
styleSheetsSpec} = require("devtools/shared/specs/stylesheets");
|
||||
const {
|
||||
addPseudoClassLock, removePseudoClassLock } = require("devtools/server/actors/highlighters/utils/markup");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
loader.lazyRequireGetter(this, "CssLogic", "devtools/shared/inspector/css-logic");
|
||||
loader.lazyRequireGetter(this, "addPseudoClassLock",
|
||||
|
@ -24,8 +25,6 @@ loader.lazyRequireGetter(this, "removePseudoClassLock",
|
|||
"devtools/server/actors/highlighters/utils/markup", true);
|
||||
loader.lazyRequireGetter(this, "loadSheet", "devtools/shared/layout/utils", true);
|
||||
|
||||
loader.lazyServiceGetter(this, "DOMUtils", "@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
|
||||
|
||||
var TRANSITION_PSEUDO_CLASS = ":-moz-styleeditor-transitioning";
|
||||
var TRANSITION_DURATION_MS = 500;
|
||||
var TRANSITION_BUFFER_MS = 1000;
|
||||
|
@ -83,8 +82,8 @@ var MediaRuleActor = protocol.ActorClassWithSpec(mediaRuleSpec, {
|
|||
|
||||
this._matchesChange = this._matchesChange.bind(this);
|
||||
|
||||
this.line = DOMUtils.getRuleLine(mediaRule);
|
||||
this.column = DOMUtils.getRuleColumn(mediaRule);
|
||||
this.line = InspectorUtils.getRuleLine(mediaRule);
|
||||
this.column = InspectorUtils.getRuleColumn(mediaRule);
|
||||
|
||||
try {
|
||||
this.mql = this.window.matchMedia(mediaRule.media.mediaText);
|
||||
|
@ -253,7 +252,7 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
|
|||
|
||||
for (let i = 0; i < rules.length; i++) {
|
||||
let rule = rules[i];
|
||||
if (DOMUtils.getRelativeRuleLine(rule) === 0) {
|
||||
if (InspectorUtils.getRelativeRuleLine(rule) === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -594,7 +593,7 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
|
|||
* 'kind' - either UPDATE_PRESERVING_RULES or UPDATE_GENERAL
|
||||
*/
|
||||
update: function (text, transition, kind = UPDATE_GENERAL) {
|
||||
DOMUtils.parseStyleSheet(this.rawSheet, text);
|
||||
InspectorUtils.parseStyleSheet(this.rawSheet, text);
|
||||
|
||||
modifiedStyleSheets.set(this.rawSheet, text);
|
||||
|
||||
|
@ -805,7 +804,8 @@ var StyleSheetsActor = protocol.ActorClassWithSpec(styleSheetsSpec, {
|
|||
doc.styleSheetChangeEventsEnabled = true;
|
||||
|
||||
let isChrome = Services.scriptSecurityManager.isSystemPrincipal(doc.nodePrincipal);
|
||||
let styleSheets = isChrome ? DOMUtils.getAllStyleSheets(doc) : doc.styleSheets;
|
||||
let styleSheets =
|
||||
isChrome ? InspectorUtils.getAllStyleSheets(doc) : doc.styleSheets;
|
||||
let actors = [];
|
||||
for (let i = 0; i < styleSheets.length; i++) {
|
||||
let sheet = styleSheets[i];
|
||||
|
|
|
@ -29,8 +29,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { Cc, Ci, Cu } = require("chrome");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const { Cu } = require("chrome");
|
||||
const nodeConstants = require("devtools/shared/dom-node-constants");
|
||||
const {
|
||||
getBindingElementAndPseudo,
|
||||
|
@ -41,6 +40,7 @@ const {
|
|||
FILTER,
|
||||
STATUS
|
||||
} = require("devtools/shared/inspector/css-logic");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
/**
|
||||
* @param {function} isInherited A function that determines if the CSS property
|
||||
|
@ -474,7 +474,7 @@ CssLogic.prototype = {
|
|||
selectorMatchesElement: function (domRule, idx) {
|
||||
let element = this.viewedElement;
|
||||
do {
|
||||
if (domUtils.selectorMatchesElement(element, domRule, idx)) {
|
||||
if (InspectorUtils.selectorMatchesElement(element, domRule, idx)) {
|
||||
return true;
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
|
@ -552,9 +552,9 @@ CssLogic.prototype = {
|
|||
}
|
||||
|
||||
// getCSSStyleRules can return null with a shadow DOM element.
|
||||
let numDomRules = domRules ? domRules.Count() : 0;
|
||||
let numDomRules = domRules ? domRules.length : 0;
|
||||
for (let i = 0; i < numDomRules; i++) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
let domRule = domRules[i];
|
||||
if (domRule.type !== CSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
@ -640,9 +640,9 @@ CssLogic.getShortName = function (element) {
|
|||
CssLogic.getSelectors = function (domRule) {
|
||||
let selectors = [];
|
||||
|
||||
let len = domUtils.getSelectorCount(domRule);
|
||||
let len = InspectorUtils.getSelectorCount(domRule);
|
||||
for (let i = 0; i < len; i++) {
|
||||
let text = domUtils.getSelectorText(domRule, i);
|
||||
let text = InspectorUtils.getSelectorText(domRule, i);
|
||||
selectors.push(text);
|
||||
}
|
||||
return selectors;
|
||||
|
@ -904,8 +904,8 @@ function CssRule(cssSheet, domRule, element) {
|
|||
if (this._cssSheet) {
|
||||
// parse domRule.selectorText on call to this.selectors
|
||||
this._selectors = null;
|
||||
this.line = domUtils.getRuleLine(this.domRule);
|
||||
this.column = domUtils.getRuleColumn(this.domRule);
|
||||
this.line = InspectorUtils.getRuleLine(this.domRule);
|
||||
this.column = InspectorUtils.getRuleColumn(this.domRule);
|
||||
this.source = this._cssSheet.shortSource + ":" + this.line;
|
||||
if (this.mediaText) {
|
||||
this.source += " @media " + this.mediaText;
|
||||
|
@ -1129,8 +1129,8 @@ CssSelector.prototype = {
|
|||
return this._specificity;
|
||||
}
|
||||
|
||||
this._specificity = domUtils.getSpecificity(this.cssRule.domRule,
|
||||
this.selectorIndex);
|
||||
this._specificity = InspectorUtils.getSpecificity(this.cssRule.domRule,
|
||||
this.selectorIndex);
|
||||
|
||||
return this._specificity;
|
||||
},
|
||||
|
@ -1483,7 +1483,3 @@ CssSelectorInfo.prototype = {
|
|||
return this.selector + " -> " + this.value;
|
||||
},
|
||||
};
|
||||
|
||||
DevToolsUtils.defineLazyGetter(this, "domUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
|
|
|
@ -28,9 +28,7 @@ Test that css-logic handles media-queries correctly
|
|||
"use strict";
|
||||
|
||||
window.onload = function () {
|
||||
const { classes: Cc, utils: Cu, interfaces: Ci } = Components;
|
||||
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
const { utils: Cu } = Components;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const Services = require("Services");
|
||||
|
@ -39,7 +37,7 @@ Test that css-logic handles media-queries correctly
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let div = document.querySelector("div");
|
||||
let cssLogic = new CssLogic(DOMUtils.isInheritedProperty);
|
||||
let cssLogic = new CssLogic(InspectorUtils.isInheritedProperty);
|
||||
cssLogic.highlight(div);
|
||||
cssLogic.processMatchedSelectors();
|
||||
|
||||
|
|
|
@ -13,12 +13,11 @@ Test that css-logic calculates CSS specificity properly
|
|||
"use strict";
|
||||
|
||||
window.onload = function () {
|
||||
const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
|
||||
const {utils: Cu} = Components;
|
||||
|
||||
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {CssLogic, CssSelector} = require("devtools/server/css-logic");
|
||||
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
const InspectorUtils = SpecialPowers.InspectorUtils;
|
||||
|
||||
const TEST_DATA = [
|
||||
{text: "*", expected: 0},
|
||||
|
@ -53,7 +52,7 @@ Test that css-logic calculates CSS specificity properly
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
createDocument();
|
||||
let cssLogic = new CssLogic(DOMUtils.isInheritedProperty);
|
||||
let cssLogic = new CssLogic(InspectorUtils.isInheritedProperty);
|
||||
|
||||
cssLogic.highlight(document.body);
|
||||
let cssSheet = cssLogic.sheets[0];
|
||||
|
@ -67,8 +66,8 @@ Test that css-logic calculates CSS specificity properly
|
|||
|
||||
let selector = new CssSelector(cssRule, selectorText, i);
|
||||
let expected = getExpectedSpecificity(selectorText);
|
||||
let specificity = DOMUtils.getSpecificity(selector.cssRule,
|
||||
selector.selectorIndex);
|
||||
let specificity = InspectorUtils.getSpecificity(selector.cssRule,
|
||||
selector.selectorIndex);
|
||||
is(specificity, expected,
|
||||
'Selector "' + selectorText + '" has a specificity of ' + expected);
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
|
|||
<script type="application/javascript">
|
||||
"use strict";
|
||||
|
||||
const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
|
||||
const KNOWN_PSEUDOCLASSES = [":hover", ":active", ":focus"];
|
||||
|
||||
window.onload = function () {
|
||||
|
@ -66,7 +63,8 @@ function checkChange(change, expectation) {
|
|||
let enabled = expectation.enabled === undefined ? true : expectation.enabled[i];
|
||||
ok(target.hasPseudoClassLock(pseudo), "Expect lock: " + pseudo);
|
||||
let rawNode = target.rawNode();
|
||||
ok(DOMUtils.hasPseudoClassLock(rawNode, pseudo), "Expect lock in dom: " + pseudo);
|
||||
ok(InspectorUtils.hasPseudoClassLock(rawNode, pseudo),
|
||||
"Expect lock in dom: " + pseudo);
|
||||
|
||||
is(rawNode.matches(pseudo), enabled,
|
||||
`Target should match pseudoclass, '${pseudo}', if enabled (with .matches())`);
|
||||
|
@ -75,7 +73,7 @@ function checkChange(change, expectation) {
|
|||
for (let pseudo of KNOWN_PSEUDOCLASSES) {
|
||||
if (!expectation.pseudos.some(expected => pseudo === expected)) {
|
||||
ok(!target.hasPseudoClassLock(pseudo), "Don't expect lock: " + pseudo);
|
||||
ok(!DOMUtils.hasPseudoClassLock(target.rawNode(), pseudo),
|
||||
ok(!InspectorUtils.hasPseudoClassLock(target.rawNode(), pseudo),
|
||||
"Don't expect lock in dom: " + pseudo);
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +170,7 @@ addTest(function testPseudoClassLock() {
|
|||
// Now shut down the walker and make sure that clears up the remaining lock.
|
||||
return gWalker.release();
|
||||
}).then(() => {
|
||||
ok(!DOMUtils.hasPseudoClassLock(contentNode, ":active"),
|
||||
ok(!InspectorUtils.hasPseudoClassLock(contentNode, ":active"),
|
||||
"Pseudoclass should have been removed during destruction.");
|
||||
teardown();
|
||||
}).then(runNextTest));
|
||||
|
|
|
@ -23,9 +23,9 @@ const { PromiseDebugging, ChromeUtils, HeapSnapshot,
|
|||
|
||||
// Create a single Sandbox to access global properties needed in this module.
|
||||
// Sandbox are memory expensive, so we should create as little as possible.
|
||||
const { CSS, FileReader, indexedDB, URL } =
|
||||
const { CSS, FileReader, indexedDB, InspectorUtils, URL } =
|
||||
Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), {
|
||||
wantGlobalProperties: ["CSS", "FileReader", "indexedDB", "URL"]
|
||||
wantGlobalProperties: ["CSS", "FileReader", "indexedDB", "InspectorUtils", "URL"]
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -179,6 +179,7 @@ exports.modules = {
|
|||
PromiseDebugging,
|
||||
ChromeUtils,
|
||||
HeapSnapshot,
|
||||
InspectorUtils,
|
||||
FileReader,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/* 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";
|
||||
|
||||
/* globals InspectorUtils */
|
||||
|
||||
/*
|
||||
* This is an xpcshell script that runs to generate a static list of CSS properties
|
||||
* as known by the platform. It is run from ./mach_commands.py by running
|
||||
|
@ -11,6 +14,8 @@
|
|||
var {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var {generateCssProperties} = require("devtools/server/actors/css-properties");
|
||||
|
||||
Components.utils.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
// xpcshell can output extra information, so place some delimiter text between
|
||||
// the output of the css properties database.
|
||||
dump("DEVTOOLS_CSS_DB_DELIMITER");
|
||||
|
@ -48,8 +53,5 @@ function cssProperties() {
|
|||
* The list of all CSS Pseudo Elements.
|
||||
*/
|
||||
function pseudoElements() {
|
||||
const {classes: Cc, interfaces: Ci} = Components;
|
||||
const domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
return domUtils.getCSSPseudoElementNames();
|
||||
return InspectorUtils.getCSSPseudoElementNames();
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
"""
|
||||
This script implements the `mach devtools-css-db` command. It runs an xpcshell script
|
||||
that uses inIDOMUtils to query the CSS properties used by the browser. This information
|
||||
is used to generate the properties-db.js file.
|
||||
This script implements the `mach devtools-css-db` command. It runs an xpcshell
|
||||
script that uses InspectorUtils to query the CSS properties used by the browser.
|
||||
This information is used to generate the properties-db.js file.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
const { getRootBindingParent } = require("devtools/shared/layout/utils");
|
||||
const { getTabPrefs } = require("devtools/shared/indentation");
|
||||
const { Ci, Cc } = require("chrome");
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
const MAX_DATA_URL_LENGTH = 40;
|
||||
|
||||
|
@ -38,9 +38,9 @@ const MAX_DATA_URL_LENGTH = 40;
|
|||
|
||||
/**
|
||||
* Provide access to the style information in a page.
|
||||
* CssLogic uses the standard DOM API, and the Gecko inIDOMUtils API to access
|
||||
* styling information in the page, and present this to the user in a way that
|
||||
* helps them understand:
|
||||
* CssLogic uses the standard DOM API, and the Gecko InspectorUtils API to
|
||||
* access styling information in the page, and present this to the user in a way
|
||||
* that helps them understand:
|
||||
* - why their expectations may not have been fulfilled
|
||||
* - how browsers process CSS
|
||||
* @constructor
|
||||
|
@ -511,9 +511,7 @@ exports.getBindingElementAndPseudo = getBindingElementAndPseudo;
|
|||
* normal element.
|
||||
*/
|
||||
function getCSSStyleRules(node) {
|
||||
const DOMUtils =
|
||||
Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
let { bindingElement, pseudo } = getBindingElementAndPseudo(node);
|
||||
return DOMUtils.getCSSStyleRules(bindingElement, pseudo);
|
||||
return InspectorUtils.getCSSStyleRules(bindingElement, pseudo);
|
||||
}
|
||||
exports.getCSSStyleRules = getCSSStyleRules;
|
||||
|
|
|
@ -19,13 +19,12 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
|
||||
const {PSEUDO_ELEMENTS, CSS_PROPERTIES, PREFERENCES} = require("devtools/shared/css/generated/properties-db");
|
||||
const {generateCssProperties} = require("devtools/server/actors/css-properties");
|
||||
const {Preferences} = require("resource://gre/modules/Preferences.jsm");
|
||||
|
||||
Components.utils.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
function run_test() {
|
||||
const propertiesErrorMessage = "If this assertion fails, then the client side CSS " +
|
||||
"properties list in devtools is out of sync with the " +
|
||||
|
@ -34,8 +33,9 @@ function run_test() {
|
|||
"the client side properties.";
|
||||
|
||||
// Check that the platform and client match for pseudo elements.
|
||||
deepEqual(PSEUDO_ELEMENTS, DOMUtils.getCSSPseudoElementNames(), `The pseudo elements ` +
|
||||
`match on the client and platform. ${propertiesErrorMessage}`);
|
||||
deepEqual(PSEUDO_ELEMENTS, InspectorUtils.getCSSPseudoElementNames(),
|
||||
"The pseudo elements match on the client and platform. " +
|
||||
propertiesErrorMessage);
|
||||
|
||||
/**
|
||||
* Check that the platform and client match for the details on their CSS properties.
|
||||
|
|
|
@ -10,14 +10,13 @@
|
|||
"use strict";
|
||||
|
||||
const jsLexer = require("devtools/shared/css/lexer");
|
||||
const domutils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
const InspectorUtils = require("InspectorUtils");
|
||||
|
||||
// An object that acts like a CSSLexer but verifies that the DOM lexer
|
||||
// and the JS lexer do the same thing.
|
||||
function DoubleLexer(input) {
|
||||
info("DoubleLexer input: " + input);
|
||||
this.domLexer = domutils.getCSSLexer(input);
|
||||
this.domLexer = InspectorUtils.getCSSLexer(input);
|
||||
this.jsLexer = jsLexer.getCSSLexer(input);
|
||||
}
|
||||
|
||||
|
|
|
@ -9559,27 +9559,6 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
// If HSTS priming was set by nsMixedContentBlocker::ShouldLoad, and we
|
||||
// would block due to mixed content, go ahead and block here. If we try to
|
||||
// proceed with priming, we will error out later on.
|
||||
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(requestingContext);
|
||||
// When loading toplevel windows, requestingContext can be null. We don't
|
||||
// really care about HSTS in that situation, though; loads in toplevel
|
||||
// windows should all be browser UI.
|
||||
if (docShell) {
|
||||
nsIDocument* document = docShell->GetDocument();
|
||||
NS_ENSURE_TRUE(document, NS_OK);
|
||||
|
||||
HSTSPrimingState state = document->GetHSTSPrimingStateForLocation(aURI);
|
||||
if (state == HSTSPrimingState::eHSTS_PRIMING_BLOCK) {
|
||||
// HSTS Priming currently disabled for InternalLoad, so we need to clear
|
||||
// the location that was added by nsMixedContentBlocker::ShouldLoad
|
||||
// Bug 1269815 will address images loaded via InternalLoad
|
||||
document->ClearHSTSPrimingLocation(aURI);
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principalToInherit = aPrincipalToInherit;
|
||||
|
|
|
@ -1750,8 +1750,32 @@ nsGlobalWindowInner::EnsureClientSource()
|
|||
|
||||
bool newClientSource = false;
|
||||
|
||||
// Get the load info for the document if we performed a load. Be careful
|
||||
// not to look at about:blank or about:srcdoc loads, though. They will have
|
||||
// a channel and loadinfo, but their loadinfo will never be controlled. This
|
||||
// would in turn inadvertantly trigger the logic below to clear the inherited
|
||||
// controller.
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
nsCOMPtr<nsIChannel> channel = mDoc->GetChannel();
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel ? channel->GetLoadInfo() : nullptr;
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
Unused << channel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
bool ignoreLoadInfo = false;
|
||||
|
||||
// Note, this is mostly copied from NS_IsAboutBlank(). Its duplicated
|
||||
// here so we can efficiently check about:srcdoc as well.
|
||||
bool isAbout = false;
|
||||
if (NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)) && isAbout) {
|
||||
nsCString spec = uri->GetSpecOrDefault();
|
||||
ignoreLoadInfo = spec.EqualsLiteral("about:blank") ||
|
||||
spec.EqualsLiteral("about:srcdoc");
|
||||
}
|
||||
|
||||
if (!ignoreLoadInfo) {
|
||||
loadInfo = channel->GetLoadInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// Take the initial client source from the docshell immediately. Even if we
|
||||
// don't end up using it here we should consume it.
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsIScriptGlobalObject.h" // for member (in nsCOMPtr)
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h" // for use in inline functions
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsPIDOMWindow.h" // for use in inline functions
|
||||
#include "nsPropertyTable.h" // for member
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsDataHashtable.h" // for member
|
||||
#include "nsURIHashKey.h" // for member
|
||||
#include "nsTHashtable.h" // for member
|
||||
#include "mozilla/net/ReferrerPolicy.h" // for member
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/UseCounter.h"
|
||||
|
@ -194,13 +194,6 @@ enum DocumentFlavor {
|
|||
DocumentFlavorPlain, // Just a Document
|
||||
};
|
||||
|
||||
// Enum for HSTS priming states
|
||||
enum class HSTSPrimingState {
|
||||
eNO_HSTS_PRIMING = 0, // don't do HSTS Priming
|
||||
eHSTS_PRIMING_ALLOW = 1, // if HSTS priming fails, allow the load to proceed
|
||||
eHSTS_PRIMING_BLOCK = 2 // if HSTS priming fails, block the load
|
||||
};
|
||||
|
||||
// Document states
|
||||
|
||||
// RTL locale: specific to the XUL localedir attribute
|
||||
|
@ -424,34 +417,6 @@ public:
|
|||
mReferrer = aReferrer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a subresource we want to load requires HSTS priming
|
||||
* to be done.
|
||||
*/
|
||||
HSTSPrimingState GetHSTSPrimingStateForLocation(nsIURI* aContentLocation) const
|
||||
{
|
||||
HSTSPrimingState state;
|
||||
if (mHSTSPrimingURIList.Get(aContentLocation, &state)) {
|
||||
return state;
|
||||
}
|
||||
return HSTSPrimingState::eNO_HSTS_PRIMING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a subresource to the HSTS priming list. If this URI is
|
||||
* not in the HSTS cache, it will trigger an HSTS priming request
|
||||
* when we try to load it.
|
||||
*/
|
||||
void AddHSTSPrimingLocation(nsIURI* aContentLocation, HSTSPrimingState aState)
|
||||
{
|
||||
mHSTSPrimingURIList.Put(aContentLocation, aState);
|
||||
}
|
||||
|
||||
void ClearHSTSPrimingLocation(nsIURI* aContentLocation)
|
||||
{
|
||||
mHSTSPrimingURIList.Remove(aContentLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document. Chances are,
|
||||
* you do not want to be using this.
|
||||
|
@ -3339,11 +3304,6 @@ protected:
|
|||
bool mUpgradeInsecureRequests;
|
||||
bool mUpgradeInsecurePreloads;
|
||||
|
||||
// if nsMixedContentBlocker requires sending an HSTS priming request,
|
||||
// temporarily store that in the document so that it can be propogated to the
|
||||
// LoadInfo and eventually the HTTP Channel
|
||||
nsDataHashtable<nsURIHashKey, HSTSPrimingState> mHSTSPrimingURIList;
|
||||
|
||||
mozilla::WeakPtr<nsDocShell> mDocumentContainer;
|
||||
|
||||
NotNull<const Encoding*> mCharacterSet;
|
||||
|
|
|
@ -1253,7 +1253,7 @@ static bool
|
|||
IsSpaceStuffable(const char16_t *s)
|
||||
{
|
||||
if (s[0] == '>' || s[0] == ' ' || s[0] == kNBSP ||
|
||||
nsCRT::strncmp(s, u"From ", 5) == 0)
|
||||
NS_strncmp(s, u"From ", 5) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsGenericDOMDataNode.h"
|
||||
#include "nsTextFrame.h"
|
||||
#include "nsFontFaceList.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/DocumentType.h"
|
||||
#include "mozilla/dom/RangeBinding.h"
|
||||
|
@ -39,6 +38,7 @@
|
|||
#include "nsStyleStruct.h"
|
||||
#include "nsStyleStructInlines.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "mozilla/dom/InspectorFontFace.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -3467,11 +3467,9 @@ nsRange::GetClientRectsAndTexts(
|
|||
mStart.Container(), mStart.Offset(), mEnd.Container(), mEnd.Offset(), true, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRange::GetUsedFontFaces(nsIDOMFontFaceList** aResult)
|
||||
nsresult
|
||||
nsRange::GetUsedFontFaces(nsTArray<nsAutoPtr<InspectorFontFace>>& aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
|
||||
NS_ENSURE_TRUE(mStart.Container(), NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsINode> startContainer = do_QueryInterface(mStart.Container());
|
||||
|
@ -3485,7 +3483,11 @@ nsRange::GetUsedFontFaces(nsIDOMFontFaceList** aResult)
|
|||
// Recheck whether we're still in the document
|
||||
NS_ENSURE_TRUE(mStart.Container()->IsInUncomposedDoc(), NS_ERROR_UNEXPECTED);
|
||||
|
||||
RefPtr<nsFontFaceList> fontFaceList = new nsFontFaceList();
|
||||
// A table to map gfxFontEntry objects to InspectorFontFace objects.
|
||||
// (We hold on to the InspectorFontFaces strongly due to the nsAutoPtrs
|
||||
// in the nsClassHashtable, until we move them out into aResult at the end
|
||||
// of the function.)
|
||||
nsLayoutUtils::UsedFontFaceTable fontFaces;
|
||||
|
||||
RangeSubtreeIterator iter;
|
||||
nsresult rv = iter.Init(this);
|
||||
|
@ -3510,20 +3512,25 @@ nsRange::GetUsedFontFaces(nsIDOMFontFaceList** aResult)
|
|||
int32_t offset = startContainer == endContainer ?
|
||||
mEnd.Offset() : content->GetText()->GetLength();
|
||||
nsLayoutUtils::GetFontFacesForText(frame, mStart.Offset(), offset,
|
||||
true, fontFaceList);
|
||||
true, fontFaces);
|
||||
continue;
|
||||
}
|
||||
if (node == endContainer) {
|
||||
nsLayoutUtils::GetFontFacesForText(frame, 0, mEnd.Offset(),
|
||||
true, fontFaceList);
|
||||
true, fontFaces);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsLayoutUtils::GetFontFacesForFrames(frame, fontFaceList);
|
||||
nsLayoutUtils::GetFontFacesForFrames(frame, fontFaces);
|
||||
}
|
||||
|
||||
// Take ownership of the InspectorFontFaces in the table and move them into
|
||||
// the aResult outparam.
|
||||
for (auto iter = fontFaces.Iter(); !iter.Done(); iter.Next()) {
|
||||
aResult.AppendElement(Move(iter.Data()));
|
||||
}
|
||||
|
||||
fontFaceList.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class DocGroup;
|
|||
class DocumentFragment;
|
||||
class DOMRect;
|
||||
class DOMRectList;
|
||||
class InspectorFontFace;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -280,7 +281,8 @@ public:
|
|||
return parentNode;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
|
||||
nsresult GetUsedFontFaces(
|
||||
nsTArray<nsAutoPtr<mozilla::dom::InspectorFontFace>>& aResult);
|
||||
|
||||
// nsIMutationObserver methods
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
|
||||
|
|
|
@ -194,12 +194,6 @@ function createPolicyTest(policy, optionalEarlierPolicy) {
|
|||
}
|
||||
|
||||
function handleRequest(request, response) {
|
||||
if (request.method == 'HEAD') {
|
||||
// respond to a HEAD request with a 418 so that we can easily distinguish
|
||||
// HSTS priming responses and ignore them
|
||||
response.setStatusLine('1.1', 418, "I'm a teapot");
|
||||
return;
|
||||
}
|
||||
var sharedKey = 'bug704320.sjs';
|
||||
var params = request.queryString.split('&');
|
||||
var action = params[0].split('=')[1];
|
||||
|
|
|
@ -25,9 +25,6 @@ function doXHR(url, onSuccess, onFail) {
|
|||
xhr.onload = function () {
|
||||
if (xhr.status == 200) {
|
||||
onSuccess(xhr);
|
||||
} else if (xhr.status == 418) {
|
||||
// Ignore HSTS priming responses
|
||||
return;
|
||||
} else {
|
||||
onFail(xhr);
|
||||
}
|
||||
|
|
|
@ -517,6 +517,10 @@ DOMInterfaces = {
|
|||
'notflattened': True
|
||||
},
|
||||
|
||||
'InspectorFontFace': {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'IntersectionObserver': {
|
||||
'nativeType': 'mozilla::dom::DOMIntersectionObserver',
|
||||
},
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/dom/Console.h"
|
||||
#include "mozilla/dom/ConsoleInstance.h"
|
||||
#include "mozilla/dom/ConsoleBinding.h"
|
||||
#include "ConsoleCommon.h"
|
||||
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
|
@ -295,24 +296,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
// This class is used to clear any exception at the end of this method.
|
||||
class ClearException
|
||||
{
|
||||
public:
|
||||
explicit ClearException(JSContext* aCx)
|
||||
: mCx(aCx)
|
||||
{
|
||||
}
|
||||
|
||||
~ClearException()
|
||||
{
|
||||
JS_ClearPendingException(mCx);
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext* mCx;
|
||||
};
|
||||
|
||||
class ConsoleRunnable : public WorkerProxyToMainThreadRunnable
|
||||
, public StructuredCloneHolderBase
|
||||
{
|
||||
|
@ -536,7 +519,7 @@ private:
|
|||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mCallData->AssertIsOnOwningThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
JS::Rooted<JSObject*> arguments(aCx,
|
||||
JS_NewArrayObject(aCx, mCallData->mCopiedArguments.Length()));
|
||||
|
@ -623,7 +606,7 @@ private:
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> argumentsValue(aCx);
|
||||
if (!Read(aCx, &argumentsValue)) {
|
||||
|
@ -681,7 +664,7 @@ private:
|
|||
bool
|
||||
PreDispatch(JSContext* aCx) override
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
JS::Rooted<JSObject*> arguments(aCx,
|
||||
JS_NewArrayObject(aCx, mArguments.Length()));
|
||||
|
@ -713,7 +696,7 @@ private:
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
// Now we could have the correct window (if we are not window-less).
|
||||
mClonedData.mParent = aInnerWindow;
|
||||
|
@ -1014,7 +997,7 @@ Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
|||
MethodName aMethodName,
|
||||
const nsAString& aMethodString)
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
Sequence<JS::Value> data;
|
||||
SequenceRooter<JS::Value> rooter(aCx, &data);
|
||||
|
@ -1037,7 +1020,7 @@ Console::TimeStamp(const GlobalObject& aGlobal,
|
|||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
ClearException ce(cx);
|
||||
ConsoleCommon::ClearException ce(cx);
|
||||
|
||||
Sequence<JS::Value> data;
|
||||
SequenceRooter<JS::Value> rooter(cx, &data);
|
||||
|
@ -1113,7 +1096,7 @@ Console::ProfileMethodInternal(JSContext* aCx, MethodName aMethodName,
|
|||
return;
|
||||
}
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
RootedDictionary<ConsoleProfileEvent> event(aCx);
|
||||
event.mAction = aAction;
|
||||
|
@ -1264,7 +1247,7 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
|
|||
|
||||
RefPtr<ConsoleCallData> callData(new ConsoleCallData());
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
if (NS_WARN_IF(!callData->Initialize(aCx, aMethodName, aMethodString,
|
||||
aData, this))) {
|
||||
|
@ -1530,7 +1513,7 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
|||
frame = *aData->mTopStackFrame;
|
||||
}
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
RootedDictionary<ConsoleEvent> event(aCx);
|
||||
|
||||
event.mAddonId = aData->mAddonId;
|
||||
|
@ -2188,7 +2171,7 @@ Console::IncreaseCounter(JSContext* aCx, const Sequence<JS::Value>& aArguments,
|
|||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
MOZ_ASSERT(!aArguments.IsEmpty());
|
||||
|
||||
|
@ -2224,7 +2207,7 @@ JS::Value
|
|||
Console::CreateCounterValue(JSContext* aCx, const nsAString& aCountLabel,
|
||||
uint32_t aCountValue) const
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
if (aCountValue == MAX_PAGE_COUNTERS) {
|
||||
RootedDictionary<ConsoleCounterError> error(aCx);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_ConsoleCommon_h
|
||||
#define mozilla_dom_ConsoleCommon_h
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace ConsoleCommon {
|
||||
|
||||
// This class is used to clear any exception at the end of this method.
|
||||
class MOZ_RAII ClearException
|
||||
{
|
||||
public:
|
||||
explicit ClearException(JSContext* aCx)
|
||||
: mCx(aCx)
|
||||
{
|
||||
}
|
||||
|
||||
~ClearException()
|
||||
{
|
||||
JS_ClearPendingException(mCx);
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext* mCx;
|
||||
};
|
||||
|
||||
} // namespace ConsoleCommon
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_ConsoleCommon_h */
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "mozilla/dom/ConsoleInstance.h"
|
||||
#include "mozilla/dom/ConsoleBinding.h"
|
||||
#include "ConsoleCommon.h"
|
||||
#include "ConsoleUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -45,6 +47,23 @@ PrefToValue(const nsCString& aPref)
|
|||
return static_cast<ConsoleLogLevel>(index);
|
||||
}
|
||||
|
||||
ConsoleUtils::Level
|
||||
WebIDLevelToConsoleUtilsLevel(ConsoleLevel aLevel)
|
||||
{
|
||||
switch (aLevel) {
|
||||
case ConsoleLevel::Log:
|
||||
return ConsoleUtils::eLog;
|
||||
case ConsoleLevel::Warning:
|
||||
return ConsoleUtils::eWarning;
|
||||
case ConsoleLevel::Error:
|
||||
return ConsoleUtils::eError;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ConsoleUtils::eLog;
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
|
||||
ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
|
||||
|
@ -132,7 +151,7 @@ ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel)
|
|||
void
|
||||
ConsoleInstance::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
Sequence<JS::Value> data;
|
||||
SequenceRooter<JS::Value> rooter(aCx, &data);
|
||||
|
@ -184,5 +203,22 @@ ConsoleInstance::Clear(JSContext* aCx)
|
|||
NS_LITERAL_STRING("clear"), data);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::ReportForServiceWorkerScope(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
ConsoleLevel aLevel)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConsoleUtils::ReportForServiceWorkerScope(aScope, aMessage, aFilename,
|
||||
aLineNumber, aColumnNumber,
|
||||
WebIDLevelToConsoleUtilsLevel(aLevel));
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -94,6 +94,14 @@ public:
|
|||
void
|
||||
Clear(JSContext* aCx);
|
||||
|
||||
// For testing only.
|
||||
void ReportForServiceWorkerScope(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
ConsoleLevel aLevel);
|
||||
|
||||
private:
|
||||
~ConsoleInstance();
|
||||
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ConsoleUtils.h"
|
||||
#include "ConsoleCommon.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
StaticRefPtr<ConsoleUtils> gConsoleUtilsService;
|
||||
|
||||
}
|
||||
|
||||
/* static */ ConsoleUtils*
|
||||
ConsoleUtils::GetOrCreate()
|
||||
{
|
||||
if (!gConsoleUtilsService) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
gConsoleUtilsService = new ConsoleUtils();
|
||||
ClearOnShutdown(&gConsoleUtilsService);
|
||||
}
|
||||
|
||||
return gConsoleUtilsService;
|
||||
}
|
||||
|
||||
ConsoleUtils::ConsoleUtils() = default;
|
||||
ConsoleUtils::~ConsoleUtils() = default;
|
||||
|
||||
/* static */ void
|
||||
ConsoleUtils::ReportForServiceWorkerScope(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
Level aLevel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<ConsoleUtils> service = ConsoleUtils::GetOrCreate();
|
||||
if (NS_WARN_IF(!service)) {
|
||||
return;
|
||||
}
|
||||
|
||||
service->ReportForServiceWorkerScopeInternal(aScope, aMessage, aFilename,
|
||||
aLineNumber, aColumnNumber,
|
||||
aLevel);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleUtils::ReportForServiceWorkerScopeInternal(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
Level aLevel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
ConsoleCommon::ClearException ce(cx);
|
||||
JS::Rooted<JSObject*> global(cx, GetOrCreateSandbox(cx));
|
||||
if (NS_WARN_IF(!global)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
|
||||
// We don't need a proxy here.
|
||||
global = js::UncheckedUnwrap(global);
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
||||
RootedDictionary<ConsoleEvent> event(cx);
|
||||
|
||||
event.mID.Construct();
|
||||
event.mID.Value().SetAsString() = aScope;
|
||||
|
||||
event.mInnerID.Construct();
|
||||
event.mInnerID.Value().SetAsString() = NS_LITERAL_STRING("ServiceWorker");
|
||||
|
||||
switch (aLevel) {
|
||||
case eLog:
|
||||
event.mLevel = NS_LITERAL_STRING("log");
|
||||
break;
|
||||
|
||||
case eWarning:
|
||||
event.mLevel = NS_LITERAL_STRING("warn");
|
||||
break;
|
||||
|
||||
case eError:
|
||||
event.mLevel = NS_LITERAL_STRING("error");
|
||||
break;
|
||||
}
|
||||
|
||||
event.mFilename = aFilename;
|
||||
event.mLineNumber = aLineNumber;
|
||||
event.mColumnNumber = aColumnNumber;
|
||||
event.mTimeStamp = JS_Now() / PR_USEC_PER_MSEC;
|
||||
|
||||
JS::Rooted<JS::Value> messageValue(cx);
|
||||
if (!dom::ToJSValue(cx, aMessage, &messageValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.mArguments.Construct();
|
||||
if (!event.mArguments.Value().AppendElement(messageValue, fallible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIConsoleAPIStorage> storage =
|
||||
do_GetService("@mozilla.org/consoleAPI-storage;1");
|
||||
|
||||
if (NS_WARN_IF(!storage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> eventValue(cx);
|
||||
if (!ToJSValue(cx, event, &eventValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a legacy property.
|
||||
JS::Rooted<JSObject*> eventObj(cx, &eventValue.toObject());
|
||||
if (NS_WARN_IF(!JS_DefineProperty(cx, eventObj, "wrappedJSObject", eventObj,
|
||||
JSPROP_ENUMERATE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
storage->RecordEvent(NS_LITERAL_STRING("ServiceWorker"), aScope, eventValue);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ConsoleUtils::GetOrCreateSandbox(JSContext* aCx)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!mSandbox) {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
MOZ_ASSERT(xpc, "This should never be null!");
|
||||
|
||||
RefPtr<NullPrincipal> nullPrincipal = NullPrincipal::Create();
|
||||
|
||||
JS::Rooted<JSObject*> sandbox(aCx);
|
||||
nsresult rv = xpc->CreateSandbox(aCx, nullPrincipal, sandbox.address());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSandbox = new JSObjectHolder(aCx, sandbox);
|
||||
}
|
||||
|
||||
return mSandbox->GetJSObject();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_ConsoleUtils_h
|
||||
#define mozilla_dom_ConsoleUtils_h
|
||||
|
||||
#include "mozilla/JSObjectHolder.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ConsoleUtils final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ConsoleUtils)
|
||||
|
||||
enum Level {
|
||||
eLog,
|
||||
eWarning,
|
||||
eError,
|
||||
};
|
||||
|
||||
// Main-thread only, reports a console message from a ServiceWorker.
|
||||
static void
|
||||
ReportForServiceWorkerScope(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
Level aLevel);
|
||||
|
||||
private:
|
||||
ConsoleUtils();
|
||||
~ConsoleUtils();
|
||||
|
||||
static ConsoleUtils*
|
||||
GetOrCreate();
|
||||
|
||||
JSObject*
|
||||
GetOrCreateSandbox(JSContext* aCx);
|
||||
|
||||
void
|
||||
ReportForServiceWorkerScopeInternal(const nsAString& aScope,
|
||||
const nsAString& aMessage,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
Level aLevel);
|
||||
|
||||
RefPtr<JSObjectHolder> mSandbox;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_ConsoleUtils_h */
|
|
@ -24,12 +24,14 @@ EXPORTS.mozilla += [
|
|||
EXPORTS.mozilla.dom += [
|
||||
'Console.h',
|
||||
'ConsoleInstance.h',
|
||||
'ConsoleUtils.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'Console.cpp',
|
||||
'ConsoleInstance.cpp',
|
||||
'ConsoleReportCollector.cpp',
|
||||
'ConsoleUtils.cpp',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
add_task(async function() {
|
||||
let p = new Promise(resolve => {
|
||||
function consoleListener() {
|
||||
Services.obs.addObserver(this, "console-api-log-event");
|
||||
}
|
||||
|
||||
consoleListener.prototype = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
let obj = aSubject.wrappedJSObject;
|
||||
Assert.ok(obj.arguments[0] === "Hello world!", "Message received!");
|
||||
Assert.ok(obj.ID === "scope", "The ID is the scope");
|
||||
Assert.ok(obj.innerID === "ServiceWorker", "The innerID is ServiceWorker");
|
||||
Assert.ok(obj.filename === "filename", "The filename matches");
|
||||
Assert.ok(obj.lineNumber === 42, "The lineNumber matches");
|
||||
Assert.ok(obj.columnNumber === 24, "The columnNumber matches");
|
||||
Assert.ok(obj.level === "error", "The level is correct");
|
||||
|
||||
Services.obs.removeObserver(this, "console-api-log-event");
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
new consoleListener();
|
||||
});
|
||||
|
||||
let ci = console.createInstance();
|
||||
ci.reportForServiceWorkerScope("scope", "Hello world!", "filename", 42, 24, "error");
|
||||
await p;
|
||||
});
|
|
@ -3,3 +3,4 @@ head =
|
|||
support-files =
|
||||
|
||||
[test_basic.js]
|
||||
[test_reportForServiceWorkerScope.js]
|
||||
|
|
|
@ -150,8 +150,9 @@ public:
|
|||
return (mStates & aEventStates.mStates) == aEventStates.mStates;
|
||||
}
|
||||
|
||||
// We only need that method for inDOMUtils::GetContentState.
|
||||
// If inDOMUtils::GetContentState is removed, this method should be removed.
|
||||
// We only need that method for InspectorUtils::GetContentState.
|
||||
// If InspectorUtils::GetContentState is removed, this method should
|
||||
// be removed.
|
||||
InternalType GetInternalValue() const {
|
||||
return mStates;
|
||||
}
|
||||
|
|
|
@ -38,15 +38,10 @@ let tests = [
|
|||
function setup() {
|
||||
Services.prefs.setBoolPref("browser.send_pings", true);
|
||||
Services.prefs.setIntPref("browser.send_pings.max_per_link", -1);
|
||||
Services.prefs.setBoolPref("security.mixed_content.block_active_content", false);
|
||||
// The server we create can't handle the priming HEAD requests
|
||||
Services.prefs.setBoolPref("security.mixed_content.send_hsts_priming", false);
|
||||
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("browser.send_pings");
|
||||
Services.prefs.clearUserPref("browser.send_pings.max_per_link");
|
||||
Services.prefs.clearUserPref("security.mixed_content.block_active_content");
|
||||
Services.prefs.clearUserPref("security.mixed_content.send_hsts_priming");
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -149,7 +144,7 @@ let tests = [
|
|||
|
||||
// The referrer will be loaded using a secure channel.
|
||||
navigate("https://example.com/chrome/dom/html/test/" +
|
||||
"file_anchor_ping.html?" + "http://localhost:" +
|
||||
"file_anchor_ping.html?" + "http://127.0.0.1:" +
|
||||
server.identity.primaryPort + ping);
|
||||
|
||||
// Wait until the ping has been sent.
|
||||
|
|
|
@ -80,7 +80,3 @@ interface nsIDOMRange;
|
|||
|
||||
// Crypto
|
||||
interface nsIDOMCrypto;
|
||||
|
||||
// Used font face (for inspector)
|
||||
interface nsIDOMFontFace;
|
||||
interface nsIDOMFontFaceList;
|
||||
|
|
|
@ -3566,14 +3566,14 @@ ContentParent::RecvIsSecureURI(const uint32_t& aType,
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming,
|
||||
ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive,
|
||||
const OriginAttributes& aOriginAttributes)
|
||||
{
|
||||
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
|
||||
if (!ourURI) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming, aOriginAttributes);
|
||||
nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aOriginAttributes);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -894,7 +894,6 @@ private:
|
|||
|
||||
virtual mozilla::ipc::IPCResult RecvAccumulateMixedContentHSTS(const URIParams& aURI,
|
||||
const bool& aActive,
|
||||
const bool& aHSTSPriming,
|
||||
const OriginAttributes& aOriginAttributes) override;
|
||||
|
||||
virtual bool DeallocPHalParent(PHalParent*) override;
|
||||
|
|
|
@ -743,7 +743,7 @@ parent:
|
|||
OriginAttributes aOriginAttributes)
|
||||
returns (bool isSecureURI);
|
||||
|
||||
async AccumulateMixedContentHSTS(URIParams aURI, bool aActive, bool aHasHSTSPriming,
|
||||
async AccumulateMixedContentHSTS(URIParams aURI, bool aActive,
|
||||
OriginAttributes aOriginAttributes);
|
||||
|
||||
nested(inside_cpow) async PHal();
|
||||
|
|
|
@ -9,9 +9,12 @@
|
|||
'use strict';
|
||||
const {
|
||||
classes: Cc,
|
||||
interfaces: Ci
|
||||
interfaces: Ci,
|
||||
utils: Cu
|
||||
} = Components;
|
||||
|
||||
Cu.importGlobalProperties(["InspectorUtils"]);
|
||||
|
||||
function ValueExtractor(aConsole, aBundle) {
|
||||
this.console = aConsole;
|
||||
this.domBundle = aBundle;
|
||||
|
@ -48,10 +51,8 @@ ValueExtractor.prototype = {
|
|||
},
|
||||
extractColorValue(spec) {
|
||||
const value = this.extractValue(spec);
|
||||
const DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
|
||||
.getService(Ci.inIDOMUtils);
|
||||
let color;
|
||||
if (DOMUtils.isValidCSSColor(value)) {
|
||||
if (InspectorUtils.isValidCSSColor(value)) {
|
||||
color = value;
|
||||
} else if (value) {
|
||||
this.console.warn(this.domBundle.formatStringFromName("ManifestInvalidCSSColor",
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsMixedContentBlocker.h"
|
||||
#include "nsCDefaultURIFixup.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
|
@ -512,13 +510,6 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
|
|||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
if (nsMixedContentBlocker::sSendHSTSPriming) {
|
||||
rv = nsMixedContentBlocker::MarkLoadInfoForPriming(uri,
|
||||
requestingContext,
|
||||
aLoadInfo);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,40 +58,6 @@ bool nsMixedContentBlocker::sBlockMixedObjectSubrequest = false;
|
|||
// Is mixed display content blocking (images, audio, video, <a ping>) enabled?
|
||||
bool nsMixedContentBlocker::sBlockMixedDisplay = false;
|
||||
|
||||
// Do we move HSTS before mixed-content
|
||||
bool nsMixedContentBlocker::sUseHSTS = false;
|
||||
// Do we send an HSTS priming request
|
||||
bool nsMixedContentBlocker::sSendHSTSPriming = false;
|
||||
// Default HSTS Priming failure timeout to 7 days, in seconds
|
||||
uint32_t nsMixedContentBlocker::sHSTSPrimingCacheTimeout = (60 * 60 * 24 * 7);
|
||||
|
||||
bool
|
||||
IsEligibleForHSTSPriming(nsIURI* aContentLocation) {
|
||||
bool isHttpScheme = false;
|
||||
nsresult rv = aContentLocation->SchemeIs("http", &isHttpScheme);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (!isHttpScheme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t port = -1;
|
||||
rv = aContentLocation->GetPort(&port);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
int32_t defaultPort = NS_GetDefaultPort("https");
|
||||
|
||||
if (port != -1 && port != defaultPort) {
|
||||
// HSTS priming requests are only sent if the port is the default port
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString hostname;
|
||||
rv = aContentLocation->GetHost(hostname);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
PRNetAddr hostAddr;
|
||||
return (PR_StringToNetAddr(hostname.get(), &hostAddr) != PR_SUCCESS);
|
||||
}
|
||||
|
||||
enum MixedContentHSTSState {
|
||||
MCB_HSTS_PASSIVE_NO_HSTS = 0,
|
||||
MCB_HSTS_PASSIVE_WITH_HSTS = 1,
|
||||
|
@ -99,22 +65,6 @@ enum MixedContentHSTSState {
|
|||
MCB_HSTS_ACTIVE_WITH_HSTS = 3
|
||||
};
|
||||
|
||||
// Similar to the existing mixed-content HSTS, except MCB_HSTS_*_NO_HSTS is
|
||||
// broken into two distinct states, indicating whether we plan to send a priming
|
||||
// request or not. If we decided not go send a priming request, it could be
|
||||
// because it is a type we do not support, or because we cached a previous
|
||||
// negative response.
|
||||
enum MixedContentHSTSPrimingState {
|
||||
eMCB_HSTS_PASSIVE_WITH_HSTS = 0,
|
||||
eMCB_HSTS_ACTIVE_WITH_HSTS = 1,
|
||||
eMCB_HSTS_PASSIVE_NO_PRIMING = 2,
|
||||
eMCB_HSTS_PASSIVE_DO_PRIMING = 3,
|
||||
eMCB_HSTS_ACTIVE_NO_PRIMING = 4,
|
||||
eMCB_HSTS_ACTIVE_DO_PRIMING = 5,
|
||||
eMCB_HSTS_PASSIVE_UPGRADE = 6,
|
||||
eMCB_HSTS_ACTIVE_UPGRADE = 7,
|
||||
};
|
||||
|
||||
// Fired at the document that attempted to load mixed content. The UI could
|
||||
// handle this event, for example, by displaying an info bar that offers the
|
||||
// choice to reload the page with mixed content permitted.
|
||||
|
@ -264,18 +214,6 @@ nsMixedContentBlocker::nsMixedContentBlocker()
|
|||
// Cache the pref for mixed display blocking
|
||||
Preferences::AddBoolVarCache(&sBlockMixedDisplay,
|
||||
"security.mixed_content.block_display_content");
|
||||
|
||||
// Cache the pref for HSTS
|
||||
Preferences::AddBoolVarCache(&sUseHSTS,
|
||||
"security.mixed_content.use_hsts");
|
||||
|
||||
// Cache the pref for sending HSTS priming
|
||||
Preferences::AddBoolVarCache(&sSendHSTSPriming,
|
||||
"security.mixed_content.send_hsts_priming");
|
||||
|
||||
// Cache the pref for HSTS priming failure cache time
|
||||
Preferences::AddUintVarCache(&sHSTSPrimingCacheTimeout,
|
||||
"security.mixed_content.hsts_priming_cache_timeout");
|
||||
}
|
||||
|
||||
nsMixedContentBlocker::~nsMixedContentBlocker()
|
||||
|
@ -405,26 +343,6 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
|||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
if (nsMixedContentBlocker::sSendHSTSPriming) {
|
||||
// The LoadInfo passed in is for the original channel, HSTS priming needs to
|
||||
// be set on the new channel, if required. If the redirect changes
|
||||
// http->https, or vice-versa, the need for priming may change.
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo;
|
||||
rv = aNewChannel->GetLoadInfo(getter_AddRefs(newLoadInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (newLoadInfo) {
|
||||
rv = nsMixedContentBlocker::MarkLoadInfoForPriming(newUri,
|
||||
requestingContext,
|
||||
newLoadInfo);
|
||||
if (NS_FAILED(rv)) {
|
||||
decision = REJECT_REQUEST;
|
||||
newLoadInfo->ClearHSTSPriming();
|
||||
}
|
||||
} else {
|
||||
decision = REJECT_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
// If the channel is about to load mixed content, abort the channel
|
||||
if (!NS_CP_ACCEPTED(decision)) {
|
||||
autoCallback.DontCallback();
|
||||
|
@ -946,37 +864,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
|||
originAttributes = aRequestPrincipal->OriginAttributesRef();
|
||||
}
|
||||
|
||||
bool active = (classification == eMixedScript);
|
||||
bool doHSTSPriming = false;
|
||||
if (IsEligibleForHSTSPriming(aContentLocation)) {
|
||||
bool hsts = false;
|
||||
bool cached = false;
|
||||
nsCOMPtr<nsISiteSecurityService> sss =
|
||||
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aContentLocation,
|
||||
0, originAttributes, &cached, nullptr, &hsts);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (hsts && sUseHSTS) {
|
||||
// assume we will be upgraded later
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
(active) ? MixedContentHSTSPrimingState::eMCB_HSTS_ACTIVE_UPGRADE
|
||||
: MixedContentHSTSPrimingState::eMCB_HSTS_PASSIVE_UPGRADE);
|
||||
*aDecision = ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Send a priming request if the result is not already cached and priming
|
||||
// requests are allowed
|
||||
if (!cached && sSendHSTSPriming) {
|
||||
// add this URI as a priming location
|
||||
doHSTSPriming = true;
|
||||
document->AddHSTSPrimingLocation(innerContentLocation,
|
||||
HSTSPrimingState::eHSTS_PRIMING_ALLOW);
|
||||
*aDecision = ACCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we know that the request is mixed content, and the only
|
||||
// question is whether we block it. Record telemetry at this point as to
|
||||
|
@ -990,9 +877,10 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
|||
//
|
||||
// We do not count requests aHadInsecureImageRedirect=true, since these are
|
||||
// just an artifact of the image caching system.
|
||||
bool active = (classification == eMixedScript);
|
||||
if (!aHadInsecureImageRedirect) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming,
|
||||
AccumulateMixedContentHSTS(innerContentLocation, active,
|
||||
originAttributes);
|
||||
} else {
|
||||
// Ask the parent process to do the same call
|
||||
|
@ -1000,7 +888,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
|||
if (cc) {
|
||||
mozilla::ipc::URIParams uri;
|
||||
SerializeURI(innerContentLocation, uri);
|
||||
cc->SendAccumulateMixedContentHSTS(uri, active, doHSTSPriming,
|
||||
cc->SendAccumulateMixedContentHSTS(uri, active,
|
||||
originAttributes);
|
||||
}
|
||||
}
|
||||
|
@ -1044,13 +932,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (doHSTSPriming) {
|
||||
document->AddHSTSPrimingLocation(innerContentLocation,
|
||||
HSTSPrimingState::eHSTS_PRIMING_BLOCK);
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
} else {
|
||||
*aDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
}
|
||||
*aDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked);
|
||||
if (!rootDoc->GetHasMixedDisplayContentBlocked() && NS_SUCCEEDED(stateRV)) {
|
||||
rootDoc->SetHasMixedDisplayContentBlocked(true);
|
||||
|
@ -1096,13 +978,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
|||
}
|
||||
} else {
|
||||
//User has not overriden the pref by Disabling protection. Reject the request and update the security state.
|
||||
if (doHSTSPriming) {
|
||||
document->AddHSTSPrimingLocation(innerContentLocation,
|
||||
HSTSPrimingState::eHSTS_PRIMING_BLOCK);
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
} else {
|
||||
*aDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
}
|
||||
*aDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked);
|
||||
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
|
||||
if (rootDoc->GetHasMixedActiveContentBlocked()) {
|
||||
|
@ -1164,8 +1040,7 @@ nsMixedContentBlocker::ShouldProcess(uint32_t aContentType,
|
|||
// content (regardless of whether it was actually blocked)
|
||||
void
|
||||
nsMixedContentBlocker::AccumulateMixedContentHSTS(
|
||||
nsIURI* aURI, bool aActive, bool aHasHSTSPriming,
|
||||
const OriginAttributes& aOriginAttributes)
|
||||
nsIURI* aURI, bool aActive, const OriginAttributes& aOriginAttributes)
|
||||
{
|
||||
// This method must only be called in the parent, because
|
||||
// nsSiteSecurityService is only available in the parent
|
||||
|
@ -1193,101 +1068,19 @@ nsMixedContentBlocker::AccumulateMixedContentHSTS(
|
|||
if (!hsts) {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
|
||||
MCB_HSTS_PASSIVE_NO_HSTS);
|
||||
if (aHasHSTSPriming) {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_PASSIVE_DO_PRIMING);
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_PASSIVE_NO_PRIMING);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
|
||||
MCB_HSTS_PASSIVE_WITH_HSTS);
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_PASSIVE_WITH_HSTS);
|
||||
}
|
||||
} else {
|
||||
if (!hsts) {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
|
||||
MCB_HSTS_ACTIVE_NO_HSTS);
|
||||
if (aHasHSTSPriming) {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_ACTIVE_DO_PRIMING);
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_ACTIVE_NO_PRIMING);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
|
||||
MCB_HSTS_ACTIVE_WITH_HSTS);
|
||||
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING_2,
|
||||
eMCB_HSTS_ACTIVE_WITH_HSTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
nsresult
|
||||
nsMixedContentBlocker::MarkLoadInfoForPriming(nsIURI* aURI,
|
||||
nsISupports* aRequestingContext,
|
||||
nsILoadInfo* aLoadInfo)
|
||||
{
|
||||
nsresult rv;
|
||||
bool sendPriming = false;
|
||||
bool mixedContentWouldBlock = false;
|
||||
rv = GetHSTSPrimingFromRequestingContext(aURI,
|
||||
aRequestingContext,
|
||||
&sendPriming,
|
||||
&mixedContentWouldBlock);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (sendPriming) {
|
||||
aLoadInfo->SetHSTSPriming(mixedContentWouldBlock);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//static
|
||||
nsresult
|
||||
nsMixedContentBlocker::GetHSTSPrimingFromRequestingContext(nsIURI* aURI,
|
||||
nsISupports* aRequestingContext,
|
||||
bool* aSendPrimingRequest,
|
||||
bool* aMixedContentWouldBlock)
|
||||
{
|
||||
*aSendPrimingRequest = false;
|
||||
*aMixedContentWouldBlock = false;
|
||||
// If we marked for priming, we used the innermost URI, so get that
|
||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||
if (!innerURI) {
|
||||
NS_ERROR("Can't get innerURI from aContentLocation");
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
bool isHttp = false;
|
||||
innerURI->SchemeIs("http", &isHttp);
|
||||
if (!isHttp) {
|
||||
// there is nothign to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the DocShell was marked for HSTS priming, propagate that to the LoadInfo
|
||||
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
|
||||
if (!docShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> document = docShell->GetDocument();
|
||||
if (!document) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
HSTSPrimingState status = document->GetHSTSPrimingStateForLocation(innerURI);
|
||||
if (status != HSTSPrimingState::eNO_HSTS_PRIMING) {
|
||||
*aSendPrimingRequest = (status != HSTSPrimingState::eNO_HSTS_PRIMING);
|
||||
*aMixedContentWouldBlock = (status == HSTSPrimingState::eHSTS_PRIMING_BLOCK);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -69,45 +69,11 @@ public:
|
|||
int16_t* aDecision);
|
||||
static void AccumulateMixedContentHSTS(nsIURI* aURI,
|
||||
bool aActive,
|
||||
bool aHasHSTSPriming,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
/* If the document associated with aRequestingContext requires priming for
|
||||
* aURI, propagate that to the LoadInfo so the HttpChannel will find out about
|
||||
* it.
|
||||
*
|
||||
* @param aURI The URI associated with the load
|
||||
* @param aRequestingContext the requesting context passed to ShouldLoad
|
||||
* @param aLoadInfo the LoadInfo for the load
|
||||
*/
|
||||
static nsresult MarkLoadInfoForPriming(nsIURI* aURI,
|
||||
nsISupports* aRequestingContext,
|
||||
nsILoadInfo* aLoadInfo);
|
||||
|
||||
/* Given a context, return whether HSTS was marked on the document associated
|
||||
* with the load for the given URI. This is used by MarkLoadInfoForPriming and
|
||||
* directly by the image loader to determine whether to allow a load to occur
|
||||
* from the cache.
|
||||
*
|
||||
* @param aURI The URI associated with the load
|
||||
* @param aRequestingContext the requesting context passed to ShouldLoad
|
||||
* @param aSendPrimingRequest out true if priming is required on the channel
|
||||
* @param aMixedContentWouldBlock out true if mixed content would block
|
||||
*/
|
||||
static nsresult GetHSTSPrimingFromRequestingContext(nsIURI* aURI,
|
||||
nsISupports* aRequestingContext,
|
||||
bool* aSendPrimingRequest,
|
||||
bool* aMixedContentWouldBlock);
|
||||
|
||||
|
||||
static bool sBlockMixedScript;
|
||||
static bool sBlockMixedObjectSubrequest;
|
||||
static bool sBlockMixedDisplay;
|
||||
// Do we move HSTS before mixed-content
|
||||
static bool sUseHSTS;
|
||||
// Do we send an HSTS priming request
|
||||
static bool sSendHSTSPriming;
|
||||
// Default HSTS Priming failure timeout in seconds
|
||||
static uint32_t sHSTSPrimingCacheTimeout;
|
||||
};
|
||||
|
||||
#endif /* nsMixedContentBlocker_h___ */
|
||||
|
|
|
@ -116,8 +116,6 @@ SimpleTest.waitForExplicitFinish();
|
|||
SpecialPowers.pushPrefEnv({
|
||||
'set': [['security.mixed_content.block_active_content', false],
|
||||
['security.mixed_content.block_display_content', false],
|
||||
['security.mixed_content.send_hsts_priming', false],
|
||||
['security.mixed_content.use_hsts', false],
|
||||
]
|
||||
},
|
||||
function() {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
[DEFAULT]
|
||||
skip-if = true # Bug 1425968 - Depends on an expiring Telemetry probe and feature is being removed
|
||||
support-files =
|
||||
head.js
|
||||
file_priming-top.html
|
||||
file_testserver.sjs
|
||||
file_1x1.png
|
||||
file_priming.js
|
||||
file_stylesheet.css
|
||||
|
||||
[browser_hsts-priming_allow_active.js]
|
||||
[browser_hsts-priming_block_active.js]
|
||||
[browser_hsts-priming_hsts_after_mixed.js]
|
||||
skip-if = os == "linux" # Bug 1311239
|
||||
[browser_hsts-priming_allow_display.js]
|
||||
[browser_hsts-priming_block_display.js]
|
||||
[browser_hsts-priming_block_active_css.js]
|
||||
[browser_hsts-priming_block_active_with_redir_same.js]
|
||||
[browser_hsts-priming_no-duplicates.js]
|
||||
[browser_hsts-priming_cache-timeout.js]
|
||||
[browser_hsts-priming_timeout.js]
|
||||
[browser_hsts-priming_no-non-standard-ports.js]
|
||||
[browser_hsts-priming_no-ip-address.js]
|
||||
[browser_hsts-priming_include-subdomains.js]
|
||||
skip-if = os == "linux" # Bug 1376238
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when active
|
||||
* content is allowed.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "allow_active";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when display
|
||||
* content is allowed.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "allow_display";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when active
|
||||
* content is blocked.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_active";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when active
|
||||
* content is blocked for css.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_active_css";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when active
|
||||
* content is blocked and redirect to the same host should still upgrade.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_active_with_redir_same";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when display
|
||||
* content is blocked.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_display";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Test that the network.hsts_priming.cache_timeout preferene causes the cache
|
||||
* to timeout
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 2,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 4,
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_display";
|
||||
|
||||
SetupPrefTestEnvironment(which, [["security.mixed_content.hsts_priming_cache_timeout", 1]]);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
await execute_test("no-ssl", test_settings[which].mimetype);
|
||||
|
||||
let pre_promise = performance.now();
|
||||
|
||||
while ((performance.now() - pre_promise) < 1000) {
|
||||
await new Promise(function (resolve) {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
// clear the fact that we saw a priming request
|
||||
test_settings[which].priming = {};
|
||||
|
||||
await execute_test("no-ssl", test_settings[which].mimetype);
|
||||
is(test_settings[which].priming["no-ssl"], true,
|
||||
"Correctly send a priming request after expiration.");
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Check that HSTS priming occurs correctly with mixed content when the
|
||||
* mixed-content blocks before HSTS.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 6,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,0,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Services.obs.addObserver(Observer, "console-api-log-event");
|
||||
Services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "hsts_after_mixed";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,55 +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/. */
|
||||
|
||||
/*
|
||||
* Description of the test:
|
||||
* If the top-level domain sends the STS header but does not have
|
||||
* includeSubdomains, HSTS priming requests should still be sent to
|
||||
* subdomains.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 2,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 4,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
// add the top-level server
|
||||
test_servers['top-level'] = {
|
||||
host: 'example.com',
|
||||
response: true,
|
||||
id: 'top-level',
|
||||
};
|
||||
test_settings.block_active.result['top-level'] = 'secure';
|
||||
|
||||
let which = "block_active";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
await execute_test("top-level", test_settings[which].mimetype);
|
||||
|
||||
await execute_test("prime-hsts", test_settings[which].mimetype);
|
||||
|
||||
ok("prime-hsts" in test_settings[which].priming,
|
||||
"HSTS priming on a subdomain when top-level does not includeSubDomains");
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Only one request should be sent per host, even if we run the test more
|
||||
* than once.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 8,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "block_display";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
// run the tests twice to validate the cache is being used
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* If the top-level domain sends the STS header but does not have
|
||||
* includeSubdomains, HSTS priming requests should still be sent to
|
||||
* subdomains.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 0,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 1,
|
||||
},
|
||||
"keyed-histograms": {
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
// add the top-level server
|
||||
test_servers['localhost-ip'] = {
|
||||
host: '127.0.0.2',
|
||||
response: true,
|
||||
id: 'localhost-ip',
|
||||
};
|
||||
test_settings.block_active.result['localhost-ip'] = 'blocked';
|
||||
|
||||
let which = "block_active";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
await execute_test("localhost-ip", test_settings[which].mimetype);
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* If the top-level domain sends the STS header but does not have
|
||||
* includeSubdomains, HSTS priming requests should still be sent to
|
||||
* subdomains.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 1,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 3,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,1,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
// add the top-level server
|
||||
test_servers['non-standard-port'] = {
|
||||
host: 'test1.example.com:1234',
|
||||
response: true,
|
||||
id: 'non-standard-port',
|
||||
};
|
||||
test_settings.block_active.result['non-standard-port'] = 'blocked';
|
||||
|
||||
let which = "block_active";
|
||||
|
||||
SetupPrefTestEnvironment(which);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
await execute_test("non-standard-port", test_settings[which].mimetype);
|
||||
|
||||
await execute_test("prime-hsts", test_settings[which].mimetype);
|
||||
|
||||
ok("prime-hsts" in test_settings[which_test].priming, "Sent priming request on standard port after non-standard was not primed");
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Description of the test:
|
||||
* Only one request should be sent per host, even if we run the test more
|
||||
* than once.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 3,
|
||||
"MIXED_CONTENT_HSTS_PRIMING_REQUESTS": 3,
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"failure": 3,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
//jscs:disable
|
||||
add_task(async function() {
|
||||
//jscs:enable
|
||||
Observer.add_observers(Services);
|
||||
registerCleanupFunction(do_cleanup);
|
||||
|
||||
let which = "timeout";
|
||||
|
||||
SetupPrefTestEnvironment(which, [["security.mixed_content.hsts_priming_request_timeout",
|
||||
1000]]);
|
||||
clear_hists(expected_telemetry);
|
||||
|
||||
for (let server of Object.keys(test_servers)) {
|
||||
await execute_test(server, test_settings[which].mimetype);
|
||||
}
|
||||
|
||||
test_telemetry(expected_telemetry);
|
||||
|
||||
SpecialPowers.popPrefEnv();
|
||||
});
|
Двоичные данные
dom/security/test/hsts/file_1x1.png
Двоичные данные
dom/security/test/hsts/file_1x1.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 17 KiB |
|
@ -1,89 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1246540</title>
|
||||
<meta http-equiv='content-type' content="text/html;charset=utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Description of the test:
|
||||
* Attempt to load an insecure resource. If the resource responds to HSTS
|
||||
* priming with an STS header, the load should continue securely.
|
||||
* If it does not, the load should continue be blocked or continue insecurely.
|
||||
*/
|
||||
|
||||
function parse_query_string() {
|
||||
var q = {};
|
||||
document.location.search.substr(1).
|
||||
split('&').forEach(function (item, idx, ar) {
|
||||
let [k, v] = item.split('=');
|
||||
q[k] = unescape(v);
|
||||
});
|
||||
return q;
|
||||
}
|
||||
|
||||
var args = parse_query_string();
|
||||
|
||||
var subresources = {
|
||||
css: { mimetype: 'text/css', file: 'file_stylesheet.css' },
|
||||
img: { mimetype: 'image/png', file: 'file_1x1.png' },
|
||||
script: { mimetype: 'text/javascript', file: 'file_priming.js' },
|
||||
};
|
||||
|
||||
function handler(ev) {
|
||||
console.log("HSTS_PRIMING: Blocked "+args.id);
|
||||
let elem = document.getElementById(args.id);
|
||||
elem.parentElement.removeChild(elem);
|
||||
}
|
||||
|
||||
function loadCss(src) {
|
||||
let head = document.getElementsByTagName("head")[0];
|
||||
let link = document.createElement("link");
|
||||
link.setAttribute("rel", "stylesheet");
|
||||
link.setAttribute("id", args.id);
|
||||
link.setAttribute("type", subresources[args.type].mimetype);
|
||||
link.setAttribute("href", src);
|
||||
link.onerror = handler;
|
||||
head.appendChild(link);
|
||||
}
|
||||
|
||||
function loadResource(src) {
|
||||
let content = document.getElementById("content");
|
||||
let testElem = document.createElement(args.type);
|
||||
testElem.setAttribute("id", args.id);
|
||||
testElem.setAttribute("charset", "UTF-8");
|
||||
testElem.onerror = handler;
|
||||
content.appendChild(testElem);
|
||||
testElem.src = src;
|
||||
}
|
||||
|
||||
function loadTest() {
|
||||
let subresource = subresources[args.type];
|
||||
|
||||
let src = "http://"
|
||||
+ args.host
|
||||
+ "/browser/dom/security/test/hsts/file_testserver.sjs"
|
||||
+ "?file=" +escape("browser/dom/security/test/hsts/" + subresource.file)
|
||||
+ "&primer=" + escape(args.id)
|
||||
+ "&mimetype=" + escape(subresource.mimetype)
|
||||
+ "&timeout=" + escape(args.timeout)
|
||||
;
|
||||
if (args.type == 'css') {
|
||||
loadCss(src);
|
||||
return;
|
||||
}
|
||||
|
||||
loadResource(src);
|
||||
}
|
||||
|
||||
// start running the tests
|
||||
loadTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +0,0 @@
|
|||
function completed() {
|
||||
return;
|
||||
}
|
||||
completed();
|
|
@ -1 +0,0 @@
|
|||
body {}
|
|
@ -1,84 +0,0 @@
|
|||
// SJS file for HSTS mochitests
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Components.utils.importGlobalProperties(["URLSearchParams"]);
|
||||
|
||||
function loadFromFile(path) {
|
||||
// Load the HTML to return in the response from file.
|
||||
// Since it's relative to the cwd of the test runner, we start there and
|
||||
// append to get to the actual path of the file.
|
||||
var testFile =
|
||||
Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsIFile);
|
||||
var dirs = path.split("/");
|
||||
for (var i = 0; i < dirs.length; i++) {
|
||||
testFile.append(dirs[i]);
|
||||
}
|
||||
var testFileStream =
|
||||
Components.classes["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
testFileStream.init(testFile, -1, 0, 0);
|
||||
var test = NetUtil.readInputStreamToString(testFileStream, testFileStream.available());
|
||||
return test;
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
const query = new URLSearchParams(request.queryString);
|
||||
|
||||
var timeout = parseInt(query.get('timeout'));
|
||||
response.processAsync();
|
||||
|
||||
timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function()
|
||||
{
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
redir = query.get('redir');
|
||||
if (redir == 'same') {
|
||||
query.delete("redir");
|
||||
response.setStatus(302);
|
||||
let newURI = request.uri;
|
||||
newURI.queryString = query.serialize();
|
||||
response.setHeader("Location", newURI.spec)
|
||||
response.write('xyzzy');
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we have a priming header, check for required behavior
|
||||
// and set header appropriately
|
||||
if (request.hasHeader('Upgrade-Insecure-Requests')) {
|
||||
var expected = query.get('primer');
|
||||
if (expected == 'prime-hsts' || expected == 'top-level') {
|
||||
// set it for 5 minutes
|
||||
response.setHeader("Strict-Transport-Security", "max-age="+(60*5), false);
|
||||
} else if (expected == 'reject-upgrade') {
|
||||
response.setHeader("Strict-Transport-Security", "max-age=0", false);
|
||||
}
|
||||
response.write('xyzzy');
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var file = query.get('file');
|
||||
if (file) {
|
||||
var mimetype = unescape(query.get('mimetype'));
|
||||
response.setHeader("Content-Type", mimetype, false);
|
||||
let contents = loadFromFile(unescape(file));
|
||||
response.write(contents);
|
||||
response.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "application/json", false);
|
||||
response.write('{}');
|
||||
response.finish();
|
||||
}, timeout, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
|
@ -1,543 +0,0 @@
|
|||
/*
|
||||
* Description of the tests:
|
||||
* Check that HSTS priming occurs correctly with mixed content
|
||||
*
|
||||
* This test uses three hostnames, each of which treats an HSTS priming
|
||||
* request differently.
|
||||
* * no-ssl never returns an ssl response
|
||||
* * reject-upgrade returns an ssl response, but with no STS header
|
||||
* * prime-hsts returns an ssl response with the appropriate STS header
|
||||
*
|
||||
* For each server, test that it response appropriately when the we allow
|
||||
* or block active or display content, as well as when we send an hsts priming
|
||||
* request, but do not change the order of mixed-content and HSTS.
|
||||
*
|
||||
* Test use http-on-examine-response, so must be run in browser context.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
var TOP_URI = "https://example.com/browser/dom/security/test/hsts/file_priming-top.html";
|
||||
|
||||
var test_servers = {
|
||||
// a test server that does not support TLS
|
||||
'no-ssl': {
|
||||
host: 'example.co.jp',
|
||||
response: false,
|
||||
id: 'no-ssl',
|
||||
},
|
||||
// a test server which does not support STS upgrade
|
||||
'reject-upgrade': {
|
||||
host: 'example.org',
|
||||
response: true,
|
||||
id: 'reject-upgrade',
|
||||
},
|
||||
// a test server when sends an STS header when priming
|
||||
'prime-hsts': {
|
||||
host: 'test1.example.com',
|
||||
response: true,
|
||||
id: 'prime-hsts'
|
||||
},
|
||||
};
|
||||
|
||||
var test_settings = {
|
||||
// mixed active content is allowed, priming will upgrade
|
||||
allow_active: {
|
||||
block_active: false,
|
||||
block_display: false,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'script',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'insecure',
|
||||
'reject-upgrade': 'insecure',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// mixed active content is blocked, priming will upgrade
|
||||
block_active: {
|
||||
block_active: true,
|
||||
block_display: false,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'script',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// keep the original order of mixed-content and HSTS, but send
|
||||
// priming requests
|
||||
hsts_after_mixed: {
|
||||
block_active: true,
|
||||
block_display: false,
|
||||
use_hsts: false,
|
||||
send_hsts_priming: true,
|
||||
type: 'script',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'blocked',
|
||||
},
|
||||
},
|
||||
// mixed display content is allowed, priming will upgrade
|
||||
allow_display: {
|
||||
block_active: true,
|
||||
block_display: false,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'img',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'insecure',
|
||||
'reject-upgrade': 'insecure',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// mixed display content is blocked, priming will upgrade
|
||||
block_display: {
|
||||
block_active: true,
|
||||
block_display: true,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'img',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// mixed active content is blocked, priming will upgrade (css)
|
||||
block_active_css: {
|
||||
block_active: true,
|
||||
block_display: true,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'css',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// mixed active content is blocked, priming will upgrade
|
||||
// redirect to the same host
|
||||
block_active_with_redir_same: {
|
||||
block_active: true,
|
||||
block_display: false,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'script',
|
||||
redir: 'same',
|
||||
timeout: 0,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'secure',
|
||||
},
|
||||
},
|
||||
// mixed active content is blocked, priming will upgrade
|
||||
// redirect to the same host
|
||||
timeout: {
|
||||
block_active: true,
|
||||
block_display: true,
|
||||
use_hsts: true,
|
||||
send_hsts_priming: true,
|
||||
type: 'script',
|
||||
timeout: 100000,
|
||||
result: {
|
||||
'no-ssl': 'blocked',
|
||||
'reject-upgrade': 'blocked',
|
||||
'prime-hsts': 'blocked',
|
||||
},
|
||||
},
|
||||
}
|
||||
// track which test we are on
|
||||
var which_test = "";
|
||||
|
||||
/**
|
||||
* A stream listener that just forwards all calls
|
||||
*/
|
||||
var StreamListener = function(subject) {
|
||||
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
let traceable = subject.QueryInterface(Ci.nsITraceableChannel);
|
||||
|
||||
this.uri = channel.URI.asciiSpec;
|
||||
this.listener = traceable.setNewListener(this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Next three methods are part of `nsIStreamListener` interface and are
|
||||
// invoked by `nsIInputStreamPump.asyncRead`.
|
||||
StreamListener.prototype.onDataAvailable = function(request, context, input, offset, count) {
|
||||
if (request.status == Cr.NS_ERROR_ABORT) {
|
||||
this.listener = null;
|
||||
return Cr.NS_SUCCESS;
|
||||
}
|
||||
let listener = this.listener;
|
||||
if (listener) {
|
||||
try {
|
||||
let rv = listener.onDataAvailable(request, context, input, offset, count);
|
||||
if (rv != Cr.NS_ERROR_ABORT) {
|
||||
// If the channel gets canceled, we sometimes get NS_ERROR_ABORT here.
|
||||
// Anything else is an error.
|
||||
return rv;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != Cr.NS_ERROR_ABORT) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Cr.NS_SUCCESS;
|
||||
};
|
||||
|
||||
// Next two methods implement `nsIRequestObserver` interface and are invoked
|
||||
// by `nsIInputStreamPump.asyncRead`.
|
||||
StreamListener.prototype.onStartRequest = function(request, context) {
|
||||
if (request.status == Cr.NS_ERROR_ABORT) {
|
||||
this.listener = null;
|
||||
return Cr.NS_SUCCESS;
|
||||
}
|
||||
let listener = this.listener;
|
||||
if (listener) {
|
||||
try {
|
||||
let rv = listener.onStartRequest(request, context);
|
||||
if (rv != Cr.NS_ERROR_ABORT) {
|
||||
// If the channel gets canceled, we sometimes get NS_ERROR_ABORT here.
|
||||
// Anything else is an error.
|
||||
return rv;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != Cr.NS_ERROR_ABORT) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Cr.NS_SUCCESS;
|
||||
};
|
||||
|
||||
// Called to signify the end of an asynchronous request. We only care to
|
||||
// discover errors.
|
||||
StreamListener.prototype.onStopRequest = function(request, context, status) {
|
||||
if (status == Cr.NS_ERROR_ABORT) {
|
||||
this.listener = null;
|
||||
return Cr.NS_SUCCESS;
|
||||
}
|
||||
let listener = this.listener;
|
||||
if (listener) {
|
||||
try {
|
||||
let rv = listener.onStopRequest(request, context, status);
|
||||
if (rv != Cr.NS_ERROR_ABORT) {
|
||||
// If the channel gets canceled, we sometimes get NS_ERROR_ABORT here.
|
||||
// Anything else is an error.
|
||||
return rv;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e != Cr.NS_ERROR_ABORT) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Cr.NS_SUCCESS;
|
||||
};
|
||||
|
||||
var Observer = {
|
||||
listeners: {},
|
||||
observe: function (subject, topic, data) {
|
||||
switch (topic) {
|
||||
case 'console-api-log-event':
|
||||
return Observer.console_api_log_event(subject, topic, data);
|
||||
case 'http-on-examine-response':
|
||||
return Observer.http_on_examine_response(subject, topic, data);
|
||||
case 'http-on-modify-request':
|
||||
return Observer.http_on_modify_request(subject, topic, data);
|
||||
}
|
||||
throw "Can't handle topic "+topic;
|
||||
},
|
||||
add_observers: function (services, include_on_modify = false) {
|
||||
services.obs.addObserver(Observer, "console-api-log-event");
|
||||
services.obs.addObserver(Observer, "http-on-examine-response");
|
||||
services.obs.addObserver(Observer, "http-on-modify-request");
|
||||
},
|
||||
cleanup: function () {
|
||||
this.listeners = {};
|
||||
},
|
||||
// When a load is blocked which results in an error event within a page, the
|
||||
// test logs to the console.
|
||||
console_api_log_event: function (subject, topic, data) {
|
||||
var message = subject.wrappedJSObject.arguments[0];
|
||||
// when we are blocked, this will match the message we sent to the console,
|
||||
// ignore everything else.
|
||||
var re = RegExp(/^HSTS_PRIMING: Blocked ([-\w]+).*$/);
|
||||
if (!re.test(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let id = message.replace(re, '$1');
|
||||
let curTest =test_servers[id];
|
||||
|
||||
if (!curTest) {
|
||||
ok(false, "HSTS priming got a console message blocked, "+
|
||||
"but doesn't match expectations "+id+" (msg="+message);
|
||||
return;
|
||||
}
|
||||
|
||||
is("blocked", test_settings[which_test].result[curTest.id], "HSTS priming "+
|
||||
which_test+":"+curTest.id+" expected "+
|
||||
test_settings[which_test].result[curTest.id]+", got blocked");
|
||||
test_settings[which_test].finished[curTest.id] = "blocked";
|
||||
},
|
||||
get_current_test: function(uri) {
|
||||
for (let item in test_servers) {
|
||||
let re = RegExp('https?://'+test_servers[item].host+'.*\/browser/dom/security/test/hsts/file_testserver.sjs');
|
||||
if (re.test(uri)) {
|
||||
return test_servers[item];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
http_on_modify_request: function (subject, topic, data) {
|
||||
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
let uri = channel.URI.asciiSpec;
|
||||
|
||||
let curTest = this.get_current_test(channel.URI.asciiSpec);
|
||||
|
||||
if (!curTest) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(uri in this.listeners)) {
|
||||
// Add an nsIStreamListener to ensure that the listener is not NULL
|
||||
this.listeners[uri] = new StreamListener(subject);
|
||||
}
|
||||
|
||||
if (channel.requestMethod != 'HEAD') {
|
||||
return;
|
||||
}
|
||||
if (typeof ok === 'undefined') {
|
||||
// we are in the wrong thread and ok and is not available
|
||||
return;
|
||||
}
|
||||
ok(!(curTest.id in test_settings[which_test].priming), "Already saw a priming request for " + curTest.id);
|
||||
test_settings[which_test].priming[curTest.id] = true;
|
||||
},
|
||||
// When we see a response come back, peek at the response and test it is secure
|
||||
// or insecure as needed. Addtionally, watch the response for priming requests.
|
||||
http_on_examine_response: function (subject, topic, data) {
|
||||
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
let curTest = this.get_current_test(channel.URI.asciiSpec);
|
||||
let uri = channel.URI.asciiSpec;
|
||||
|
||||
if (!curTest) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result = (channel.URI.asciiSpec.startsWith('https:')) ? "secure" : "insecure";
|
||||
|
||||
// This is a priming request, go ahead and validate we were supposed to see
|
||||
// a response from the server
|
||||
if (channel.requestMethod == 'HEAD') {
|
||||
is(true, curTest.response, "HSTS priming response found " + curTest.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the response to our query, make sure it matches
|
||||
is(result, test_settings[which_test].result[curTest.id],
|
||||
"HSTS priming result " + which_test + ":" + curTest.id);
|
||||
test_settings[which_test].finished[curTest.id] = result;
|
||||
if (this.listeners[uri]) {
|
||||
this.listeners[uri] = undefined;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// opens `uri' in a new tab and focuses it.
|
||||
// returns the newly opened tab
|
||||
function openTab(uri) {
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, uri);
|
||||
|
||||
// select tab and make sure its browser is focused
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.ownerGlobal.focus();
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
function clear_sts_data() {
|
||||
for (let test in test_servers) {
|
||||
SpecialPowers.cleanUpSTSData('http://'+test_servers[test].host);
|
||||
}
|
||||
}
|
||||
|
||||
var oldCanRecord = Services.telemetry.canRecordExtended;
|
||||
|
||||
function do_cleanup() {
|
||||
clear_sts_data();
|
||||
|
||||
Services.obs.removeObserver(Observer, "console-api-log-event");
|
||||
Services.obs.removeObserver(Observer, "http-on-examine-response");
|
||||
|
||||
Services.telemetry.canRecordExtended = oldCanRecord;
|
||||
|
||||
Observer.cleanup();
|
||||
}
|
||||
|
||||
function SetupPrefTestEnvironment(which, additional_prefs) {
|
||||
which_test = which;
|
||||
clear_sts_data();
|
||||
|
||||
var settings = test_settings[which];
|
||||
// priming counts how many priming requests we saw
|
||||
settings.priming = {};
|
||||
// priming counts how many tests were finished
|
||||
settings.finished= {};
|
||||
|
||||
var prefs = [["security.mixed_content.block_active_content",
|
||||
settings.block_active],
|
||||
["security.mixed_content.block_display_content",
|
||||
settings.block_display],
|
||||
["security.mixed_content.use_hsts",
|
||||
settings.use_hsts],
|
||||
["security.mixed_content.send_hsts_priming",
|
||||
settings.send_hsts_priming],
|
||||
];
|
||||
|
||||
if (additional_prefs) {
|
||||
for (let idx in additional_prefs) {
|
||||
prefs.push(additional_prefs[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
Services.telemetry.canRecordExtended = true;
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': prefs});
|
||||
}
|
||||
|
||||
// make the top-level test uri
|
||||
function build_test_uri(base_uri, host, test_id, type, timeout) {
|
||||
return base_uri +
|
||||
"?host=" + escape(host) +
|
||||
"&id=" + escape(test_id) +
|
||||
"&type=" + escape(type) +
|
||||
"&timeout=" + escape(timeout)
|
||||
;
|
||||
}
|
||||
|
||||
// open a new tab, load the test, and wait for it to finish
|
||||
async function execute_test(test, mimetype) {
|
||||
var src = build_test_uri(TOP_URI, test_servers[test].host,
|
||||
test, test_settings[which_test].type,
|
||||
test_settings[which_test].timeout);
|
||||
|
||||
await BrowserTestUtils.withNewTab(src, () => {});
|
||||
}
|
||||
|
||||
/* Expected should look something like this:
|
||||
* The numbers are the sum of all telemetry values.
|
||||
var expected_telemetry = {
|
||||
"histograms": {
|
||||
"MIXED_CONTENT_HSTS_PRIMING_RESULT": 6,
|
||||
"HSTS_PRIMING_REQUESTS": 10,
|
||||
"HSTS_UPGRADE_SOURCE": [ 0,0,2,0,0,0,0,0,0 ]
|
||||
},
|
||||
"keyed-histograms": {
|
||||
"HSTS_PRIMING_REQUEST_DURATION": {
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
},
|
||||
}
|
||||
};
|
||||
*/
|
||||
function test_telemetry(expected) {
|
||||
for (let key in expected['histograms']) {
|
||||
let hs = undefined;
|
||||
try {
|
||||
let hist = Services.telemetry.getHistogramById(key);
|
||||
hs = hist.snapshot();
|
||||
hist.clear();
|
||||
} catch(e) {
|
||||
ok(false, "Caught exception trying to get histogram for key " + key + ":" + e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hs) {
|
||||
ok(false, "No histogram found for key " + key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Array.isArray(expected['histograms'][key])) {
|
||||
var is_ok = true;
|
||||
if (expected['histograms'][key].length != hs.counts.length) {
|
||||
ok(false, "Histogram lengths match");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let idx in expected['histograms'][key]) {
|
||||
is_ok = (hs.counts[idx] >= expected['histograms'][key][idx]);
|
||||
if (!is_ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(is_ok, "Histogram counts match for " + key + " - Got " + hs.counts + ", expected " + expected['histograms'][key]);
|
||||
} else {
|
||||
// there may have been other background requests processed
|
||||
ok(hs.counts.reduce(sum) >= expected['histograms'][key], "Histogram counts match expected, got " + hs.counts.reduce(sum) + ", expected at least " + expected['histograms'][key]);
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in expected['keyed-histograms']) {
|
||||
let hs = undefined;
|
||||
try {
|
||||
let hist = Services.telemetry.getKeyedHistogramById(key);
|
||||
hs = hist.snapshot();
|
||||
hist.clear();
|
||||
} catch(e) {
|
||||
ok(false, "Caught exception trying to get histogram for key " + key + " :" + e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hs) {
|
||||
ok(false, "No keyed histogram found for key " + key);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let hist_key in expected['keyed-histograms'][key]) {
|
||||
ok(hist_key in hs, "Keyed histogram exists with key");
|
||||
if (hist_key in hs) {
|
||||
ok(hs[hist_key].counts.reduce(sum) >= expected['keyed-histograms'][key][hist_key], "Keyed histogram counts match expected got " + hs[hist_key].counts.reduce(sum) + ", expected at least " + expected['keyed-histograms'][key][hist_key])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sum(a, b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
function clear_hists(hists) {
|
||||
for (let key in hists['histograms']) {
|
||||
try {
|
||||
let hist = Services.telemetry.getHistogramById(key);
|
||||
hist.clear();
|
||||
} catch(e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in hists['keyed-histograms']) {
|
||||
try {
|
||||
let hist = Services.telemetry.getKeyedHistogramById(key);
|
||||
hist.clear();
|
||||
} catch(e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -162,9 +162,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=62178
|
|||
}
|
||||
|
||||
function startTest() {
|
||||
// Set prefs to use mixed-content before HSTS
|
||||
SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.use_hsts", false],
|
||||
["security.mixed_content.send_hsts_priming", false]]});
|
||||
//Set the first set of mixed content settings and increment the counter.
|
||||
changePrefs([], function() {
|
||||
//listen for a messages from the mixed content test harness
|
||||
|
|
|
@ -36,13 +36,8 @@ function receiveMessage(event) {
|
|||
}
|
||||
|
||||
function startTest() {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [["security.mixed_content.use_hsts", false],
|
||||
["security.mixed_content.send_hsts_priming", false]]
|
||||
}, function () {
|
||||
let testframe = document.getElementById("testframe");
|
||||
testframe.src = PATH + "file_redirect.html";
|
||||
});
|
||||
let testframe = document.getElementById("testframe");
|
||||
testframe.src = PATH + "file_redirect.html";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -31,5 +31,4 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
'cors/browser.ini',
|
||||
'csp/browser.ini',
|
||||
'general/browser.ini',
|
||||
'hsts/browser.ini',
|
||||
]
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
|
||||
const sss = Cc["@mozilla.org/content/style-sheet-service;1"]
|
||||
.getService(Ci.nsIStyleSheetService);
|
||||
const domutils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
|
@ -26,7 +24,7 @@
|
|||
const authorUrl = "chrome://mochikit/content/tests/SimpleTest/test.css";
|
||||
|
||||
let results = [];
|
||||
for (let sheet of domutils.getAllStyleSheets(document)) {
|
||||
for (let sheet of InspectorUtils.getAllStyleSheets(document)) {
|
||||
if (sheet.href === agentUrl) {
|
||||
is(sheet.parsingMode, "agent", "agent sheet has expected mode");
|
||||
results[sss.AGENT_SHEET] = 1;
|
||||
|
@ -48,7 +46,7 @@
|
|||
|
||||
// Check that re-parsing preserves the mode.
|
||||
let mode = sheet.parsingMode;
|
||||
domutils.parseStyleSheet(sheet, "body { color: chartreuse; }");
|
||||
InspectorUtils.parseStyleSheet(sheet, "body { color: chartreuse; }");
|
||||
is(sheet.parsingMode, mode,
|
||||
"check that re-parsing preserved mode " + mode);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ dictionary CSSToken {
|
|||
* CSSLexer is an interface to the CSS lexer. It tokenizes an
|
||||
* input stream and returns CSS tokens.
|
||||
*
|
||||
* @see inIDOMUtils.getCSSLexer to create an instance of the lexer.
|
||||
* @see InspectorUtils.getCSSLexer to create an instance of the lexer.
|
||||
*/
|
||||
[ChromeOnly]
|
||||
interface CSSLexer
|
||||
|
|
|
@ -186,3 +186,14 @@ dictionary ConsoleInstanceOptions {
|
|||
// specified).
|
||||
DOMString maxLogLevelPref = "";
|
||||
};
|
||||
|
||||
enum ConsoleLevel { "log", "warning", "error" };
|
||||
|
||||
// this interface is just for testing
|
||||
partial interface ConsoleInstance {
|
||||
[ChromeOnly]
|
||||
void reportForServiceWorkerScope(DOMString scope, DOMString message,
|
||||
DOMString filename, unsigned long lineNumber,
|
||||
unsigned long columnNumber,
|
||||
ConsoleLevel level);
|
||||
};
|
||||
|
|
|
@ -3,16 +3,80 @@
|
|||
* 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/.
|
||||
*/
|
||||
dictionary InspectorRGBTriple {
|
||||
/*
|
||||
* NOTE: Using octet for RGB components is not generally OK, because
|
||||
* they can be outside the 0-255 range, but for backwards-compatible
|
||||
* named colors (which is what we use this dictionary for) the 0-255
|
||||
* assumption is fine.
|
||||
*/
|
||||
octet r = 0;
|
||||
octet g = 0;
|
||||
octet b = 0;
|
||||
|
||||
/**
|
||||
* A collection of utility methods for use by devtools.
|
||||
*
|
||||
* See InspectorUtils.h for documentation on these methods.
|
||||
*/
|
||||
[ChromeOnly]
|
||||
namespace InspectorUtils {
|
||||
sequence<StyleSheet> getAllStyleSheets(Document document);
|
||||
sequence<CSSRule> getCSSStyleRules(
|
||||
Element element,
|
||||
[TreatNullAs=EmptyString] optional DOMString pseudo = "");
|
||||
unsigned long getRuleLine(CSSRule rule);
|
||||
unsigned long getRuleColumn(CSSRule rule);
|
||||
unsigned long getRelativeRuleLine(CSSRule rule);
|
||||
[NewObject] CSSLexer getCSSLexer(DOMString text);
|
||||
unsigned long getSelectorCount(CSSStyleRule rule);
|
||||
[Throws] DOMString getSelectorText(CSSStyleRule rule,
|
||||
unsigned long selectorIndex);
|
||||
[Throws] unsigned long long getSpecificity(CSSStyleRule rule,
|
||||
unsigned long selectorIndex);
|
||||
[Throws] boolean selectorMatchesElement(
|
||||
Element element,
|
||||
CSSStyleRule rule,
|
||||
unsigned long selectorIndex,
|
||||
[TreatNullAs=EmptyString] optional DOMString pseudo = "");
|
||||
boolean isInheritedProperty(DOMString property);
|
||||
sequence<DOMString> getCSSPropertyNames(optional PropertyNamesOptions options);
|
||||
[Throws] sequence<DOMString> getCSSValuesForProperty(DOMString property);
|
||||
[Throws] DOMString rgbToColorName(octet r, octet g, octet b);
|
||||
InspectorRGBATuple? colorToRGBA(DOMString colorString);
|
||||
boolean isValidCSSColor(DOMString colorString);
|
||||
[Throws] sequence<DOMString> getSubpropertiesForCSSProperty(DOMString property);
|
||||
[Throws] boolean cssPropertyIsShorthand(DOMString property);
|
||||
|
||||
// TODO: Change this to use an enum.
|
||||
const unsigned long TYPE_LENGTH = 0;
|
||||
const unsigned long TYPE_PERCENTAGE = 1;
|
||||
const unsigned long TYPE_COLOR = 2;
|
||||
const unsigned long TYPE_URL = 3;
|
||||
const unsigned long TYPE_ANGLE = 4;
|
||||
const unsigned long TYPE_FREQUENCY = 5;
|
||||
const unsigned long TYPE_TIME = 6;
|
||||
const unsigned long TYPE_GRADIENT = 7;
|
||||
const unsigned long TYPE_TIMING_FUNCTION = 8;
|
||||
const unsigned long TYPE_IMAGE_RECT = 9;
|
||||
const unsigned long TYPE_NUMBER = 10;
|
||||
[Throws] boolean cssPropertySupportsType(DOMString property, unsigned long type);
|
||||
|
||||
boolean isIgnorableWhitespace(CharacterData dataNode);
|
||||
Node? getParentForNode(Node node, boolean showingAnonymousContent);
|
||||
[NewObject] NodeList getChildrenForNode(Node node,
|
||||
boolean showingAnonymousContent);
|
||||
sequence<DOMString> getBindingURLs(Element element);
|
||||
[Throws] void setContentState(Element element, unsigned long long state);
|
||||
[Throws] void removeContentState(
|
||||
Element element,
|
||||
unsigned long long state,
|
||||
optional boolean clearActiveDocument = false);
|
||||
unsigned long long getContentState(Element element);
|
||||
[NewObject, Throws] sequence<InspectorFontFace> getUsedFontFaces(Range range);
|
||||
sequence<DOMString> getCSSPseudoElementNames();
|
||||
void addPseudoClassLock(Element element,
|
||||
DOMString pseudoClass,
|
||||
optional boolean enabled = true);
|
||||
void removePseudoClassLock(Element element, DOMString pseudoClass);
|
||||
boolean hasPseudoClassLock(Element element, DOMString pseudoClass);
|
||||
void clearPseudoClassLocks(Element element);
|
||||
[Throws] void parseStyleSheet(CSSStyleSheet sheet, DOMString input);
|
||||
void scrollElementIntoView(Element element);
|
||||
};
|
||||
|
||||
dictionary PropertyNamesOptions {
|
||||
boolean includeAliases = false;
|
||||
};
|
||||
|
||||
dictionary InspectorRGBATuple {
|
||||
|
@ -27,3 +91,26 @@ dictionary InspectorRGBATuple {
|
|||
double b = 0;
|
||||
double a = 1;
|
||||
};
|
||||
|
||||
[ChromeOnly]
|
||||
interface InspectorFontFace {
|
||||
// An indication of how we found this font during font-matching.
|
||||
// Note that the same physical font may have been found in multiple ways within a range.
|
||||
readonly attribute boolean fromFontGroup;
|
||||
readonly attribute boolean fromLanguagePrefs;
|
||||
readonly attribute boolean fromSystemFallback;
|
||||
|
||||
// available for all fonts
|
||||
readonly attribute DOMString name; // full font name as obtained from the font resource
|
||||
readonly attribute DOMString CSSFamilyName; // a family name that could be used in CSS font-family
|
||||
// (not necessarily the actual name that was used,
|
||||
// due to aliases, generics, localized names, etc)
|
||||
|
||||
// meaningful only when the font is a user font defined using @font-face
|
||||
readonly attribute CSSFontFaceRule? rule; // null if no associated @font-face rule
|
||||
readonly attribute long srcIndex; // index in the rule's src list, -1 if no @font-face rule
|
||||
readonly attribute DOMString URI; // empty string if not a downloaded font, i.e. local
|
||||
readonly attribute DOMString localName; // empty string if not a src:local(...) rule
|
||||
readonly attribute DOMString format; // as per http://www.w3.org/TR/css3-webfonts/#referencing
|
||||
readonly attribute DOMString metadata; // XML metadata from WOFF file (if any)
|
||||
};
|
||||
|
|
|
@ -32,10 +32,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=398492
|
|||
/** Test for Bug 398492 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const InspectorUtils = SpecialPowers.InspectorUtils;
|
||||
|
||||
function getXBLParent(node) {
|
||||
var utils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Components.interfaces.inIDOMUtils);
|
||||
return utils.getParentForNode(node, true);
|
||||
return SpecialPowers.unwrap(InspectorUtils.getParentForNode(node, true));
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
|
|
|
@ -130,8 +130,6 @@ public:
|
|||
using EditorBase::RemoveAttributeOrEquivalent;
|
||||
using EditorBase::SetAttributeOrEquivalent;
|
||||
|
||||
nsresult MouseMove(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
// nsStubMutationObserver overrides
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
|
@ -444,6 +442,30 @@ public:
|
|||
mDefaultParagraphSeparator = aSep;
|
||||
}
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is pressed
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
* @param aMouseEvent [IN] the event
|
||||
*/
|
||||
nsresult OnMouseDown(int32_t aX, int32_t aY, nsIDOMElement* aTarget,
|
||||
nsIDOMEvent* aMouseEvent);
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is released
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
*/
|
||||
nsresult OnMouseUp(int32_t aX, int32_t aY, nsIDOMElement* aTarget);
|
||||
|
||||
/**
|
||||
* event callback when the mouse pointer is moved
|
||||
* @param aMouseEvent [IN] the event
|
||||
*/
|
||||
nsresult OnMouseMove(nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
protected:
|
||||
class BlobReader final : public nsIEditorBlobListener
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ HTMLEditorEventListener::MouseUp(nsIDOMMouseEvent* aMouseEvent)
|
|||
int32_t clientX, clientY;
|
||||
aMouseEvent->GetClientX(&clientX);
|
||||
aMouseEvent->GetClientY(&clientY);
|
||||
htmlEditor->MouseUp(clientX, clientY, element);
|
||||
htmlEditor->OnMouseUp(clientX, clientY, element);
|
||||
|
||||
return EditorEventListener::MouseUp(aMouseEvent);
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ HTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
|
|||
int32_t clientX, clientY;
|
||||
aMouseEvent->GetClientX(&clientX);
|
||||
aMouseEvent->GetClientY(&clientY);
|
||||
htmlEditor->MouseDown(clientX, clientY, element, aMouseEvent->AsEvent());
|
||||
htmlEditor->OnMouseDown(clientX, clientY, element, aMouseEvent->AsEvent());
|
||||
}
|
||||
|
||||
return EditorEventListener::MouseDown(aMouseEvent);
|
||||
|
|
|
@ -121,7 +121,7 @@ ResizerMouseMotionListener::HandleEvent(nsIDOMEvent* aMouseEvent)
|
|||
RefPtr<HTMLEditor> htmlEditor = mHTMLEditorWeak.get();
|
||||
if (htmlEditor) {
|
||||
// check if we have to redisplay a resizing shadow
|
||||
htmlEditor->MouseMove(mouseEvent);
|
||||
htmlEditor->OnMouseMove(mouseEvent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -548,11 +548,11 @@ HTMLEditor::StartResizing(nsIDOMElement* aHandle)
|
|||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::MouseDown(int32_t aClientX,
|
||||
int32_t aClientY,
|
||||
nsIDOMElement* aTarget,
|
||||
nsIDOMEvent* aEvent)
|
||||
nsresult
|
||||
HTMLEditor::OnMouseDown(int32_t aClientX,
|
||||
int32_t aClientY,
|
||||
nsIDOMElement* aTarget,
|
||||
nsIDOMEvent* aEvent)
|
||||
{
|
||||
bool anonElement = false;
|
||||
if (aTarget && NS_SUCCEEDED(aTarget->HasAttribute(NS_LITERAL_STRING("_moz_anonclass"), &anonElement)))
|
||||
|
@ -580,10 +580,10 @@ HTMLEditor::MouseDown(int32_t aClientX,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::MouseUp(int32_t aClientX,
|
||||
int32_t aClientY,
|
||||
nsIDOMElement* aTarget)
|
||||
nsresult
|
||||
HTMLEditor::OnMouseUp(int32_t aClientX,
|
||||
int32_t aClientY,
|
||||
nsIDOMElement* aTarget)
|
||||
{
|
||||
if (mIsResizing) {
|
||||
// we are resizing and release the mouse button, so let's
|
||||
|
@ -805,18 +805,8 @@ HTMLEditor::GetNewResizingHeight(int32_t aX,
|
|||
return std::max(resized, 1);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::MouseMove(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
if (NS_WARN_IF(!mouseEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
return MouseMove(mouseEvent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLEditor::MouseMove(nsIDOMMouseEvent* aMouseEvent)
|
||||
HTMLEditor::OnMouseMove(nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
MOZ_ASSERT(aMouseEvent);
|
||||
|
||||
|
|
|
@ -47,30 +47,5 @@ interface nsIHTMLObjectResizer : nsISupports
|
|||
* Refresh visible resizers
|
||||
*/
|
||||
void refreshResizers();
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is pressed
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
* @param aMouseEvent [IN] the event
|
||||
*/
|
||||
void mouseDown(in long aX, in long aY,
|
||||
in nsIDOMElement aTarget, in nsIDOMEvent aMouseEvent);
|
||||
|
||||
/**
|
||||
* event callback when a mouse button is released
|
||||
* @param aX [IN] horizontal position of the pointer
|
||||
* @param aY [IN] vertical position of the pointer
|
||||
* @param aTarget [IN] the element triggering the event
|
||||
*/
|
||||
void mouseUp(in long aX, in long aY,
|
||||
in nsIDOMElement aTarget);
|
||||
|
||||
/**
|
||||
* event callback when the mouse pointer is moved
|
||||
* @param aMouseEvent [IN] the event
|
||||
*/
|
||||
void mouseMove(in nsIDOMEvent aMouseEvent);
|
||||
};
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче