Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generated IDL attribute names to CSS properties #611

Merged
merged 3 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/cli/crawl-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ const path = require('path');
const specs = require('browser-specs');
const webidlParser = require('./parse-webidl');
const cssDfnParser = require('../lib/css-grammar-parser');
const fetch = require('../lib/util').fetch;
const requireFromWorkingDirectory = require('../lib/util').requireFromWorkingDirectory;
const completeWithAlternativeUrls = require('../lib/util').completeWithAlternativeUrls;
const isLatestLevelThatPasses = require('../lib/util').isLatestLevelThatPasses;
const processSpecification = require('../lib/util').processSpecification;
const { setupBrowser, teardownBrowser } = require('../lib/util');
const { generateIdlNames, saveIdlNames } = require('./generate-idlnames');
const {
completeWithAlternativeUrls,
fetch,
getGeneratedIDLNamesByCSSProperty,
isLatestLevelThatPasses,
processSpecification,
requireFromWorkingDirectory,
setupBrowser,
teardownBrowser
} = require('../lib/util');

/**
* Flattens an array
Expand Down Expand Up @@ -129,7 +133,7 @@ async function crawlSpec(spec, crawlOptions) {
}
});

// Parse extracted CSS definitions
// Parse extracted CSS definitions and add generated IDL attribute names
Object.entries(result.css.properties || {}).forEach(([prop, dfn]) => {
if (dfn.value || dfn.newValues) {
try {
Expand All @@ -139,6 +143,7 @@ async function crawlSpec(spec, crawlOptions) {
dfn.valueParseError = e.message;
}
}
dfn.styleDeclaration = getGeneratedIDLNamesByCSSProperty(prop);
});
Object.entries(result.css.descriptors || {}).forEach(([desc, dfn]) => {
if (dfn.value) {
Expand Down
54 changes: 53 additions & 1 deletion src/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,57 @@ async function expandCrawlResult(crawl, baseFolder) {
}


/**
* Retrieves the list of IDL attribute names that the CSS property generates
* per the CSSOM spec, see:
* https://drafts.csswg.org/cssom/#ref-for-css-property-to-idl-attribute
*
* @function
* @param {String} property CSS property name
* @return {Array(String)} An array of IDL attribute names, dashed attribute
* first, then camel-cased attribute if different, then webkit-cased attribute
* name if needed
*/
function getGeneratedIDLNamesByCSSProperty(property) {
// Converts a CSS property to an IDL attribute name per the CSSOM spec:
// https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
function cssPropertyToIDLAttribute(property, lowercaseFirst) {
let output = '';
let uppercaseNext = false;
if (lowercaseFirst) {
property = property.substr(1);
}
for (const c of property) {
if (c === '-') {
uppercaseNext = true;
} else if (uppercaseNext) {
uppercaseNext = false;
output += c.toUpperCase();
} else {
output += c;
}
}
return output;
}

// Start with dashed attribute
const res = [property];

// Add camel-cased attribute if different
const camelCased = cssPropertyToIDLAttribute(property, false);
if (camelCased !== property) {
res.push(camelCased);
}

// Add webkit-cased attribute if needed
if (property.startsWith('-webkit-')) {
res.push(cssPropertyToIDLAttribute(property, true));
}

return res;
};


module.exports = {
fetch,
requireFromWorkingDirectory,
Expand All @@ -593,5 +644,6 @@ module.exports = {
processSingleSpecification,
completeWithAlternativeUrls,
isLatestLevelThatPasses,
expandCrawlResult
expandCrawlResult,
getGeneratedIDLNamesByCSSProperty
};
28 changes: 26 additions & 2 deletions tests/util.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const { assert } = require('chai');

const specs = require('browser-specs');
const { isLatestLevelThatPasses } = require('../src/lib/util');
const {
getGeneratedIDLNamesByCSSProperty,
isLatestLevelThatPasses
} = require('../src/lib/util');

describe('isLatestLevelThatPasses', () => {
function getSpecAtLevel(level, flags) {
Expand Down Expand Up @@ -76,4 +79,25 @@ describe('isLatestLevelThatPasses', () => {
(s.seriesComposition === 'full')));
assert.isTrue(isLatestLevelThatPasses(spec, specs, s => s === spec));
});
});
});


describe('getGeneratedIDLNamesByCSSProperty', () => {
it('returns the camel-cased and dashed attribute names for "touch-action"', () => {
assert.deepEqual(
getGeneratedIDLNamesByCSSProperty('touch-action'),
['touch-action', 'touchAction']);
});

it('returns the camel-cased, webkit-cased and dashed attribute names for "-webkit-background-clip"', () => {
assert.deepEqual(
getGeneratedIDLNamesByCSSProperty('-webkit-background-clip'),
['-webkit-background-clip', 'WebkitBackgroundClip', 'webkitBackgroundClip']);
});

it('returns just the name for "display"', () => {
assert.deepEqual(
getGeneratedIDLNamesByCSSProperty('display'),
['display']);
});
});