Bug 1309065 - Be smarter about filling in the client-side css properties db; r=tromey

MozReview-Commit-ID: BOYwveTH1Hy

--HG--
rename : devtools/server/tests/mochitest/test_css-properties_01.html => devtools/server/tests/mochitest/test_css-properties.html
extra : rebase_source : 11ceb980e2d1039b0120e761ee59e9760ee57b00
This commit is contained in:
gtatum@mozilla.com 2016-10-11 20:30:24 +00:00
Родитель 7a44b94e0e
Коммит 3878d6e752
9 изменённых файлов: 631 добавлений и 118 удалений

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

@ -68,17 +68,12 @@ function generateCssProperties() {
let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name);
// In order to maintain any backwards compatible changes when debugging older
// clients, take the definition from the static CSS properties database, and fill it
// in with the most recent property definition from the server.
const clientDefinition = CSS_PROPERTIES[name] || {};
const serverDefinition = {
properties[name] = {
isInherited: DOMUtils.isInheritedProperty(name),
values,
supports,
subproperties,
};
properties[name] = Object.assign(clientDefinition, serverDefinition);
});
return properties;

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

@ -30,8 +30,7 @@ support-files =
[test_css-logic.html]
[test_css-logic-media-queries.html]
[test_css-logic-specificity.html]
[test_css-properties_01.html]
[test_css-properties_02.html]
[test_css-properties.html]
[test_Debugger.Source.prototype.introductionScript.html]
[test_Debugger.Source.prototype.introductionType.html]
[test_Debugger.Source.prototype.element.html]

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

