UNPKG

2.13 kBJavaScriptView Raw
1'use strict';
2
3var R_FONT_FACE = /\@font-face\s*\{([\s\S]*?)\}/g;
4var R_CSS_PAIR = /\s*([a-zA-Z\-]+)\s*:\s*([\s\S]+?)\s*(?:;|$)/g;
5var R_URL_SRC = /^\s*url\(([\s\S]*?)\)(?:\s+format\(([\s\S]*?)\))?\s*$/;
6
7module.exports = function fontsCssLoader(response) {
8 return response.text().then(function (text) {
9 var fonts = parseStylesheet(text);
10 var urls = extractFontURLs(fonts);
11
12 return urls;
13 });
14};
15
16function parseStylesheet(content) {
17 var fonts = [];
18 var face = undefined;
19
20 if (!content) {
21 return fonts;
22 }
23
24 while (face = R_FONT_FACE.exec(content)) {
25 var font = {};
26 var faceData = face[1].trim();
27 var pair = undefined;
28
29 while (pair = R_CSS_PAIR.exec(faceData)) {
30 var prop = pair[1].replace('font-', '');
31 var val = pair[2];
32
33 if (prop === 'unicode-range') {
34 font.unicodeRange = val;
35 } else if (prop === 'feature-settings') {
36 font.featureSettings = val;
37 } else {
38 font[prop] = prop === 'family' ? val.replace(/'|"/g, '') : val;
39 }
40 }
41
42 fonts.push(font);
43 }
44
45 return fonts;
46}
47
48function extractFontURLs(fonts) {
49 var urls = [];
50
51 if (!fonts.length) {
52 return urls;
53 }
54
55 fonts.forEach(function (font) {
56 var sources = parseSources(font);
57 if (!sources) return;
58
59 sources.url.forEach(function (source) {
60 source = parseUrlSource(source);
61
62 if (source[0]) {
63 urls.push(source[0]);
64 }
65 });
66 });
67
68 return urls;
69}
70
71function parseSources(font) {
72 if (!font || !font.src) {
73 return;
74 }
75
76 var sources = font.src.trim().split(/\s*,\s*/);
77
78 var localSources = [];
79 var urlSources = [];
80
81 for (var i = 0, len = sources.length; i < len; i++) {
82 var source = sources[i];
83
84 if (source.indexOf('local') === 0) {
85 localSources.push(source);
86 } else {
87 urlSources.push(source);
88 }
89 }
90
91 return {
92 local: localSources,
93 url: urlSources
94 };
95}
96
97function parseUrlSource(source) {
98 var match = source && source.match(R_URL_SRC);
99
100 if (!match) {
101 return [];
102 }
103
104 return [match[1] && match[1].replace(/'|"/g, ''), match[2] && match[2].replace(/'|"/g, '')];
105}
\No newline at end of file