diff --git a/src/css/property-descriptors/__tests__/font-family.ts b/src/css/property-descriptors/__tests__/font-family.ts new file mode 100644 index 0000000..4400bb2 --- /dev/null +++ b/src/css/property-descriptors/__tests__/font-family.ts @@ -0,0 +1,31 @@ +import {deepEqual} from 'assert'; +import {Parser} from '../../syntax/parser'; +import {fontFamily} from '../font-family'; + +const fontFamilyParse = (value: string) => fontFamily.parse(Parser.parseValues(value)); + +describe('property-descriptors', () => { + describe('font-family', () => { + it('sans-serif', () => + deepEqual(fontFamilyParse('sans-serif'), [ + "sans-serif", + ])); + + it('great fonts 40 library', () => + deepEqual(fontFamilyParse('great fonts 40 library'), [ + "'great fonts 40 library'", + ])); + + it('preferred font, "quoted fallback font", font', () => + deepEqual(fontFamilyParse('preferred font, "quoted fallback font", font'), [ + "'preferred font'", + "'quoted fallback font'", + "font" + ])); + + it("'escaping test\\'s font'", () => + deepEqual(fontFamilyParse("'escaping test\\'s font'"), [ + "'escaping test\'s font'", + ])); + }); +}); diff --git a/src/css/property-descriptors/font-family.ts b/src/css/property-descriptors/font-family.ts index b544aee..8ebab4f 100644 --- a/src/css/property-descriptors/font-family.ts +++ b/src/css/property-descriptors/font-family.ts @@ -1,6 +1,6 @@ import {IPropertyListDescriptor, PropertyDescriptorParsingType} from '../IPropertyDescriptor'; import {CSSValue} from '../syntax/parser'; -import {StringValueToken, TokenType} from '../syntax/tokenizer'; +import {TokenType} from '../syntax/tokenizer'; export type FONT_FAMILY = string; @@ -12,9 +12,26 @@ export const fontFamily: IPropertyListDescriptor = { prefix: false, type: PropertyDescriptorParsingType.LIST, parse: (tokens: CSSValue[]) => { - return tokens.filter(isStringToken).map(token => token.value); + const accumulator: string[] = []; + const results: string[] = []; + tokens.forEach(token => { + switch (token.type) { + case TokenType.IDENT_TOKEN: + case TokenType.STRING_TOKEN: + accumulator.push(token.value); + break; + case TokenType.NUMBER_TOKEN: + accumulator.push(token.number.toString()); + break; + case TokenType.COMMA_TOKEN: + results.push(accumulator.join(' ')); + accumulator.length = 0; + break; + } + }); + if (accumulator.length) { + results.push(accumulator.join(' ')); + } + return results.map(result => result.indexOf(' ') === -1 ? result : `'${result}'`); } }; - -const isStringToken = (token: CSSValue): token is StringValueToken => - token.type === TokenType.STRING_TOKEN || token.type === TokenType.IDENT_TOKEN;