@ -1,86 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
Bug 1265798 - Replace inIDOMUtils.cssPropertyIsShorthand
-->
<head>
<meta charset="utf-8">
<title>Test CSS Properties Actor</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" src="inspector-helpers.js"></script>
<script type="application/javascript;version=1.8">
window.onload = function() {
const { initCssProperties, getCssProperties } =
require("devtools/shared/fronts/css-properties");
const { CSS_PROPERTIES_DB } = require("devtools/shared/css/properties-db");
function promiseAttachUrl (url) {
return new Promise((resolve, reject) => {
attachURL(url, function(err, client, tab, doc) {
if (err) {
return reject(err);
}
resolve({client, tab, doc});
});
})
}
addAsyncTest(function* setup() {
let url = document.getElementById("cssProperties").href;
let attachmentA = yield promiseAttachUrl(url);
let attachmentB = yield promiseAttachUrl(url);
let attachmentC = yield promiseAttachUrl(url);
const toolboxMatchingVersions = {
target: {
hasActor: () => true,
client: attachmentA.client,
form: attachmentA.tab,
},
win: window
};
const toolboxDifferentVersions = {
target: {
hasActor: () => true,
client: attachmentB.client,
form: attachmentB.tab
},
win: { navigator: { userAgent:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 " +
"Firefox/30.0" }}
};
// Modify a property on the static database, to differentiate between a generated
// and static CSS properties database.
CSS_PROPERTIES_DB.properties.color.isStatic = true;
yield initCssProperties(toolboxMatchingVersions);
yield initCssProperties(toolboxDifferentVersions);
const cssPropertiesMatching = getCssProperties(toolboxMatchingVersions);
const cssPropertiesDifferent = getCssProperties(toolboxDifferentVersions);
is(cssPropertiesMatching.properties.color.isStatic, true,
"The static CSS database is used when the client and platform versions match.");
isnot(cssPropertiesDifferent.properties.color.isStatic, undefined,
"The generated CSS database is used when the client and platform versions do " +
"not match, but the client is a Firefox.");
delete CSS_PROPERTIES_DB.properties.color.isStatic;
runNextTest();
});
SimpleTest.waitForExplicitFinish();
runNextTest();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265798">Mozilla Bug 1265798</a>
<a id="cssProperties" target="_blank" href="inspector_css-properties.html">Test Document</a>
</body>
</html>

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

@ -13,6 +13,7 @@ import os
import sys
import string
import subprocess
from mozbuild import shellutil
from mozbuild.base import (
MozbuildObject,
MachCommandBase,
@ -39,12 +40,46 @@ class MachCommands(MachCommandBase):
"""Generate the static css properties database for devtools and write it to file."""
print("Re-generating the css properties database...")
preferences = self.get_preferences()
db = self.get_properties_db_from_xpcshell()
self.output_template({
'preferences': stringify(preferences),
'cssProperties': stringify(db['cssProperties']),
'pseudoElements': stringify(db['pseudoElements'])})
def get_preferences(self):
"""Get all of the preferences associated with enabling and disabling a property."""
# Build the command to run the preprocessor on PythonCSSProps.h
headerPath = resolve_path(self.topsrcdir, 'layout/style/PythonCSSProps.h')
cpp = self.substs['CPP']
if not cpp:
print("Unable to find the cpp program. Please do a full, nonartifact")
print("build and try this again.")
sys.exit(1)
if type(cpp) is list:
cmd = cpp
else:
cmd = shellutil.split(cpp)
cmd += shellutil.split(self.substs['ACDEFINES'])
cmd.append(headerPath)
# The preprocessed list takes the following form:
# [ (name, prop, id, flags, pref, proptype), ... ]
preprocessed = eval(subprocess.check_output(cmd))
# Map this list
# (name, prop, id, flags, pref, proptype) => (name, pref)
preferences = [
(name, pref)
for name, prop, id, flags, pref, proptype in preprocessed
if 'CSS_PROPERTY_INTERNAL' not in flags and pref]
return preferences
def get_properties_db_from_xpcshell(self):
"""Generate the static css properties db for devtools from an xpcshell script."""
build = MozbuildObject.from_environment()

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

@ -9377,3 +9377,546 @@ exports.PSEUDO_ELEMENTS = [
":placeholder",
":-moz-color-swatch"
];
/**
* A list of the preferences keys for whether a CSS property is enabled or not. This is
* exposed for testing purposes.
*/
exports.PREFERENCES = [
[
"all",
"layout.css.all-shorthand.enabled"
],
[
"background-blend-mode",
"layout.css.background-blend-mode.enabled"
],
[
"box-decoration-break",
"layout.css.box-decoration-break.enabled"
],
[
"color-adjust",
"layout.css.color-adjust.enabled"
],
[
"contain",
"layout.css.contain.enabled"
],
[
"grid",
"layout.css.grid.enabled"
],
[
"grid-area",
"layout.css.grid.enabled"
],
[
"grid-auto-columns",
"layout.css.grid.enabled"
],
[
"grid-auto-flow",
"layout.css.grid.enabled"
],
[
"grid-auto-rows",
"layout.css.grid.enabled"
],
[
"grid-column",
"layout.css.grid.enabled"
],
[
"grid-column-end",
"layout.css.grid.enabled"
],
[
"grid-column-gap",
"layout.css.grid.enabled"
],
[
"grid-column-start",
"layout.css.grid.enabled"
],
[
"grid-gap",
"layout.css.grid.enabled"
],
[
"grid-row",
"layout.css.grid.enabled"
],
[
"grid-row-end",
"layout.css.grid.enabled"
],
[
"grid-row-gap",
"layout.css.grid.enabled"
],
[
"grid-row-start",
"layout.css.grid.enabled"
],
[
"grid-template",
"layout.css.grid.enabled"
],
[
"grid-template-areas",
"layout.css.grid.enabled"
],
[
"grid-template-columns",
"layout.css.grid.enabled"
],
[
"grid-template-rows",
"layout.css.grid.enabled"
],
[
"initial-letter",
"layout.css.initial-letter.enabled"
],
[
"image-orientation",
"layout.css.image-orientation.enabled"
],
[
"isolation",
"layout.css.isolation.enabled"
],
[
"mix-blend-mode",
"layout.css.mix-blend-mode.enabled"
],
[
"object-fit",
"layout.css.object-fit-and-position.enabled"
],
[
"object-position",
"layout.css.object-fit-and-position.enabled"
],
[
"-moz-osx-font-smoothing",
"layout.css.osx-font-smoothing.enabled"
],
[
"overflow-clip-box",
"layout.css.overflow-clip-box.enabled"
],
[
"paint-order",
"svg.paint-order.enabled"
],
[
"scroll-behavior",
"layout.css.scroll-behavior.property-enabled"
],
[
"scroll-snap-coordinate",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-destination",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-points-x",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-points-y",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type-x",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type-y",
"layout.css.scroll-snap.enabled"
],
[
"shape-outside",
"layout.css.shape-outside.enabled"
],
[
"text-combine-upright",
"layout.css.text-combine-upright.enabled"
],
[
"-webkit-text-fill-color",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-stroke",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-stroke-color",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-stroke-width",
"layout.css.prefixes.webkit"
],
[
"touch-action",
"layout.css.touch_action.enabled"
],
[
"-moz-transform",
"layout.css.prefixes.transforms"
],
[
"transform-box",
"svg.transform-box.enabled"
],
[
"-moz-transform-origin",
"layout.css.prefixes.transforms"
],
[
"-moz-perspective-origin",
"layout.css.prefixes.transforms"
],
[
"-moz-perspective",
"layout.css.prefixes.transforms"
],
[
"-moz-transform-style",
"layout.css.prefixes.transforms"
],
[
"-moz-backface-visibility",
"layout.css.prefixes.transforms"
],
[
"-moz-border-image",
"layout.css.prefixes.border-image"
],
[
"-moz-transition",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-delay",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-duration",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-property",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-timing-function",
"layout.css.prefixes.transitions"
],
[
"-moz-animation",
"layout.css.prefixes.animations"
],
[
"-moz-animation-delay",
"layout.css.prefixes.animations"
],
[
"-moz-animation-direction",
"layout.css.prefixes.animations"
],
[
"-moz-animation-duration",
"layout.css.prefixes.animations"
],
[
"-moz-animation-fill-mode",
"layout.css.prefixes.animations"
],
[
"-moz-animation-iteration-count",
"layout.css.prefixes.animations"
],
[
"-moz-animation-name",
"layout.css.prefixes.animations"
],
[
"-moz-animation-play-state",
"layout.css.prefixes.animations"
],
[
"-moz-animation-timing-function",
"layout.css.prefixes.animations"
],
[
"-moz-box-sizing",
"layout.css.prefixes.box-sizing"
],
[
"-moz-font-feature-settings",
"layout.css.prefixes.font-features"
],
[
"-moz-font-language-override",
"layout.css.prefixes.font-features"
],
[
"-webkit-animation",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-delay",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-direction",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-duration",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-fill-mode",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-iteration-count",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-name",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-play-state",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-timing-function",
"layout.css.prefixes.webkit"
],
[
"-webkit-filter",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-size-adjust",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform-style",
"layout.css.prefixes.webkit"
],
[
"-webkit-backface-visibility",
"layout.css.prefixes.webkit"
],
[
"-webkit-perspective",
"layout.css.prefixes.webkit"
],
[
"-webkit-perspective-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-delay",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-duration",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-property",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-timing-function",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-top-left-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-top-right-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-bottom-left-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-bottom-right-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-background-clip",
"layout.css.prefixes.webkit"
],
[
"-webkit-background-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-background-size",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-image",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-shadow",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-sizing",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-flex",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-ordinal-group",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-orient",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-direction",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-align",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-pack",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-direction",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-wrap",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-flow",
"layout.css.prefixes.webkit"
],
[
"-webkit-order",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-grow",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-shrink",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-basis",
"layout.css.prefixes.webkit"
],
[
"-webkit-justify-content",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-items",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-self",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-content",
"layout.css.prefixes.webkit"
],
[
"-webkit-user-select",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-clip",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-composite",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-image",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-x",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-y",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-repeat",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-size",
"layout.css.prefixes.webkit"
]
];

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

@ -18,3 +18,9 @@ exports.CSS_PROPERTIES = ${cssProperties};
* A list of the pseudo elements.
*/
exports.PSEUDO_ELEMENTS = ${pseudoElements};
/**
* A list of the preferences keys for whether a CSS property is enabled or not. This is
* exposed for testing purposes.
*/
exports.PREFERENCES = ${preferences};

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

@ -234,15 +234,7 @@ const initCssProperties = Task.async(function* (toolbox) {
// Get the list dynamically if the cssProperties actor exists.
if (toolbox.target.hasActor("cssProperties")) {
front = CssPropertiesFront(client, toolbox.target.form);
const serverDB = yield front.getCSSDatabase();
// Ensure the database was returned in a format that is understood.
// Older versions of the protocol could return a blank database.
if (!serverDB.properties && !serverDB.margin) {
db = CSS_PROPERTIES_DB;
} else {
db = serverDB;
}
db = yield front.getCSSDatabase();
} else {
// The target does not support this actor, so require a static list of supported
// properties.
@ -294,9 +286,6 @@ function normalizeCssData(db) {
db = { properties: db };
}
// Fill in any missing DB information from the static database.
db = Object.assign({}, CSS_PROPERTIES_DB, db);
let missingSupports = !db.properties.color.supports;
let missingValues = !db.properties.color.values;
let missingSubproperties = !db.properties.background.subproperties;
@ -320,6 +309,10 @@ function normalizeCssData(db) {
db.properties[name].subproperties =
CSS_PROPERTIES_DB.properties[name].subproperties;
}
// Add "isInherited" information to the css properties if it's missing.
if (db.properties.font.isInherited) {
db.properties[name].isInherited = CSS_PROPERTIES_DB.properties[name].isInherited;
}
}
}

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

@ -22,8 +22,9 @@
const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
.getService(Components.interfaces.inIDOMUtils);
const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db");
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");
function run_test() {
const propertiesErrorMessage = "If this assertion fails, then the client side CSS " +
@ -38,7 +39,9 @@ function run_test() {
/**
* Check that the platform and client match for the details on their CSS properties.
* Enumerate each property to aid in debugging.
* Enumerate each property to aid in debugging. Sometimes these properties don't
* completely agree due to differences in preferences. Check the currently set
* preference for that property to see if it's enabled.
*/
const platformProperties = generateCssProperties();
@ -47,17 +50,18 @@ function run_test() {
const clientProperty = CSS_PROPERTIES[propertyName];
const deepEqual = isJsonDeepEqual(platformProperty, clientProperty);
// The "all" property can contain information that can be turned on and off by
// preferences. These values can be different between OSes, so ignore the equality
// check for this property, since this is likely to fail.
if (propertyName === "all") {
continue;
}
if (deepEqual) {
ok(true, `The static database and platform match for "${propertyName}".`);
} else {
const prefMessage = `The static database and platform do not match ` +
`for "${propertyName}".`;
if (getPreference(propertyName) === false) {
ok(true, `${prefMessage} However, there is a preference for disabling this ` +
`property on the current build.`);
} else {
ok(false, `${prefMessage} ${propertiesErrorMessage}`);
}
ok(false, `The static database and platform do not match for ` + `
"${propertyName}". ${propertiesErrorMessage}`);
}
}
@ -75,8 +79,14 @@ function run_test() {
}
mismatches.forEach(propertyName => {
ok(false, `The static database and platform do not agree on the property ` +
`"${propertyName}" ${propertiesErrorMessage}`);
if (getPreference(propertyName) === false) {
ok(true, `The static database and platform do not agree on the property ` +
`"${propertyName}" This is ok because it is currently disabled through ` +
`a preference.`);
} else {
ok(false, `The static database and platform do not agree on the property ` +
`"${propertyName}" ${propertiesErrorMessage}`);
}
});
}
@ -134,3 +144,21 @@ function getKeyMismatches(a, b) {
return aMismatches.concat(bMismatches);
}
/**
* Get the preference value of whether this property is enabled. Returns an empty string
* if no preference exists.
*
* @param {String} propertyName
* @return {Boolean|undefined}
*/
function getPreference(propertyName) {
const preference = PREFERENCES.find(([prefPropertyName, preferenceKey]) => {
return prefPropertyName === propertyName && !!preferenceKey;
});
if (preference) {
return Preferences.get(preference[1]);
}
return undefined;
}