Skip to content

Commit

Permalink
Add utility for stripping local(...) tokens from a @font-face src pro…
Browse files Browse the repository at this point in the history
…perty
  • Loading branch information
papandreou committed Aug 8, 2018
1 parent 547c2e1 commit 178a830
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
51 changes: 51 additions & 0 deletions lib/util/fonts/stripLocalTokens.js
@@ -0,0 +1,51 @@
const postcssValuesParser = require('postcss-values-parser');

module.exports = function stripLocalTokens(cssValue) {
const tokens = postcssValuesParser(cssValue).tokens;
for (let i = 0; i < tokens.length - 3; i += 1) {
if (
tokens[i][0] === 'word' &&
tokens[i][1].toLowerCase() === 'local' &&
tokens[i + 1][0] === '(' &&
(tokens[i + 2][0] === 'string' || tokens[i + 2][0] === 'word') &&
tokens[i + 3][0] === ')'
) {
let startIndex = i;
let numTokensToRemove = 4;
let commaBefore = false;
let commaAfter = false;
while (
startIndex > 0 &&
['space', 'comma'].includes(tokens[startIndex - 1][0])
) {
if (tokens[startIndex - 1][0] === 'comma') {
commaBefore = true;
}
startIndex -= 1;
numTokensToRemove += 1;
}

while (
startIndex + numTokensToRemove < tokens.length &&
['space', 'comma'].includes(tokens[startIndex + numTokensToRemove][0])
) {
if (tokens[startIndex + numTokensToRemove][0] === 'comma') {
commaAfter = true;
}
numTokensToRemove += 1;
}
if (commaBefore && commaAfter) {
tokens.splice(
startIndex,
numTokensToRemove,
['comma', ','],
['space', ' ']
);
} else {
tokens.splice(startIndex, numTokensToRemove);
}
i = startIndex - 1;
}
}
return tokens.map(token => token[1]).join('');
};
83 changes: 83 additions & 0 deletions test/util/fonts/stripLocalTokens.js
@@ -0,0 +1,83 @@
const expect = require('unexpected').clone();
const stripLocalTokens = require('../../../lib/util/fonts/stripLocalTokens');

expect.addAssertion(
'<string> to come out as <string>',
(expect, subject, value) => {
expect(stripLocalTokens(subject), 'to equal', value);
}
);

describe('stripLocalTokens', function() {
it('should strip a standalone local(...) token', function() {
expect('local(foo)', 'to come out as', '');
});

it('should strip an initial local(...) token and a following comma', function() {
expect('local(foo), url(bar)', 'to come out as', 'url(bar)');
});

it('should strip a local(...) token surrounded by multple other tokens and leave a comma', function() {
expect(
'url(foo), local(bar), url(quux)',
'to come out as',
'url(foo), url(quux)'
);
});

it('should ignore the casing of the word local', function() {
expect(
'url(foo), LOCAL(bar), url(quux)',
'to come out as',
'url(foo), url(quux)'
);
});

it('should support singlequoted strings', function() {
expect(
`url('foo'), local('bar'), url('quux')`,
'to come out as',
"url('foo'), url('quux')"
);
});

it('should support doublequoted strings', function() {
expect(
`url("foo"), local("bar"), url("quux")`,
'to come out as',
'url("foo"), url("quux")'
);
});

it('should strip multiple consecutive local(...) tokens with space between them', function() {
expect(
`url('foo'), local(bar), local(quux), url('baz')`,
'to come out as',
"url('foo'), url('baz')"
);
});

it('should strip multiple consecutive local(...) tokens with space before and after the comma', function() {
expect(
`url('foo') , local(bar) , local(quux) , url('baz')`,
'to come out as',
"url('foo'), url('baz')"
);
});

it('should strip multiple initial, consecutive local(...) tokens', function() {
expect(
`local('Roboto Bold Italic'), local('Roboto-BoldItalic'), url(KFOjCnqEu92Fr1Mu51TzBic6CsI.woff) format('woff')`,
'to come out as',
`url(KFOjCnqEu92Fr1Mu51TzBic6CsI.woff) format('woff')`
);
});

it('should strip multiple consecutive local(...) tokens without space between them', function() {
expect(
`url('foo'), local(bar),local(quux), url('baz')`,
'to come out as',
"url('foo'), url('baz')"
);
});
});

0 comments on commit 178a830

Please sign in to comment.