css-font-face-src
Version:
A CSS @font-face src property value parser
718 lines (714 loc) • 24.6 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cssFontFaceSrc = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// Generated by peggy v. 2.0.1 (ts-pegjs plugin v. 3.0.0 )
//
// https://peggyjs.org/ https://github.com/metadevpro/ts-pegjs
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = exports.PeggySyntaxError = void 0;
let util = require("../util");
function peg$padEnd(str, targetLength, padString) {
padString = padString || ' ';
if (str.length > targetLength) {
return str;
}
targetLength -= str.length;
padString += padString.repeat(targetLength);
return str + padString.slice(0, targetLength);
}
class PeggySyntaxError extends Error {
static buildMessage(expected, found) {
function hex(ch) {
return ch.charCodeAt(0).toString(16).toUpperCase();
}
function literalEscape(s) {
return s
.replace(/\\/g, "\\\\")
.replace(/"/g, "\\\"")
.replace(/\0/g, "\\0")
.replace(/\t/g, "\\t")
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/[\x00-\x0F]/g, (ch) => "\\x0" + hex(ch))
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch));
}
function classEscape(s) {
return s
.replace(/\\/g, "\\\\")
.replace(/\]/g, "\\]")
.replace(/\^/g, "\\^")
.replace(/-/g, "\\-")
.replace(/\0/g, "\\0")
.replace(/\t/g, "\\t")
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/[\x00-\x0F]/g, (ch) => "\\x0" + hex(ch))
.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch));
}
function describeExpectation(expectation) {
switch (expectation.type) {
case "literal":
return "\"" + literalEscape(expectation.text) + "\"";
case "class":
const escapedParts = expectation.parts.map((part) => {
return Array.isArray(part)
? classEscape(part[0]) + "-" + classEscape(part[1])
: classEscape(part);
});
return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
case "any":
return "any character";
case "end":
return "end of input";
case "other":
return expectation.description;
}
}
function describeExpected(expected1) {
const descriptions = expected1.map(describeExpectation);
let i;
let j;
descriptions.sort();
if (descriptions.length > 0) {
for (i = 1, j = 1; i < descriptions.length; i++) {
if (descriptions[i - 1] !== descriptions[i]) {
descriptions[j] = descriptions[i];
j++;
}
}
descriptions.length = j;
}
switch (descriptions.length) {
case 1:
return descriptions[0];
case 2:
return descriptions[0] + " or " + descriptions[1];
default:
return descriptions.slice(0, -1).join(", ")
+ ", or "
+ descriptions[descriptions.length - 1];
}
}
function describeFound(found1) {
return found1 ? "\"" + literalEscape(found1) + "\"" : "end of input";
}
return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
}
constructor(message, expected, found, location) {
super();
this.message = message;
this.expected = expected;
this.found = found;
this.location = location;
this.name = "PeggySyntaxError";
if (typeof Object.setPrototypeOf === "function") {
Object.setPrototypeOf(this, PeggySyntaxError.prototype);
}
else {
this.__proto__ = PeggySyntaxError.prototype;
}
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, PeggySyntaxError);
}
}
format(sources) {
let str = 'Error: ' + this.message;
if (this.location) {
let src = null;
let k;
for (k = 0; k < sources.length; k++) {
if (sources[k].grammarSource === this.location.source) {
src = sources[k].text.split(/\r\n|\n|\r/g);
break;
}
}
let s = this.location.start;
let loc = this.location.source + ':' + s.line + ':' + s.column;
if (src) {
let e = this.location.end;
let filler = peg$padEnd('', s.line.toString().length, ' ');
let line = src[s.line - 1];
let last = s.line === e.line ? e.column : line.length + 1;
str += '\n --> ' + loc + '\n' + filler + ' |\n' + s.line + ' | ' + line + '\n' + filler + ' | ' +
peg$padEnd('', s.column - 1, ' ') +
peg$padEnd('', last - s.column, '^');
}
else {
str += '\n at ' + loc;
}
}
return str;
}
}
exports.PeggySyntaxError = PeggySyntaxError;
function peg$parse(input, options) {
options = options !== undefined ? options : {};
const peg$FAILED = {};
const peg$source = options.grammarSource;
const peg$startRuleFunctions = { start: peg$parsestart };
let peg$startRuleFunction = peg$parsestart;
const peg$c0 = "";
const peg$c1 = function () { return []; };
const peg$c2 = ",";
const peg$c3 = peg$literalExpectation(",", false);
const peg$c4 = function (x, xs) { return [x].concat(xs); };
const peg$c5 = function (entry) { return [entry]; };
const peg$c6 = function (url, format) { return { url: url, format: format }; };
const peg$c7 = function (url) { return { url: url }; };
const peg$c8 = "url(";
const peg$c9 = peg$literalExpectation("url(", false);
const peg$c10 = ")";
const peg$c11 = peg$literalExpectation(")", false);
const peg$c12 = function (value) { return value; };
const peg$c13 = "format(";
const peg$c14 = peg$literalExpectation("format(", false);
const peg$c15 = "local(";
const peg$c16 = peg$literalExpectation("local(", false);
const peg$c17 = function (value) { return { local: value }; };
const peg$c18 = /^[^)]/;
const peg$c19 = peg$classExpectation([")"], true, false);
const peg$c20 = function (chars) { return util.extractValue(chars.join("")); };
const peg$c21 = /^[ \t\r\n\f]/;
const peg$c22 = peg$classExpectation([" ", "\t", "\r", "\n", "\f"], false, false);
let peg$currPos = 0;
let peg$savedPos = 0;
const peg$posDetailsCache = [{ line: 1, column: 1 }];
let peg$maxFailPos = 0;
let peg$maxFailExpected = [];
let peg$silentFails = 0;
let peg$result;
if (options.startRule !== undefined) {
if (!(options.startRule in peg$startRuleFunctions)) {
throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
}
peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
}
function text() {
return input.substring(peg$savedPos, peg$currPos);
}
function location() {
return peg$computeLocation(peg$savedPos, peg$currPos);
}
function expected(description, location1) {
location1 = location1 !== undefined
? location1
: peg$computeLocation(peg$savedPos, peg$currPos);
throw peg$buildStructuredError([peg$otherExpectation(description)], input.substring(peg$savedPos, peg$currPos), location1);
}
function error(message, location1) {
location1 = location1 !== undefined
? location1
: peg$computeLocation(peg$savedPos, peg$currPos);
throw peg$buildSimpleError(message, location1);
}
function peg$literalExpectation(text1, ignoreCase) {
return { type: "literal", text: text1, ignoreCase: ignoreCase };
}
function peg$classExpectation(parts, inverted, ignoreCase) {
return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
}
function peg$anyExpectation() {
return { type: "any" };
}
function peg$endExpectation() {
return { type: "end" };
}
function peg$otherExpectation(description) {
return { type: "other", description: description };
}
function peg$computePosDetails(pos) {
let details = peg$posDetailsCache[pos];
let p;
if (details) {
return details;
}
else {
p = pos - 1;
while (!peg$posDetailsCache[p]) {
p--;
}
details = peg$posDetailsCache[p];
details = {
line: details.line,
column: details.column
};
while (p < pos) {
if (input.charCodeAt(p) === 10) {
details.line++;
details.column = 1;
}
else {
details.column++;
}
p++;
}
peg$posDetailsCache[pos] = details;
return details;
}
}
function peg$computeLocation(startPos, endPos) {
const startPosDetails = peg$computePosDetails(startPos);
const endPosDetails = peg$computePosDetails(endPos);
return {
source: peg$source,
start: {
offset: startPos,
line: startPosDetails.line,
column: startPosDetails.column
},
end: {
offset: endPos,
line: endPosDetails.line,
column: endPosDetails.column
}
};
}
function peg$fail(expected1) {
if (peg$currPos < peg$maxFailPos) {
return;
}
if (peg$currPos > peg$maxFailPos) {
peg$maxFailPos = peg$currPos;
peg$maxFailExpected = [];
}
peg$maxFailExpected.push(expected1);
}
function peg$buildSimpleError(message, location1) {
return new PeggySyntaxError(message, [], "", location1);
}
function peg$buildStructuredError(expected1, found, location1) {
return new PeggySyntaxError(PeggySyntaxError.buildMessage(expected1, found), expected1, found, location1);
}
function peg$parsestart() {
let s0, s1;
s0 = peg$parsesourceEntries();
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$c0;
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c1();
}
s0 = s1;
}
return s0;
}
function peg$parsesourceEntries() {
let s0, s1, s2, s3, s4, s5;
s0 = peg$currPos;
s1 = peg$parsesourceEntry();
if (s1 !== peg$FAILED) {
s2 = [];
s3 = peg$parsewhitespace();
while (s3 !== peg$FAILED) {
s2.push(s3);
s3 = peg$parsewhitespace();
}
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 44) {
s3 = peg$c2;
peg$currPos++;
}
else {
s3 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c3);
}
}
if (s3 !== peg$FAILED) {
s4 = [];
s5 = peg$parsewhitespace();
while (s5 !== peg$FAILED) {
s4.push(s5);
s5 = peg$parsewhitespace();
}
if (s4 !== peg$FAILED) {
s5 = peg$parsesourceEntries();
if (s5 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c4(s1, s5);
s0 = s1;
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parsesourceEntry();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c5(s1);
}
s0 = s1;
}
return s0;
}
function peg$parsesourceEntry() {
let s0;
s0 = peg$parseurlEntry();
if (s0 === peg$FAILED) {
s0 = peg$parselocalEntry();
}
return s0;
}
function peg$parseurlEntry() {
let s0, s1, s2, s3;
s0 = peg$currPos;
s1 = peg$parseurl();
if (s1 !== peg$FAILED) {
s2 = [];
s3 = peg$parsewhitespace();
while (s3 !== peg$FAILED) {
s2.push(s3);
s3 = peg$parsewhitespace();
}
if (s2 !== peg$FAILED) {
s3 = peg$parseformat();
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c6(s1, s3);
s0 = s1;
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parseurl();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c7(s1);
}
s0 = s1;
}
return s0;
}
function peg$parseurl() {
let s0, s1, s2, s3;
s0 = peg$currPos;
if (input.substr(peg$currPos, 4) === peg$c8) {
s1 = peg$c8;
peg$currPos += 4;
}
else {
s1 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c9);
}
}
if (s1 !== peg$FAILED) {
s2 = peg$parsevalue();
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 41) {
s3 = peg$c10;
peg$currPos++;
}
else {
s3 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c11);
}
}
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c12(s2);
s0 = s1;
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
return s0;
}
function peg$parseformat() {
let s0, s1, s2, s3;
s0 = peg$currPos;
if (input.substr(peg$currPos, 7) === peg$c13) {
s1 = peg$c13;
peg$currPos += 7;
}
else {
s1 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c14);
}
}
if (s1 !== peg$FAILED) {
s2 = peg$parsevalue();
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 41) {
s3 = peg$c10;
peg$currPos++;
}
else {
s3 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c11);
}
}
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c12(s2);
s0 = s1;
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
return s0;
}
function peg$parselocalEntry() {
let s0, s1, s2, s3;
s0 = peg$currPos;
if (input.substr(peg$currPos, 6) === peg$c15) {
s1 = peg$c15;
peg$currPos += 6;
}
else {
s1 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c16);
}
}
if (s1 !== peg$FAILED) {
s2 = peg$parsevalue();
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 41) {
s3 = peg$c10;
peg$currPos++;
}
else {
s3 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c11);
}
}
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c17(s2);
s0 = s1;
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
else {
peg$currPos = s0;
s0 = peg$FAILED;
}
return s0;
}
function peg$parsevalue() {
let s0, s1, s2;
s0 = peg$currPos;
s1 = [];
if (peg$c18.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
}
else {
s2 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c19);
}
}
if (s2 !== peg$FAILED) {
while (s2 !== peg$FAILED) {
s1.push(s2);
if (peg$c18.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
}
else {
s2 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c19);
}
}
}
}
else {
s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c20(s1);
}
s0 = s1;
return s0;
}
function peg$parsewhitespace() {
let s0;
if (peg$c21.test(input.charAt(peg$currPos))) {
s0 = input.charAt(peg$currPos);
peg$currPos++;
}
else {
s0 = peg$FAILED;
if (peg$silentFails === 0) {
peg$fail(peg$c22);
}
}
return s0;
}
peg$result = peg$startRuleFunction();
if (peg$result !== peg$FAILED && peg$currPos === input.length) {
return peg$result;
}
else {
if (peg$result !== peg$FAILED && peg$currPos < input.length) {
peg$fail(peg$endExpectation());
}
throw peg$buildStructuredError(peg$maxFailExpected, peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, peg$maxFailPos < input.length
? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
: peg$computeLocation(peg$maxFailPos, peg$maxFailPos));
}
}
exports.parse = peg$parse;
},{"../util":3}],2:[function(require,module,exports){
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.serialize = exports.parse = exports.SyntaxError = void 0;
const grammar = __importStar(require("./grammar/index"));
class SyntaxError extends Error {
constructor(message, location) {
super(message);
this.name = SyntaxError.name;
this.location = location;
}
}
exports.SyntaxError = SyntaxError;
function parse(fontFaceSourceValue) {
try {
return grammar.parse(fontFaceSourceValue);
}
catch (e) {
const error = e;
throw new SyntaxError(error.message, error.location);
}
}
exports.parse = parse;
function serialize(parsedFontFaceSources) {
return parsedFontFaceSources.map(item => {
let itemStr;
if (item.url) {
itemStr = `url("${item.url}")`;
if (item.format) {
itemStr = `${itemStr} format("${item.format}")`;
}
}
else {
itemStr = `local("${item.local}")`;
}
return itemStr;
}).join(', ');
}
exports.serialize = serialize;
},{"./grammar/index":1}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractValue = void 0;
const WHITESPACE_REGEX = /^[\t\r\f\n ]*(.+?)[\t\r\f\n ]*$/;
const DOUBLE_QUOTE_REGEX = /^"(.*)"$/;
const SINGLE_QUOTE_REGEX = /^'(.*)'$/;
function trimCSSWhitespace(str) {
return str.replace(WHITESPACE_REGEX, "$1");
}
;
function unquoteString(quotedStr) {
if (DOUBLE_QUOTE_REGEX.test(quotedStr)) {
return quotedStr.replace(DOUBLE_QUOTE_REGEX, "$1");
}
if (SINGLE_QUOTE_REGEX.test(quotedStr)) {
return quotedStr.replace(SINGLE_QUOTE_REGEX, "$1");
}
return quotedStr;
}
;
function extractValue(value) {
return unquoteString(trimCSSWhitespace(value));
}
exports.extractValue = extractValue;
;
},{}]},{},[2])(2)
});