Bug 947733 - Tooltips are shown on !important properties in the rule-view; r=miker

This commit is contained in:
Patrick Brosset 2014-01-30 16:04:47 +01:00
parent f2def806aa
commit 61c34f059a
3 changed files with 210 additions and 3 deletions

View File

@ -66,3 +66,4 @@ support-files =
[browser_computedview_original_source_link.js]
[browser_bug946331_close_tooltip_on_new_selection.js]
[browser_bug942297_user_property_reset.js]
[browser_styleinspector_outputparser.js]

View File

@ -0,0 +1,194 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test expected outputs of the output-parser's parseCssProperty function.
// This is more of a unit test than a mochitest-browser test, but can't be
// tested with an xpcshell test as the output-parser requires the DOM to work.
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let {OutputParser} = devtools.require("devtools/output-parser");
const COLOR_CLASS = "color-class";
const URL_CLASS = "url-class";
function test() {
waitForExplicitFinish();
let testData = [
{
name: "width",
value: "100%",
test: fragment => {
is(fragment.querySelectorAll("*").length, 0);
is(fragment.textContent, "100%");
}
},
{
name: "width",
value: "blue",
test: fragment => {
is(fragment.querySelectorAll("*").length, 0);
}
},
{
name: "content",
value: "'red url(test.png) repeat top left'",
test: fragment => {
is(fragment.querySelectorAll("*").length, 0);
}
},
{
name: "content",
value: "\"blue\"",
test: fragment => {
is(fragment.querySelectorAll("*").length, 0);
}
},
{
name: "margin-left",
value: "url(something.jpg)",
test: fragment => {
is(fragment.querySelectorAll("*").length, 0);
}
},
{
name: "background-color",
value: "transparent",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.textContent, "transparent");
}
},
{
name: "color",
value: "red",
test: fragment => {
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.textContent, "red");
}
},
{
name: "color",
value: "#F06",
test: fragment => {
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.textContent, "#F06");
}
},
{
name: "border-top-left-color",
value: "rgba(14, 255, 20, .5)",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.textContent, "rgba(14, 255, 20, .5)");
}
},
{
name: "border",
value: "80em dotted pink",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.querySelector("." + COLOR_CLASS).textContent, "pink");
}
},
{
name: "color",
value: "red !important",
test: fragment => {
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.textContent, "red !important");
}
},
{
name: "background",
value: "red url(test.png) repeat top left",
test: fragment => {
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.querySelectorAll("." + URL_CLASS).length, 1);
is(fragment.querySelector("." + COLOR_CLASS).textContent, "red");
is(fragment.querySelector("." + URL_CLASS).textContent, "test.png");
is(fragment.querySelectorAll("*").length, 2);
}
},
{
name: "background",
value: "blue url(test.png) repeat top left !important",
test: fragment => {
is(fragment.querySelectorAll("." + COLOR_CLASS).length, 1);
is(fragment.querySelectorAll("." + URL_CLASS).length, 1);
is(fragment.querySelector("." + COLOR_CLASS).textContent, "blue");
is(fragment.querySelector("." + URL_CLASS).textContent, "test.png");
is(fragment.querySelectorAll("*").length, 2);
}
},
{
name: "list-style-image",
value: "url(\"images/arrow.gif\")",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelector("." + URL_CLASS).textContent, "images/arrow.gif");
}
},
{
name: "list-style-image",
value: "url(\"images/arrow.gif\")!important",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelector("." + URL_CLASS).textContent, "images/arrow.gif");
is(fragment.textContent, "url('images/arrow.gif')!important");
}
},
{
name: "-moz-binding",
value: "url(http://somesite.com/path/to/binding.xml#someid)",
test: fragment => {
is(fragment.querySelectorAll("*").length, 1);
is(fragment.querySelectorAll("." + URL_CLASS).length, 1);
is(fragment.querySelector("." + URL_CLASS).textContent, "http://somesite.com/path/to/binding.xml#someid");
}
},
{
name: "background",
value: "linear-gradient(to right, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 30%, rgba(31,170,217,.5) 44%, #F06 75%, red 100%)",
test: fragment => {
is(fragment.querySelectorAll("*").length, 5);
let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS);
is(allSwatches.length, 5);
is(allSwatches[0].textContent, "rgba(183,222,237,1)");
is(allSwatches[1].textContent, "rgba(33,180,226,1)");
is(allSwatches[2].textContent, "rgba(31,170,217,.5)");
is(allSwatches[3].textContent, "#F06");
is(allSwatches[4].textContent, "red");
}
},
{
name: "background",
value: "-moz-radial-gradient(center 45deg, circle closest-side, orange 0%, red 100%)",
test: fragment => {
is(fragment.querySelectorAll("*").length, 2);
let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS);
is(allSwatches.length, 2);
is(allSwatches[0].textContent, "orange");
is(allSwatches[1].textContent, "red");
}
}
];
let parser = new OutputParser();
for (let i = 0; i < testData.length; i ++) {
let data = testData[i];
info("Output-parser test data " + i + ". {" + data.name + " : " + data.value + ";}");
data.test(parser.parseCssProperty(data.name, data.value, {
colorClass: COLOR_CLASS,
urlClass: URL_CLASS,
defaultColorType: false
}));
}
finish();
}

View File

@ -11,7 +11,7 @@ const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
const HTML_NS = "http://www.w3.org/1999/xhtml";
const MAX_ITERATIONS = 100;
const REGEX_QUOTES = /^".*?"|^".*/;
const REGEX_QUOTES = /^".*?"|^".*|^'.*?'|^'.*/;
const REGEX_URL = /^url\(["']?(.+?)(?::(\d+))?["']?\)/;
const REGEX_WHITESPACE = /^\s+/;
const REGEX_FIRST_WORD_OR_CHAR = /^\w+|^./;
@ -273,12 +273,24 @@ OutputParser.prototype = {
return match.charAt(1).toUpperCase();
});
value = value.replace("!important", "");
let div = doc.createElement("div");
div.style[name] = value;
return !!div.style[name];
},
/**
* Tests if a given colorObject output by CssColor is valid for parsing.
* Valid means it's really a color, not any of the CssColor SPECIAL_VALUES
* except transparent
*/
_isValidColor: function(colorObj) {
return colorObj.valid &&
(!colorObj.specialValue || colorObj.specialValue === "transparent");
},
/**
* Append a color to the output.
*
@ -294,7 +306,7 @@ OutputParser.prototype = {
_appendColor: function(color, options={}) {
let colorObj = new colorUtils.CssColor(color);
if (colorObj.valid && !colorObj.specialValue) {
if (this._isValidColor(colorObj)) {
if (options.colorSwatchClass) {
this._appendNode("span", {
class: options.colorSwatchClass,
@ -459,5 +471,5 @@ OutputParser.prototype = {
defaults[item] = overrides[item];
}
return defaults;
},
}
};