Skip to content

Commit

Permalink
Merge 54d9aa5 into e90ea78
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou committed Nov 14, 2019
2 parents e90ea78 + 54d9aa5 commit 16ecf80
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 7 deletions.
28 changes: 27 additions & 1 deletion lib/getCssRulesByProperty.js
@@ -1,5 +1,6 @@
const specificity = require('specificity');
const postcss = require('postcss');
const unquote = require('./unquote');

const counterRendererNames = new Set([
'none',
Expand All @@ -20,6 +21,16 @@ const counterRendererNames = new Set([
'hebrew'
]);

function unwrapNamespace(str) {
if (/^"/.test(str)) {
return unquote(str);
} else if (/^url\(.*\)$/i.test(str)) {
return unquote(str.replace(/^url\((.*)\)$/, '$1'));
} else {
throw new Error(`Cannot parse CSS namespace: ${str}`);
}
}

function getCssRulesByProperty(properties, cssSource, existingPredicates) {
if (!Array.isArray(properties)) {
throw new Error('properties argument must be an array');
Expand All @@ -30,7 +41,15 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
existingPredicates = existingPredicates || {};

const parseTree = postcss.parse(cssSource);

let defaultNamespaceURI = 'http://www.w3.org/1999/xhtml';
parseTree.walkAtRules('namespace', rule => {
const fragments = rule.params.split(/\s+/);
if (fragments.length === 1) {
defaultNamespaceURI = unwrapNamespace(rule.params);
}
// FIXME: Support registering namespace prefixes (fragments.length === 2):
// https://developer.mozilla.org/en-US/docs/Web/CSS/@namespace
});
const rulesByProperty = {
counterStyles: [],
keyframes: []
Expand Down Expand Up @@ -67,6 +86,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
specificityObject.selector === 'bogusselector';
(rulesByProperty[propName] = rulesByProperty[propName] || []).push({
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand Down Expand Up @@ -111,6 +131,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {

rulesByProperty['list-style-type'].push({
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand Down Expand Up @@ -139,6 +160,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {

rulesByProperty['animation-name'].push({
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand Down Expand Up @@ -173,6 +195,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
if (properties.includes('transition-property')) {
rulesByProperty['transition-property'].push({
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand All @@ -187,6 +210,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
if (properties.includes('transition-duration')) {
rulesByProperty['transition-duration'].push({
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand All @@ -207,6 +231,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
specificityObject.selector === 'bogusselector';
const value = {
predicates: getCurrentPredicates(),
namespaceURI: defaultNamespaceURI,
selector: isStyleAttribute
? undefined
: specificityObject.selector.trim(),
Expand Down Expand Up @@ -249,6 +274,7 @@ function getCssRulesByProperty(properties, cssSource, existingPredicates) {
) {
rulesByProperty.keyframes.push({
name: node.params,
namespaceURI: defaultNamespaceURI,
predicates: getCurrentPredicates(),
node
});
Expand Down
12 changes: 7 additions & 5 deletions lib/subsetFonts.js
Expand Up @@ -689,12 +689,14 @@ async function subsetFonts(
seenFontFaceCombos.add(key);
}

const textByProps = fontTracer(
htmlAsset.parseTree,
gatherStylesheetsWithPredicates(htmlAsset.assetGraph, htmlAsset),
memoizedGetCssRulesByProperty,
const textByProps = fontTracer(htmlAsset.parseTree, {
stylesheetsWithPredicates: gatherStylesheetsWithPredicates(
htmlAsset.assetGraph,
htmlAsset
),
getCssRulesByProperty: memoizedGetCssRulesByProperty,
htmlAsset
);
});
if (headlessBrowser) {
textByProps.push(...(await headlessBrowser.tracePage(htmlAsset)));
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -49,7 +49,7 @@
"css-list-helpers": "^2.0.0",
"font-family-papandreou": "^0.2.0-patch1",
"font-snapper": "^1.0.1",
"font-tracer": "^1.1.0",
"font-tracer": "^1.2.1",
"fontkit": "^1.8.0",
"lodash.groupby": "^4.6.0",
"postcss-value-parser": "^4.0.2",
Expand Down
77 changes: 77 additions & 0 deletions test/getCssRulesByProperty.js
Expand Up @@ -45,6 +45,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'red',
Expand All @@ -53,6 +54,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h2',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'blue',
Expand All @@ -74,6 +76,7 @@ describe('getCssRulesByProperty', function() {
{
selector: undefined,
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [1, 0, 0, 0],
prop: 'color',
value: 'red',
Expand All @@ -96,6 +99,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'red',
Expand All @@ -104,6 +108,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'color',
value: 'blue',
Expand All @@ -130,6 +135,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -140,6 +146,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -163,6 +170,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -173,6 +181,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -183,6 +192,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -193,6 +203,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -216,6 +227,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -226,6 +238,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font-size',
value: '10px',
Expand All @@ -234,6 +247,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font',
value: '15px serif',
Expand All @@ -242,6 +256,7 @@ describe('getCssRulesByProperty', function() {
{
selector: 'h1',
predicates: {},
namespaceURI: 'http://www.w3.org/1999/xhtml',
specificityArray: [0, 0, 0, 1],
prop: 'font-size',
value: '20px',
Expand All @@ -251,4 +266,66 @@ describe('getCssRulesByProperty', function() {
});
});
});

describe('with a different default namespace', function() {
describe('given as a quoted string', function() {
it('should annotate the style rules with the default namespace', function() {
const result = getRules(
['font-size'],
'@namespace "foo"; h1 { font-size: 20px }',
[]
);

expect(result, 'to satisfy', {
'font-size': [
{
selector: 'h1',
namespaceURI: 'foo',
value: '20px'
}
]
});
});
});

describe('given as a url(...)', function() {
it('should annotate the style rules with the default namespace', function() {
const result = getRules(
['font-size'],
'@namespace url(foo); h1 { font-size: 20px }',
[]
);

expect(result, 'to satisfy', {
'font-size': [
{
selector: 'h1',
namespaceURI: 'foo',
value: '20px'
}
]
});
});
});

describe('given as a url("...")', function() {
it('should annotate the style rules with the default namespace', function() {
const result = getRules(
['font-size'],
'@namespace url("foo"); h1 { font-size: 20px }',
[]
);

expect(result, 'to satisfy', {
'font-size': [
{
selector: 'h1',
namespaceURI: 'foo',
value: '20px'
}
]
});
});
});
});
});

0 comments on commit 16ecf80

Please sign in to comment.