summaryrefslogtreecommitdiffstats
path: root/devtools/shared
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared')
-rw-r--r--devtools/shared/css/color.js32
-rw-r--r--devtools/shared/fronts/css-properties.js34
-rw-r--r--devtools/shared/gcli/commands/cmd.js4
-rw-r--r--devtools/shared/gcli/commands/cookie.js22
-rw-r--r--devtools/shared/gcli/commands/screenshot.js6
-rw-r--r--devtools/shared/gcli/source/lib/gcli/commands/help.js4
-rw-r--r--devtools/shared/inspector/css-logic.js12
-rw-r--r--devtools/shared/locales/en-US/gcli.properties9
-rw-r--r--devtools/shared/qrcode/moz.build2
-rw-r--r--devtools/shared/specs/node.js6
-rw-r--r--devtools/shared/specs/storage.js28
-rw-r--r--devtools/shared/specs/stylesheets.js8
-rw-r--r--devtools/shared/tests/mochitest/chrome.ini3
-rw-r--r--devtools/shared/tests/mochitest/test_css-logic-getCssPath.html121
-rw-r--r--devtools/shared/webconsole/network-helper.js27
-rw-r--r--devtools/shared/webconsole/network-monitor.js55
-rw-r--r--devtools/shared/webconsole/test/test_page_errors.html10
17 files changed, 337 insertions, 46 deletions
diff --git a/devtools/shared/css/color.js b/devtools/shared/css/color.js
index b354043d7..98ddeff19 100644
--- a/devtools/shared/css/color.js
+++ b/devtools/shared/css/color.js
@@ -28,6 +28,10 @@ const SPECIALVALUES = new Set([
* Usage:
* let {colorUtils} = require("devtools/shared/css/color");
* let color = new colorUtils.CssColor("red");
+ * // In order to support css-color-4 color function, pass true to the
+ * // second argument.
+ * // e.g.
+ * // let color = new colorUtils.CssColor("red", true);
*
* color.authored === "red"
* color.hasAlpha === false
@@ -58,8 +62,9 @@ const SPECIALVALUES = new Set([
* Valid values for COLOR_UNIT_PREF are contained in CssColor.COLORUNIT.
*/
-function CssColor(colorValue) {
+function CssColor(colorValue, supportsCssColor4ColorFunction = false) {
this.newColor(colorValue);
+ this.cssColor4 = supportsCssColor4ColorFunction;
}
module.exports.colorUtils = {
@@ -92,6 +97,9 @@ CssColor.prototype = {
// A lower-cased copy of |authored|.
lowerCased: null,
+ // Whether the value should be parsed using css-color-4 rules.
+ cssColor4: false,
+
_setColorUnitUppercase: function (color) {
// Specifically exclude the case where the color is
// case-insensitive. This makes it so that "#000" isn't
@@ -136,7 +144,7 @@ CssColor.prototype = {
},
get valid() {
- return isValidCSSColor(this.authored);
+ return isValidCSSColor(this.authored, this.cssColor4);
},
/**
@@ -393,7 +401,7 @@ CssColor.prototype = {
* appropriate.
*/
_getRGBATuple: function () {
- let tuple = colorToRGBA(this.authored);
+ let tuple = colorToRGBA(this.authored, this.cssColor4);
tuple.a = parseFloat(tuple.a.toFixed(1));
@@ -481,11 +489,13 @@ function roundTo(number, digits) {
* Color in the form of hex, hsl, hsla, rgb, rgba.
* @param {Number} alpha
* Alpha value for the color, between 0 and 1.
+ * @param {Boolean} useCssColor4ColorFunction
+ * use css-color-4 color function or not.
* @return {String}
* Converted color with `alpha` value in rgba form.
*/
-function setAlpha(colorValue, alpha) {
- let color = new CssColor(colorValue);
+function setAlpha(colorValue, alpha, useCssColor4ColorFunction = false) {
+ let color = new CssColor(colorValue, useCssColor4ColorFunction);
// Throw if the color supplied is not valid.
if (!color.valid) {
@@ -1049,12 +1059,11 @@ function parseOldStyleRgb(lexer, hasAlpha) {
* color's components. Any valid CSS color form can be passed in.
*
* @param {String} name the color
- * @param {Boolean} oldColorFunctionSyntax use old color function syntax or the
- * css-color-4 syntax
+ * @param {Boolean} useCssColor4ColorFunction use css-color-4 color function or not.
* @return {Object} an object of the form {r, g, b, a}; or null if the
* name was not a valid color
*/
-function colorToRGBA(name, oldColorFunctionSyntax = true) {
+function colorToRGBA(name, useCssColor4ColorFunction = false) {
name = name.trim().toLowerCase();
if (name in cssColors) {
@@ -1089,7 +1098,7 @@ function colorToRGBA(name, oldColorFunctionSyntax = true) {
let hsl = func.text === "hsl" || func.text === "hsla";
let vals;
- if (oldColorFunctionSyntax) {
+ if (!useCssColor4ColorFunction) {
let hasAlpha = (func.text === "rgba" || func.text === "hsla");
vals = hsl ? parseOldStyleHsl(lexer, hasAlpha) : parseOldStyleRgb(lexer, hasAlpha);
} else {
@@ -1110,8 +1119,9 @@ function colorToRGBA(name, oldColorFunctionSyntax = true) {
* Check whether a string names a valid CSS color.
*
* @param {String} name The string to check
+ * @param {Boolean} useCssColor4ColorFunction use css-color-4 color function or not.
* @return {Boolean} True if the string is a CSS color name.
*/
-function isValidCSSColor(name) {
- return colorToRGBA(name) !== null;
+function isValidCSSColor(name, useCssColor4ColorFunction = false) {
+ return colorToRGBA(name, useCssColor4ColorFunction) !== null;
}
diff --git a/devtools/shared/fronts/css-properties.js b/devtools/shared/fronts/css-properties.js
index 9b3172a22..d61bb4b07 100644
--- a/devtools/shared/fronts/css-properties.js
+++ b/devtools/shared/fronts/css-properties.js
@@ -47,6 +47,20 @@ const CssPropertiesFront = FrontClassWithSpec(cssPropertiesSpec, {
});
/**
+ * Query the feature supporting status in the featureSet.
+ *
+ * @param {Hashmap} featureSet the feature set hashmap
+ * @param {String} feature the feature name string
+ * @return {Boolean} has the feature or not
+ */
+function hasFeature(featureSet, feature) {
+ if (feature in featureSet) {
+ return featureSet[feature];
+ }
+ return false;
+}
+
+/**
* Ask questions to a CSS database. This class does not care how the database
* gets loaded in, only the questions that you can ask to it.
* Prototype functions are bound to 'this' so they can be passed around as helper
@@ -62,10 +76,16 @@ function CssProperties(db) {
this.properties = db.properties;
this.pseudoElements = db.pseudoElements;
+ // supported feature
+ this.cssColor4ColorFunction = hasFeature(db.supportedFeature,
+ "css-color-4-color-function");
+
this.isKnown = this.isKnown.bind(this);
this.isInherited = this.isInherited.bind(this);
this.supportsType = this.supportsType.bind(this);
this.isValidOnClient = this.isValidOnClient.bind(this);
+ this.supportsCssColor4ColorFunction =
+ this.supportsCssColor4ColorFunction.bind(this);
// A weakly held dummy HTMLDivElement to test CSS properties on the client.
this._dummyElements = new WeakMap();
@@ -181,6 +201,15 @@ CssProperties.prototype = {
}
return [];
},
+
+ /**
+ * Checking for the css-color-4 color function support.
+ *
+ * @return {Boolean} Return true if the server supports css-color-4 color function.
+ */
+ supportsCssColor4ColorFunction() {
+ return this.cssColor4ColorFunction;
+ },
};
/**
@@ -292,6 +321,11 @@ function normalizeCssData(db) {
reattachCssColorValues(db);
+ // If there is no supportedFeature in db, create an empty one.
+ if (!db.supportedFeature) {
+ db.supportedFeature = {};
+ }
+
return db;
}
diff --git a/devtools/shared/gcli/commands/cmd.js b/devtools/shared/gcli/commands/cmd.js
index 1777ed960..1b3cb2ecb 100644
--- a/devtools/shared/gcli/commands/cmd.js
+++ b/devtools/shared/gcli/commands/cmd.js
@@ -137,8 +137,6 @@ exports.items = [
return !prefBranch.prefHasUserValue(PREF_DIR);
},
exec: function(args, context) {
- gcli.load();
-
let dirName = prefBranch.getComplexValue(PREF_DIR,
Ci.nsISupportsString).data.trim();
return l10n.lookupFormat("cmdStatus3", [ dirName ]);
@@ -170,8 +168,6 @@ exports.items = [
supportsString.data = args.directory;
prefBranch.setComplexValue(PREF_DIR, Ci.nsISupportsString, supportsString);
- gcli.load();
-
return l10n.lookupFormat("cmdStatus3", [ args.directory ]);
}
}
diff --git a/devtools/shared/gcli/commands/cookie.js b/devtools/shared/gcli/commands/cookie.js
index f1680042f..203ac738c 100644
--- a/devtools/shared/gcli/commands/cookie.js
+++ b/devtools/shared/gcli/commands/cookie.js
@@ -100,7 +100,7 @@ exports.items = [
let cookies = [];
while (enm.hasMoreElements()) {
- let cookie = enm.getNext().QueryInterface(Ci.nsICookie);
+ let cookie = enm.getNext().QueryInterface(Ci.nsICookie2);
if (isCookieAtHost(cookie, host)) {
cookies.push({
host: cookie.host,
@@ -108,9 +108,10 @@ exports.items = [
value: cookie.value,
path: cookie.path,
expires: cookie.expires,
- secure: cookie.secure,
- httpOnly: cookie.httpOnly,
- sameDomain: cookie.sameDomain
+ isDomain: cookie.isDomain,
+ isHttpOnly: cookie.isHttpOnly,
+ isSecure: cookie.isSecure,
+ isSession: cookie.isSession,
});
}
}
@@ -169,11 +170,14 @@ exports.items = [
for (let cookie of cookies) {
cookie.expires = translateExpires(cookie.expires);
- let noAttrs = !cookie.secure && !cookie.httpOnly && !cookie.sameDomain;
- cookie.attrs = (cookie.secure ? "secure" : " ") +
- (cookie.httpOnly ? "httpOnly" : " ") +
- (cookie.sameDomain ? "sameDomain" : " ") +
- (noAttrs ? l10n.lookup("cookieListOutNone") : " ");
+ let noAttrs = !cookie.isDomain && !cookie.isHttpOnly &&
+ !cookie.isSecure && !cookie.isSession;
+ cookie.attrs = ((cookie.isDomain ? "isDomain " : "") +
+ (cookie.isHttpOnly ? "isHttpOnly " : "") +
+ (cookie.isSecure ? "isSecure " : "") +
+ (cookie.isSession ? "isSession " : "") +
+ (noAttrs ? l10n.lookup("cookieListOutNone") : ""))
+ .trim();
}
return context.createView({
diff --git a/devtools/shared/gcli/commands/screenshot.js b/devtools/shared/gcli/commands/screenshot.js
index e2f38b6d9..11bafcab9 100644
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -277,6 +277,12 @@ function createScreenshotData(document, args) {
window.scrollTo(0,0);
width = window.innerWidth + window.scrollMaxX - window.scrollMinX;
height = window.innerHeight + window.scrollMaxY - window.scrollMinY;
+ let writingMode = "horizontal-tb";
+ if (window.getComputedStyle(document.documentElement)) {
+ writingMode = window.getComputedStyle(document.documentElement).writingMode;
+ }
+ let orientation = writingMode.substring(0, writingMode.indexOf("-")).toLowerCase();
+ left = ((orientation != "vertical") ? left : (-width + window.innerWidth));
filename = filename.replace(".png", "-fullpage.png");
}
else if (args.selector) {
diff --git a/devtools/shared/gcli/source/lib/gcli/commands/help.js b/devtools/shared/gcli/source/lib/gcli/commands/help.js
index 7d1cc9087..365c53380 100644
--- a/devtools/shared/gcli/source/lib/gcli/commands/help.js
+++ b/devtools/shared/gcli/source/lib/gcli/commands/help.js
@@ -275,7 +275,7 @@ exports.items = [
' <div if="${command.isParent}">\n' +
' <p class="gcli-help-header">${l10n.subCommands}:</p>\n' +
' <ul class="gcli-help-${subcommands}">\n' +
- ' <li if="${subcommands.length === 0}">${l10n.subcommandsNone}</li>\n' +
+ ' <li if="${subcommands.length === 0}">${l10n.subCommandsNone}</li>\n' +
' <li foreach="subcommand in ${subcommands}">\n' +
' ${subcommand.name}: ${subcommand.description}\n' +
' <span class="gcli-out-shortcut" data-command="help ${subcommand.name}"\n' +
@@ -321,7 +321,7 @@ exports.items = [
'\n' +
'<span if="${command.isParent}"># ${l10n.subCommands}:</span>\n' +
'\n' +
- '<span if="${subcommands.length === 0}">${l10n.subcommandsNone}</span>\n' +
+ '<span if="${subcommands.length === 0}">${l10n.subCommandsNone}</span>\n' +
'<loop foreach="subcommand in ${subcommands}">* ${subcommand.name}: ${subcommand.description}\n' +
'</loop>\n' +
'</div>\n',
diff --git a/devtools/shared/inspector/css-logic.js b/devtools/shared/inspector/css-logic.js
index c8cdd2fdb..901b7a189 100644
--- a/devtools/shared/inspector/css-logic.js
+++ b/devtools/shared/inspector/css-logic.js
@@ -30,6 +30,8 @@
"use strict";
+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
@@ -103,6 +105,13 @@ exports.shortSource = function (sheet) {
return exports.l10n("rule.sourceInline");
}
+ // If the sheet is a data URL, return a trimmed version of it.
+ let dataUrl = sheet.href.trim().match(/^data:.*?,((?:.|\r|\n)*)$/);
+ if (dataUrl) {
+ return dataUrl[1].length > MAX_DATA_URL_LENGTH ?
+ `${dataUrl[1].substr(0, MAX_DATA_URL_LENGTH - 1)}…` : dataUrl[1];
+ }
+
// We try, in turn, the filename, filePath, query string, whole thing
let url = {};
try {
@@ -123,8 +132,7 @@ exports.shortSource = function (sheet) {
return url.query;
}
- let dataUrl = sheet.href.match(/^(data:[^,]*),/);
- return dataUrl ? dataUrl[1] : sheet.href;
+ return sheet.href;
};
const TAB_CHARS = "\t";
diff --git a/devtools/shared/locales/en-US/gcli.properties b/devtools/shared/locales/en-US/gcli.properties
index e5231e44a..59c344832 100644
--- a/devtools/shared/locales/en-US/gcli.properties
+++ b/devtools/shared/locales/en-US/gcli.properties
@@ -141,9 +141,10 @@ helpManual=Provide help either on a specific command (if a search string is prov
helpSearchDesc=Search string
helpSearchManual3=search string to use in narrowing down the displayed commands. Regular expressions not supported.
-# LOCALIZATION NOTE: These strings are displayed in the help page for a
-# command in the console.
+# LOCALIZATION NOTE (helpManSynopsis, helpManDescription): These strings are
+# displayed in the help page for a command in the console.
helpManSynopsis=Synopsis
+helpManDescription=Description
# LOCALIZATION NOTE: This message is displayed in the help page if the command
# has no parameters.
@@ -177,6 +178,10 @@ helpIntro=GCLI is an experiment to create a highly usable command line for web d
# sub-commands.
subCommands=Sub-Commands
+# LOCALIZATION NOTE: Text shown as part of the output of the 'help' command
+# when the command in question should have sub-commands but in fact has none.
+subCommandsNone=None
+
# LOCALIZATION NOTE: This error message is displayed when the command line is
# cannot find a match for the parse types.
commandParseError=Command line parsing error
diff --git a/devtools/shared/qrcode/moz.build b/devtools/shared/qrcode/moz.build
index 68a093b1c..c9493a538 100644
--- a/devtools/shared/qrcode/moz.build
+++ b/devtools/shared/qrcode/moz.build
@@ -9,7 +9,7 @@ DIRS += [
]
# Save file size on Fennec until there are active plans to use the decoder there
-if CONFIG['MOZ_BUILD_APP'] != 'mobile/android':
+if not CONFIG['MOZ_FENNEC']:
DIRS += [
'decoder'
]
diff --git a/devtools/shared/specs/node.js b/devtools/shared/specs/node.js
index ea3d1b264..022d7f1ac 100644
--- a/devtools/shared/specs/node.js
+++ b/devtools/shared/specs/node.js
@@ -37,6 +37,12 @@ const nodeSpec = generateActorSpec({
value: RetVal("string")
}
},
+ getCssPath: {
+ request: {},
+ response: {
+ value: RetVal("string")
+ }
+ },
scrollIntoView: {
request: {},
response: {}
diff --git a/devtools/shared/specs/storage.js b/devtools/shared/specs/storage.js
index d6ddaefe5..42a35073a 100644
--- a/devtools/shared/specs/storage.js
+++ b/devtools/shared/specs/storage.js
@@ -40,6 +40,7 @@ function createStorageSpec(options) {
// Cookies store object
types.addDictType("cookieobject", {
+ uniqueKey: "string",
name: "string",
value: "longstring",
path: "nullable:string",
@@ -61,7 +62,7 @@ types.addDictType("cookiestoreobject", {
// Common methods for edit/remove
const editRemoveMethods = {
- getEditableFields: {
+ getFields: {
request: {},
response: {
value: RetVal("json")
@@ -89,6 +90,13 @@ createStorageSpec({
methods: Object.assign({},
editRemoveMethods,
{
+ addItem: {
+ request: {
+ guid: Arg(0, "string"),
+ },
+ response: {}
+ }
+ }, {
removeAll: {
request: {
host: Arg(0, "string"),
@@ -96,6 +104,14 @@ createStorageSpec({
},
response: {}
}
+ }, {
+ removeAllSessionCookies: {
+ request: {
+ host: Arg(0, "string"),
+ domain: Arg(1, "nullable:string")
+ },
+ response: {}
+ }
}
)
});
@@ -110,6 +126,14 @@ types.addDictType("storageobject", {
const storageMethods = Object.assign({},
editRemoveMethods,
{
+ addItem: {
+ request: {
+ guid: Arg(0, "string"),
+ host: Arg(1, "nullable:string")
+ },
+ response: {}
+ }
+ }, {
removeAll: {
request: {
host: Arg(0, "string")
@@ -176,11 +200,13 @@ createStorageSpec({
// This is a union on idb object, db metadata object and object store metadata
// object
types.addDictType("idbobject", {
+ uniqueKey: "string",
name: "nullable:string",
db: "nullable:string",
objectStore: "nullable:string",
origin: "nullable:string",
version: "nullable:number",
+ storage: "nullable:string",
objectStores: "nullable:number",
keyPath: "nullable:string",
autoIncrement: "nullable:boolean",
diff --git a/devtools/shared/specs/stylesheets.js b/devtools/shared/specs/stylesheets.js
index c89a7c088..fc75281f8 100644
--- a/devtools/shared/specs/stylesheets.js
+++ b/devtools/shared/specs/stylesheets.js
@@ -105,6 +105,14 @@ exports.styleSheetSpec = styleSheetSpec;
const styleSheetsSpec = generateActorSpec({
typeName: "stylesheets",
+ events: {
+ "stylesheet-added": {
+ type: "stylesheetAdded",
+ sheet: Arg(0, "stylesheet"),
+ isNew: Arg(1, "boolean")
+ },
+ },
+
methods: {
getStyleSheets: {
request: {},
diff --git a/devtools/shared/tests/mochitest/chrome.ini b/devtools/shared/tests/mochitest/chrome.ini
index 85ece7c48..3e4e028d1 100644
--- a/devtools/shared/tests/mochitest/chrome.ini
+++ b/devtools/shared/tests/mochitest/chrome.ini
@@ -2,6 +2,7 @@
tags = devtools
skip-if = os == 'android'
-[test_eventemitter_basic.html]
+[test_css-logic-getCssPath.html]
[test_devtools_extensions.html]
+[test_eventemitter_basic.html]
skip-if = os == 'linux' && debug # Bug 1205739
diff --git a/devtools/shared/tests/mochitest/test_css-logic-getCssPath.html b/devtools/shared/tests/mochitest/test_css-logic-getCssPath.html
new file mode 100644
index 000000000..2c444308a
--- /dev/null
+++ b/devtools/shared/tests/mochitest/test_css-logic-getCssPath.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1323700
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1323700</title>
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+ <script type="application/javascript;version=1.8">
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
+const CssLogic = require("devtools/shared/inspector/css-logic");
+
+var _tests = [];
+function addTest(test) {
+ _tests.push(test);
+}
+
+function runNextTest() {
+ if (_tests.length == 0) {
+ SimpleTest.finish()
+ return;
+ }
+ _tests.shift()();
+}
+
+window.onload = function() {
+ SimpleTest.waitForExplicitFinish();
+ runNextTest();
+}
+
+addTest(function getCssPathForUnattachedElement() {
+ var unattached = document.createElement("div");
+ unattached.id = "unattached";
+ try {
+ CssLogic.getCssPath(unattached);
+ ok(false, "Unattached node did not throw")
+ } catch(e) {
+ ok(e, "Unattached node throws an exception");
+ }
+
+ var unattachedChild = document.createElement("div");
+ unattached.appendChild(unattachedChild);
+ try {
+ CssLogic.getCssPath(unattachedChild);
+ ok(false, "Unattached child node did not throw")
+ } catch(e) {
+ ok(e, "Unattached child node throws an exception");
+ }
+
+ var unattachedBody = document.createElement("body");
+ try {
+ CssLogic.getCssPath(unattachedBody);
+ ok(false, "Unattached body node did not throw")
+ } catch(e) {
+ ok(e, "Unattached body node throws an exception");
+ }
+
+ runNextTest();
+});
+
+addTest(function cssPathHasOneStepForEachAncestor() {
+ for (let el of [...document.querySelectorAll('*')]) {
+ let splitPath = CssLogic.getCssPath(el).split(" ");
+
+ let expectedNbOfParts = 0;
+ var parent = el.parentNode;
+ while (parent) {
+ expectedNbOfParts ++;
+ parent = parent.parentNode;
+ }
+
+ is(splitPath.length, expectedNbOfParts, "There are enough parts in the full path");
+ }
+
+ runNextTest();
+});
+
+addTest(function getCssPath() {
+ let data = [{
+ selector: "#id",
+ path: "html body div div div.class div#id"
+ }, {
+ selector: "html",
+ path: "html"
+ }, {
+ selector: "body",
+ path: "html body"
+ }, {
+ selector: ".c1.c2.c3",
+ path: "html body span.c1.c2.c3"
+ }, {
+ selector: "#i",
+ path: "html body span#i.c1.c2"
+ }];
+
+ for (let {selector, path} of data) {
+ let node = document.querySelector(selector);
+ is (CssLogic.getCssPath(node), path, `Full css path is correct for ${selector}`);
+ }
+
+ runNextTest();
+});
+ </script>
+</head>
+<body>
+ <div>
+ <div>
+ <div class="class">
+ <div id="id"></div>
+ </div>
+ </div>
+ </div>
+ <span class="c1 c2 c3"></span>
+ <span id="i" class="c1 c2"></span>
+</body>
+</html>
diff --git a/devtools/shared/webconsole/network-helper.js b/devtools/shared/webconsole/network-helper.js
index af6a2e55b..4e25fac26 100644
--- a/devtools/shared/webconsole/network-helper.js
+++ b/devtools/shared/webconsole/network-helper.js
@@ -63,6 +63,8 @@ const {components, Cc, Ci} = require("chrome");
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const Services = require("Services");
+const { LocalizationHelper } = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/client/locales/netmonitor.properties");
// The cache used in the `nsIURL` function.
const gNSURLStore = new Map();
@@ -620,6 +622,31 @@ var NetworkHelper = {
// Cipher suite.
info.cipherSuite = SSLStatus.cipherName;
+ // Key exchange group name.
+ info.keaGroupName = SSLStatus.keaGroupName;
+ // Localise two special values.
+ if (info.keaGroupName == "none") {
+ info.keaGroupName = L10N.getStr("netmonitor.security.keaGroup.none");
+ }
+ if (info.keaGroupName == "custom") {
+ info.keaGroupName = L10N.getStr("netmonitor.security.keaGroup.custom");
+ }
+ if (info.keaGroupName == "unknown group") {
+ info.keaGroupName = L10N.getStr("netmonitor.security.keaGroup.unknown");
+ }
+
+ // Certificate signature scheme.
+ info.signatureSchemeName = SSLStatus.signatureSchemeName;
+ // Localise two special values.
+ if (info.signatureSchemeName == "none") {
+ info.signatureSchemeName =
+ L10N.getStr("netmonitor.security.signatureScheme.none");
+ }
+ if (info.signatureSchemeName == "unknown signature") {
+ info.signatureSchemeName =
+ L10N.getStr("netmonitor.security.signatureScheme.unknown");
+ }
+
// Protocol version.
info.protocolVersion =
this.formatSecurityProtocol(SSLStatus.protocolVersion);
diff --git a/devtools/shared/webconsole/network-monitor.js b/devtools/shared/webconsole/network-monitor.js
index 084493432..a55162f52 100644
--- a/devtools/shared/webconsole/network-monitor.js
+++ b/devtools/shared/webconsole/network-monitor.js
@@ -732,7 +732,9 @@ NetworkMonitor.prototype = {
0x804b0004: "STATUS_CONNECTED_TO",
0x804b0005: "STATUS_SENDING_TO",
0x804b000a: "STATUS_WAITING_FOR",
- 0x804b0006: "STATUS_RECEIVING_FROM"
+ 0x804b0006: "STATUS_RECEIVING_FROM",
+ 0x804b000c: "STATUS_TLS_STARTING",
+ 0x804b000d: "STATUS_TLS_ENDING"
},
httpDownloadActivities: [
@@ -1327,8 +1329,24 @@ NetworkMonitor.prototype = {
let response = {};
response.httpVersion = statusLineArray.shift();
- response.remoteAddress = httpActivity.channel.remoteAddress;
- response.remotePort = httpActivity.channel.remotePort;
+ // XXX:
+ // Sometimes, when using a proxy server (manual proxy configuration),
+ // throws an error:
+ // 0x80040111 (NS_ERROR_NOT_AVAILABLE)
+ // [nsIHttpChannelInternal.remoteAddress]
+ // Bug 1337791 is the suspect.
+ response.remoteAddress = null;
+ try {
+ response.remoteAddress = httpActivity.channel.remoteAddress;
+ } catch (e) {
+ Cu.reportError(e);
+ }
+ response.remotePort = null;
+ try {
+ response.remotePort = httpActivity.channel.remotePort;
+ } catch (e) {
+ Cu.reportError(e);
+ }
response.status = statusLineArray.shift();
response.statusText = statusLineArray.join(" ");
response.headersSize = extraStringData.length;
@@ -1390,6 +1408,7 @@ NetworkMonitor.prototype = {
timings: {
blocked: 0,
dns: 0,
+ ssl: 0,
connect: 0,
send: 0,
wait: 0,
@@ -1424,6 +1443,36 @@ NetworkMonitor.prototype = {
harTimings.connect = -1;
}
+ if (timings.STATUS_TLS_STARTING && timings.STATUS_TLS_ENDING) {
+ harTimings.ssl = timings.STATUS_TLS_ENDING.last -
+ timings.STATUS_TLS_STARTING.first;
+ } else {
+ harTimings.ssl = -1;
+ }
+
+ // sometimes the connection information events are attached to a speculative
+ // channel instead of this one, but necko might glue them back together in the
+ // nsITimedChannel interface used by Resource and Navigation Timing
+ let timedChannel = httpActivity.channel.QueryInterface(Ci.nsITimedChannel);
+
+ if ((harTimings.connect <= 0) && timedChannel) {
+ if (timedChannel.secureConnectionStartTime > timedChannel.connectStartTime) {
+ harTimings.connect =
+ timedChannel.secureConnectionStartTime - timedChannel.connectStartTime;
+ harTimings.ssl =
+ timedChannel.connectEndTime - timedChannel.secureConnectionStartTime;
+ } else {
+ harTimings.connect =
+ timedChannel.connectEndTime - timedChannel.connectStartTime;
+ harTimings.ssl = -1;
+ }
+ }
+
+ if ((harTimings.dns <= 0) && timedChannel) {
+ harTimings.dns =
+ timedChannel.domainLookupEndTime - timedChannel.domainLookupStartTime;
+ }
+
if (timings.STATUS_SENDING_TO) {
harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first;
} else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) {
diff --git a/devtools/shared/webconsole/test/test_page_errors.html b/devtools/shared/webconsole/test/test_page_errors.html
index 19e5ba4b4..78138856e 100644
--- a/devtools/shared/webconsole/test/test_page_errors.html
+++ b/devtools/shared/webconsole/test/test_page_errors.html
@@ -102,16 +102,6 @@ function doPageErrors()
warning: false,
exception: true,
},
- "var f = Function('x y', 'return x + y;');": {
- errorMessage: /malformed formal/,
- errorMessageName: "JSMSG_BAD_FORMAL",
- sourceName: /test_page_errors/,
- category: "chrome javascript",
- timeStamp: /^\d+$/,
- error: false,
- warning: false,
- exception: true,
- },
"function a() { return; 1 + 1; }": {
errorMessage: /unreachable code/,
errorMessageName: "JSMSG_STMT_AFTER_RETURN",