Bug 1360868 - Properly formatted data URLs in source links r=pbro
MozReview-Commit-ID: 7loVwUynHhw
--- a/devtools/client/inspector/rules/models/rule.js
+++ b/devtools/client/inspector/rules/models/rule.js
@@ -135,21 +135,32 @@ Rule.prototype = {
* Promise which resolves with location as an object containing
* both the full and short version of the source string.
*/
getOriginalSourceStrings: function () {
return this.domRule.getOriginalLocation().then(({href,
line, mediaText}) => {
let mediaString = mediaText ? " @" + mediaText : "";
let linePart = line > 0 ? (":" + line) : "";
+ let decodedHref = href;
+
+ if (decodedHref) {
+ try {
+ decodedHref = decodeURI(href);
+ } catch (e) {
+ decodedHref = href;
+ }
+
+ decodedHref = unescape(href);
+ }
let sourceStrings = {
- full: (href || CssLogic.l10n("rule.sourceInline")) + linePart +
+ full: (decodedHref || CssLogic.l10n("rule.sourceInline")) + linePart +
mediaString,
- short: CssLogic.shortSource({href: href}) + linePart + mediaString
+ short: CssLogic.shortSource({href: decodedHref}) + linePart + mediaString
};
return sourceStrings;
});
},
/**
* Returns true if the rule matches the creation options
--- a/devtools/client/inspector/rules/test/browser_rules_style-editor-link.js
+++ b/devtools/client/inspector/rules/test/browser_rules_style-editor-link.js
@@ -1,20 +1,22 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test the links from the rule-view to the styleeditor
-const STYLESHEET_URL = "data:text/css," + encodeURIComponent(
- ["#first {",
- "color: blue",
- "}"].join("\n"));
+const STYLESHEET_DATA_URL_CONTENTS = ["#first {",
+ "color: blue",
+ "}"].join("\n");
+const STYLESHEET_DATA_URL =
+ `data:text/css,${encodeURIComponent(STYLESHEET_DATA_URL_CONTENTS)}`;
+const STYLESHEET_DECODED_DATA_URL = `data:text/css,${STYLESHEET_DATA_URL_CONTENTS}`;
const EXTERNAL_STYLESHEET_FILE_NAME = "doc_style_editor_link.css";
const EXTERNAL_STYLESHEET_URL = URL_ROOT + EXTERNAL_STYLESHEET_FILE_NAME;
const DOCUMENT_URL = "data:text/html;charset=utf-8," + encodeURIComponent(`
<html>
<head>
<title>Rule view style editor link test</title>
@@ -22,17 +24,17 @@ const DOCUMENT_URL = "data:text/html;cha
html { color: #000000; }
div { font-variant: small-caps; color: #000000; }
.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em;
font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">
</style>
<style>
div { font-weight: bold; }
</style>
- <link rel="stylesheet" type="text/css" href="${STYLESHEET_URL}">
+ <link rel="stylesheet" type="text/css" href="${STYLESHEET_DATA_URL}">
<link rel="stylesheet" type="text/css" href="${EXTERNAL_STYLESHEET_URL}">
</head>
<body>
<h1>Some header text</h1>
<p id="salutation" style="font-size: 12pt">hi.</p>
<p id="body" style="font-size: 12pt">I am a test-case. This text exists
solely to provide some things to
<span style="color: yellow" class="highlight">
@@ -169,25 +171,37 @@ function* testDisabledStyleEditor(view,
clickLinkByIndex(view, 1);
yield onStyleEditorSelected;
is(toolbox.currentToolId, "styleeditor", "Style Editor should be selected");
Services.prefs.clearUserPref("devtools.styleeditor.enabled");
}
function testRuleViewLinkLabel(view) {
- let link = getRuleViewLinkByIndex(view, 2);
+ // Check data URL link label
+ let link = getRuleViewLinkByIndex(view, 1);
let labelElem = link.querySelector(".ruleview-rule-source-label");
let value = labelElem.textContent;
let tooltipText = labelElem.getAttribute("title");
- is(value, EXTERNAL_STYLESHEET_FILE_NAME + ":1",
- "rule view stylesheet display value matches filename and line number");
- is(tooltipText, EXTERNAL_STYLESHEET_URL + ":1",
- "rule view stylesheet tooltip text matches the full URI path");
+ is(value, `${STYLESHEET_DATA_URL_CONTENTS}:1`,
+ "rule view data URL stylesheet display value matches contents");
+ is(tooltipText, `${STYLESHEET_DECODED_DATA_URL}:1`,
+ "rule view data URL stylesheet tooltip text matches the full URI path");
+
+ // Check external link label
+ link = getRuleViewLinkByIndex(view, 2);
+ labelElem = link.querySelector(".ruleview-rule-source-label");
+ value = labelElem.textContent;
+ tooltipText = labelElem.getAttribute("title");
+
+ is(value, `${EXTERNAL_STYLESHEET_FILE_NAME}:1`,
+ "rule view external stylesheet display value matches filename and line number");
+ is(tooltipText, `${EXTERNAL_STYLESHEET_URL}:1`,
+ "rule view external stylesheet tooltip text matches the full URI path");
}
function testUnselectableRuleViewLink(view, index) {
let link = getRuleViewLinkByIndex(view, index);
let unselectable = link.hasAttribute("unselectable");
ok(unselectable, "Rule view is unselectable");
}
--- a/devtools/shared/inspector/css-logic.js
+++ b/devtools/shared/inspector/css-logic.js
@@ -4,16 +4,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { getRootBindingParent } = require("devtools/shared/layout/utils");
const { getTabPrefs } = require("devtools/shared/indentation");
+const CROP_STRING_LENGTH = 40;
+
/*
* About the objects defined in this file:
* - CssLogic contains style information about a view context. It provides
* access to 2 sets of objects: Css[Sheet|Rule|Selector] provide access to
* information that does not change when the selected element changes while
* Css[Property|Selector]Info provide information that is dependent on the
* selected element.
* Its key methods are highlight(), getPropertyInfo() and forEachSheet(), etc
@@ -104,16 +106,22 @@ exports.isContentStylesheet = function (
* @param {CSSStyleSheet} sheet the DOM object for the style sheet.
*/
exports.shortSource = function (sheet) {
// Use a string like "inline" if there is no source href
if (!sheet || !sheet.href) {
return exports.l10n("rule.sourceInline");
}
+ let dataUrl = sheet.href.trim().match(/^data:.*?,((?:.|\r|\n)*)$/);
+ if (dataUrl) {
+ return dataUrl[1].length > CROP_STRING_LENGTH ?
+ dataUrl[1].substr(0, CROP_STRING_LENGTH - 1) + "…" : dataUrl[1];
+ }
+
// We try, in turn, the filename, filePath, query string, whole thing
let url = {};
try {
url = new URL(sheet.href);
} catch (ex) {
// Some UA-provided stylesheets are not valid URLs.
}
@@ -124,18 +132,17 @@ exports.shortSource = function (sheet) {
}
return url.pathname;
}
if (url.query) {
return url.query;
}
- let dataUrl = sheet.href.match(/^(data:[^,]*),/);
- return dataUrl ? dataUrl[1] : sheet.href;
+ return sheet.href;
};
const TAB_CHARS = "\t";
const SPACE_CHARS = " ";
/**
* Prettify minified CSS text.
* This prettifies CSS code where there is no indentation in usual places while