single-file-core 1.5.48 → 1.5.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/index.js +1 -4
- package/core/lib/processor-helper-inline.js +24 -0
- package/core/lib/processor-helper.js +15 -2
- package/core/util.js +2 -5
- package/modules/css-media-query-utils.js +63 -0
- package/modules/css-medias-alt-minifier.js +26 -23
- package/modules/css-rules-minifier.js +904 -79
- package/modules/css-scope-prelude-parser.js +119 -0
- package/modules/css-selector-sanitizer.js +106 -0
- package/modules/css-specificity.js +211 -0
- package/modules/html-serializer.js +14 -9
- package/modules/index.js +0 -2
- package/package.json +2 -2
- package/processors/compression/compression.js +182 -20
- package/processors/hooks/content/content-hooks-frames-web.js +2 -4
- package/processors/hooks/content/content-hooks-frames.js +6 -8
- package/vendor/css-font-property-parser.js +87 -67
- package/vendor/css-tree.js +9 -9
- package/modules/css-matched-rules.js +0 -384
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global Node
|
|
24
|
+
/* global Node */
|
|
25
25
|
|
|
26
26
|
import {
|
|
27
27
|
configure,
|
|
@@ -167,11 +167,12 @@ async function process(pageData, options, lastModDate = new Date()) {
|
|
|
167
167
|
}
|
|
168
168
|
const endTags = options.preventAppendedData || options.embeddedImage ? "" : "</body></html>";
|
|
169
169
|
if (options.extractDataFromPage) {
|
|
170
|
-
const payload =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
]);
|
|
174
|
-
|
|
170
|
+
const payload = new Uint32Array(insertionsCRLF.length + substitutionsLF.length + 2);
|
|
171
|
+
payload.set(new Uint32Array([insertionsCRLF.length]), 0);
|
|
172
|
+
payload.set(new Uint32Array(insertionsCRLF), 1);
|
|
173
|
+
payload.set(new Uint32Array([substitutionsLF.length]), insertionsCRLF.length + 1);
|
|
174
|
+
payload.set(new Uint32Array(substitutionsLF), insertionsCRLF.length + 2);
|
|
175
|
+
extraData = "<sfz-extra-data>" + compress(payload.buffer) + "</sfz-extra-data>";
|
|
175
176
|
if (options.preventAppendedData || extraData.length > 65535 - endTags.length - (options.embeddedImage ? PNG_IEND_LENGTH : 0)) {
|
|
176
177
|
if (!options.extraDataSize) {
|
|
177
178
|
options.extraDataSize = Math.floor(extraData.length * 1.001);
|
|
@@ -365,14 +366,6 @@ function findExtraDataTags(textContent, pageData, options, lastModDate, indexExt
|
|
|
365
366
|
}
|
|
366
367
|
}
|
|
367
368
|
|
|
368
|
-
async function arrayToBase64(data) {
|
|
369
|
-
const fileReader = new FileReader();
|
|
370
|
-
return await new Promise(resolve => {
|
|
371
|
-
fileReader.onload = event => resolve(event.target.result.substring(37));
|
|
372
|
-
fileReader.readAsDataURL(new Blob([new Uint32Array(data)], { type: "application/octet-stream" }));
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
369
|
async function writeData(writable, array) {
|
|
377
370
|
const streamWriter = writable.getWriter();
|
|
378
371
|
await streamWriter.ready;
|
|
@@ -425,7 +418,8 @@ async function addFile(zipWriter, prefixName, data) {
|
|
|
425
418
|
}
|
|
426
419
|
|
|
427
420
|
async function getContent() {
|
|
428
|
-
const
|
|
421
|
+
const BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
422
|
+
const { Blob, XMLHttpRequest, document, stop } = globalThis;
|
|
429
423
|
const characterMap = new Map([
|
|
430
424
|
[65533, 0], [8364, 128], [8218, 130], [402, 131], [8222, 132], [8230, 133], [8224, 134], [8225, 135], [710, 136], [8240, 137],
|
|
431
425
|
[352, 138], [8249, 139], [338, 140], [381, 142], [8216, 145], [8217, 146], [8220, 147], [8221, 148], [8226, 149], [8211, 150],
|
|
@@ -483,9 +477,11 @@ async function getContent() {
|
|
|
483
477
|
const charCode = textContent.charCodeAt(index);
|
|
484
478
|
zipData.push(charCode > 255 ? characterMap.get(charCode) : charCode);
|
|
485
479
|
}
|
|
486
|
-
const
|
|
487
|
-
const
|
|
488
|
-
const
|
|
480
|
+
const payload = new Uint32Array(decompress(zipDataElement.textContent).buffer);
|
|
481
|
+
const insertionsCRLFLength = payload[0];
|
|
482
|
+
const insertionsCRLF = payload.slice(1, 1 + insertionsCRLFLength);
|
|
483
|
+
const substitutionsLFLength = payload[1 + insertionsCRLFLength];
|
|
484
|
+
const substitutionsLF = payload.slice(2 + insertionsCRLFLength, 2 + insertionsCRLFLength + substitutionsLFLength);
|
|
489
485
|
insertionsCRLF.forEach(index => zipData.splice(index, 1, 13, 10));
|
|
490
486
|
substitutionsLF.forEach(index => zipData[index] = 13);
|
|
491
487
|
return new Blob([new Uint8Array(zipData)], { type: "application/octet-stream" });
|
|
@@ -493,7 +489,173 @@ async function getContent() {
|
|
|
493
489
|
throw new Error("Extra zip data data not found");
|
|
494
490
|
}
|
|
495
491
|
|
|
496
|
-
|
|
497
|
-
|
|
492
|
+
function decompress(src) {
|
|
493
|
+
src = base64Decode(src);
|
|
494
|
+
let out = new Uint8Array(1024);
|
|
495
|
+
let outLen = 0;
|
|
496
|
+
for (let i = 0; i < src.length;) {
|
|
497
|
+
const ctrl = src[i++];
|
|
498
|
+
if ((ctrl & 0x80) === 0) {
|
|
499
|
+
const L = ctrl;
|
|
500
|
+
ensure(outLen + L);
|
|
501
|
+
for (let j = 0; j < L && i < src.length; j++) {
|
|
502
|
+
out[outLen++] = src[i++];
|
|
503
|
+
}
|
|
504
|
+
} else {
|
|
505
|
+
const L = (ctrl & 0x7f) + 3;
|
|
506
|
+
const off = (src[i++] << 8) | src[i++];
|
|
507
|
+
const start = outLen - off;
|
|
508
|
+
ensure(outLen + L);
|
|
509
|
+
for (let k = 0; k < L; k++) {
|
|
510
|
+
out[outLen++] = out[start + k];
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return new Uint8Array(out.buffer.slice(0, outLen));
|
|
515
|
+
|
|
516
|
+
function ensure(n) {
|
|
517
|
+
if (out.length < n) {
|
|
518
|
+
let nl = out.length * 2;
|
|
519
|
+
while (nl < n) {
|
|
520
|
+
nl *= 2;
|
|
521
|
+
}
|
|
522
|
+
const nbuf = new Uint8Array(nl);
|
|
523
|
+
nbuf.set(out.subarray(0, outLen));
|
|
524
|
+
out = nbuf;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function base64Decode(b64) {
|
|
530
|
+
b64 = String(b64).replace(/[^A-Za-z0-9+/=]/g, "");
|
|
531
|
+
const len = b64.length;
|
|
532
|
+
const out = [];
|
|
533
|
+
for (let i = 0; i < len; i += 4) {
|
|
534
|
+
const a = BASE64_TABLE.indexOf(b64[i]);
|
|
535
|
+
const b = BASE64_TABLE.indexOf(b64[i + 1]);
|
|
536
|
+
const c = BASE64_TABLE.indexOf(b64[i + 2]);
|
|
537
|
+
const d = BASE64_TABLE.indexOf(b64[i + 3]);
|
|
538
|
+
const n = (a << 18) | (b << 12) | ((c & 63) << 6) | (d & 63);
|
|
539
|
+
out.push((n >> 16) & 0xff);
|
|
540
|
+
if (b64[i + 2] !== "=") {
|
|
541
|
+
out.push((n >> 8) & 0xff);
|
|
542
|
+
}
|
|
543
|
+
if (b64[i + 3] !== "=") {
|
|
544
|
+
out.push(n & 0xff);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return new Uint8Array(out);
|
|
498
548
|
}
|
|
499
549
|
}
|
|
550
|
+
|
|
551
|
+
const BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
552
|
+
|
|
553
|
+
function base64Encode(bytes) {
|
|
554
|
+
let out = "";
|
|
555
|
+
const len = bytes.length;
|
|
556
|
+
let i = 0;
|
|
557
|
+
for (; i + 2 < len; i += 3) {
|
|
558
|
+
const n = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
|
|
559
|
+
out += BASE64_TABLE[(n >> 18) & 63] + BASE64_TABLE[(n >> 12) & 63] + BASE64_TABLE[(n >> 6) & 63] + BASE64_TABLE[n & 63];
|
|
560
|
+
}
|
|
561
|
+
const rem = len - i;
|
|
562
|
+
if (rem === 1) {
|
|
563
|
+
const n = bytes[i] << 16;
|
|
564
|
+
out += BASE64_TABLE[(n >> 18) & 63] + BASE64_TABLE[(n >> 12) & 63] + "==";
|
|
565
|
+
} else if (rem === 2) {
|
|
566
|
+
const n = (bytes[i] << 16) | (bytes[i + 1] << 8);
|
|
567
|
+
out += BASE64_TABLE[(n >> 18) & 63] + BASE64_TABLE[(n >> 12) & 63] + BASE64_TABLE[(n >> 6) & 63] + "=";
|
|
568
|
+
}
|
|
569
|
+
return out;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function compress(input) {
|
|
573
|
+
const src = new Uint8Array(input);
|
|
574
|
+
const N = src.length;
|
|
575
|
+
const out = [];
|
|
576
|
+
const litBuf = [];
|
|
577
|
+
const MAX_OFFSET = 0xffff;
|
|
578
|
+
const MAX_MATCH = 130;
|
|
579
|
+
const MAX_CANDIDATES = 64;
|
|
580
|
+
const map = new Map();
|
|
581
|
+
let i = 0;
|
|
582
|
+
while (i < N) {
|
|
583
|
+
let bestLen = 0, bestOff = 0;
|
|
584
|
+
if (i + 2 < N) {
|
|
585
|
+
const key = (src[i] << 16) | (src[i + 1] << 8) | src[i + 2];
|
|
586
|
+
const cand = map.get(key) || [];
|
|
587
|
+
for (let c = cand.length - 1; c >= 0; c--) {
|
|
588
|
+
const j = cand[c];
|
|
589
|
+
const off = i - j;
|
|
590
|
+
if (off <= 0 || off > MAX_OFFSET) {
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
let k = 0;
|
|
594
|
+
while (k < MAX_MATCH && i + k < N && src[j + k] === src[i + k]) {
|
|
595
|
+
k++;
|
|
596
|
+
}
|
|
597
|
+
if (k > bestLen && k >= 3) {
|
|
598
|
+
bestLen = k; bestOff = off;
|
|
599
|
+
if (bestLen === MAX_MATCH) {
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (bestLen >= 3) {
|
|
607
|
+
if (litBuf.length) {
|
|
608
|
+
flushLiterals();
|
|
609
|
+
}
|
|
610
|
+
let remain = bestLen;
|
|
611
|
+
let produced = 0;
|
|
612
|
+
while (remain > 0) {
|
|
613
|
+
const take = Math.min(remain, MAX_MATCH);
|
|
614
|
+
out.push(0x80 | ((take - 3) & 0x7f));
|
|
615
|
+
out.push((bestOff >> 8) & 0xff);
|
|
616
|
+
out.push(bestOff & 0xff);
|
|
617
|
+
remain -= take;
|
|
618
|
+
produced += take;
|
|
619
|
+
}
|
|
620
|
+
const start = i;
|
|
621
|
+
for (let p = start; p < start + produced; p++) {
|
|
622
|
+
addPos(p);
|
|
623
|
+
}
|
|
624
|
+
i += produced;
|
|
625
|
+
} else {
|
|
626
|
+
litBuf.push(src[i]);
|
|
627
|
+
addPos(i);
|
|
628
|
+
i++;
|
|
629
|
+
if (litBuf.length === 127) {
|
|
630
|
+
flushLiterals();
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (litBuf.length) {
|
|
635
|
+
flushLiterals();
|
|
636
|
+
}
|
|
637
|
+
const u8 = new Uint8Array(out);
|
|
638
|
+
return base64Encode(u8);
|
|
639
|
+
|
|
640
|
+
function flushLiterals() {
|
|
641
|
+
while (litBuf.length) {
|
|
642
|
+
const take = Math.min(127, litBuf.length);
|
|
643
|
+
out.push(take);
|
|
644
|
+
for (let t = 0; t < take; t++) {
|
|
645
|
+
out.push(litBuf.shift());
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function addPos(pos) {
|
|
651
|
+
if (pos + 2 < N) {
|
|
652
|
+
const key = (src[pos] << 16) | (src[pos + 1] << 8) | src[pos + 2];
|
|
653
|
+
const arr = map.get(key) || [];
|
|
654
|
+
arr.push(pos);
|
|
655
|
+
if (arr.length > MAX_CANDIDATES) {
|
|
656
|
+
arr.shift();
|
|
657
|
+
}
|
|
658
|
+
map.set(key, arr);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global window */
|
|
25
|
-
|
|
26
24
|
(globalThis => {
|
|
27
25
|
|
|
28
26
|
const LOAD_DEFERRED_IMAGES_START_EVENT = "single-file-load-deferred-images-start";
|
|
@@ -261,7 +259,7 @@
|
|
|
261
259
|
if (!keepZoomLevel) {
|
|
262
260
|
dispatchResizeEvent();
|
|
263
261
|
const docBoundingRect = scrollingElement.getBoundingClientRect();
|
|
264
|
-
if (window == window.top) {
|
|
262
|
+
if (globalThis.window == globalThis.window.top) {
|
|
265
263
|
[...observers].forEach(([intersectionObserver, observer]) => {
|
|
266
264
|
const getBoundingClientRectDefined = observer.options && observer.options.root && observer.options.root.getBoundingClientRect;
|
|
267
265
|
const rootBoundingRect = getBoundingClientRectDefined && observer.options.root.getBoundingClientRect();
|
|
@@ -446,4 +444,4 @@
|
|
|
446
444
|
}
|
|
447
445
|
}
|
|
448
446
|
|
|
449
|
-
})(typeof globalThis == "object" ? globalThis : window);
|
|
447
|
+
})(typeof globalThis == "object" ? globalThis : globalThis.window);
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global window */
|
|
25
|
-
|
|
26
24
|
const LOAD_DEFERRED_IMAGES_START_EVENT = "single-file-load-deferred-images-start";
|
|
27
25
|
const LOAD_DEFERRED_IMAGES_END_EVENT = "single-file-load-deferred-images-end";
|
|
28
26
|
const LOAD_DEFERRED_IMAGES_KEEP_ZOOM_LEVEL_START_EVENT = "single-file-load-deferred-images-keep-zoom-level-start";
|
|
@@ -51,15 +49,15 @@ const JSON = globalThis.JSON;
|
|
|
51
49
|
const MutationObserver = globalThis.MutationObserver;
|
|
52
50
|
|
|
53
51
|
let fontFaces, worklets;
|
|
54
|
-
if (window[FONT_FACE_PROPERTY_NAME]) {
|
|
55
|
-
fontFaces = window[FONT_FACE_PROPERTY_NAME];
|
|
52
|
+
if (globalThis.window[FONT_FACE_PROPERTY_NAME]) {
|
|
53
|
+
fontFaces = globalThis.window[FONT_FACE_PROPERTY_NAME];
|
|
56
54
|
} else {
|
|
57
|
-
fontFaces = window[FONT_FACE_PROPERTY_NAME] = new Map();
|
|
55
|
+
fontFaces = globalThis.window[FONT_FACE_PROPERTY_NAME] = new Map();
|
|
58
56
|
}
|
|
59
|
-
if (window[WORKLET_PROPERTY_NAME]) {
|
|
60
|
-
worklets = window[WORKLET_PROPERTY_NAME];
|
|
57
|
+
if (globalThis.window[WORKLET_PROPERTY_NAME]) {
|
|
58
|
+
worklets = globalThis.window[WORKLET_PROPERTY_NAME];
|
|
61
59
|
} else {
|
|
62
|
-
worklets = window[WORKLET_PROPERTY_NAME] = new Map();
|
|
60
|
+
worklets = globalThis.window[WORKLET_PROPERTY_NAME] = new Map();
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
init();
|
|
@@ -49,25 +49,24 @@
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
import * as cssTree from "./css-tree.js";
|
|
52
|
-
|
|
53
|
-
const REGEXP_DOUBLE_QUOTES_STRING = /^"(.*?)"$/;
|
|
52
|
+
import { process as cssUnescape } from "./css-unescape.js";
|
|
54
53
|
|
|
55
|
-
const
|
|
54
|
+
const GLOBAL_KEYWORDS = new Set([
|
|
56
55
|
"inherit",
|
|
57
56
|
"initial",
|
|
58
57
|
"unset"
|
|
59
|
-
];
|
|
58
|
+
]);
|
|
60
59
|
|
|
61
|
-
const
|
|
60
|
+
const SYSTEM_FONT_KEYWORDS = new Set([
|
|
62
61
|
"caption",
|
|
63
62
|
"icon",
|
|
64
63
|
"menu",
|
|
65
64
|
"message-box",
|
|
66
65
|
"small-caption",
|
|
67
66
|
"status-bar"
|
|
68
|
-
];
|
|
67
|
+
]);
|
|
69
68
|
|
|
70
|
-
const
|
|
69
|
+
const FONT_WEIGHT_KEYWORDS = new Set([
|
|
71
70
|
"normal",
|
|
72
71
|
"bold",
|
|
73
72
|
"bolder",
|
|
@@ -81,15 +80,20 @@ const fontWeightKeywords = [
|
|
|
81
80
|
"700",
|
|
82
81
|
"800",
|
|
83
82
|
"900"
|
|
84
|
-
];
|
|
83
|
+
]);
|
|
85
84
|
|
|
86
|
-
const
|
|
85
|
+
const FONT_STYLE_KEYWORDS = new Set([
|
|
87
86
|
"normal",
|
|
88
87
|
"italic",
|
|
89
88
|
"oblique"
|
|
90
|
-
];
|
|
89
|
+
]);
|
|
91
90
|
|
|
92
|
-
const
|
|
91
|
+
const FONT_VARIANT_KEYWORDS = new Set([
|
|
92
|
+
"normal",
|
|
93
|
+
"small-caps"
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
const FONT_STRETCH_KEYWORDS = new Set([
|
|
93
97
|
"normal",
|
|
94
98
|
"condensed",
|
|
95
99
|
"semi-condensed",
|
|
@@ -99,7 +103,29 @@ const fontStretchKeywords = [
|
|
|
99
103
|
"semi-expanded",
|
|
100
104
|
"extra-expanded",
|
|
101
105
|
"ultra-expanded"
|
|
102
|
-
];
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
const SIZE_TYPES = new Set([
|
|
109
|
+
"Dimension",
|
|
110
|
+
"Identifier",
|
|
111
|
+
"Percentage",
|
|
112
|
+
"Number",
|
|
113
|
+
"Function",
|
|
114
|
+
"UnaryExpression"
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
const FONT_DESCRIPTOR_KEYS = new Set([
|
|
118
|
+
"style",
|
|
119
|
+
"variant",
|
|
120
|
+
"weight",
|
|
121
|
+
"stretch"
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
const OPERATOR_TYPE = "Operator";
|
|
125
|
+
const IDENTIFIER_TYPE = "Identifier";
|
|
126
|
+
const NORMAL_KEYWORD = "normal";
|
|
127
|
+
const LINE_HEIGHT_SEPARATOR = "/";
|
|
128
|
+
const FAMILY_SEPARATOR = ",";
|
|
103
129
|
|
|
104
130
|
const errorPrefix = "[parse-css-font] ";
|
|
105
131
|
|
|
@@ -109,64 +135,67 @@ export {
|
|
|
109
135
|
|
|
110
136
|
function parse(value) {
|
|
111
137
|
const stringValue = cssTree.generate(value);
|
|
112
|
-
|
|
138
|
+
const stringValueLower = stringValue.toLowerCase();
|
|
139
|
+
if (SYSTEM_FONT_KEYWORDS.has(stringValueLower)) {
|
|
113
140
|
return { system: stringValue };
|
|
114
141
|
}
|
|
142
|
+
if (GLOBAL_KEYWORDS.has(stringValueLower)) {
|
|
143
|
+
return { global: stringValue };
|
|
144
|
+
}
|
|
115
145
|
const tokens = value.children;
|
|
116
|
-
|
|
117
146
|
const font = {
|
|
118
|
-
lineHeight:
|
|
119
|
-
stretch:
|
|
120
|
-
style:
|
|
121
|
-
variant:
|
|
122
|
-
weight:
|
|
147
|
+
lineHeight: NORMAL_KEYWORD,
|
|
148
|
+
stretch: NORMAL_KEYWORD,
|
|
149
|
+
style: NORMAL_KEYWORD,
|
|
150
|
+
variant: NORMAL_KEYWORD,
|
|
151
|
+
weight: NORMAL_KEYWORD,
|
|
123
152
|
};
|
|
124
|
-
|
|
125
|
-
let isLocked = false;
|
|
153
|
+
const seen = { style: false, variant: false, weight: false, stretch: false };
|
|
126
154
|
for (let tokenNode = tokens.head; tokenNode; tokenNode = tokenNode.next) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
155
|
+
const tokenRaw = tokenNode.data.name || tokenNode.data.value || cssTree.generate(tokenNode.data);
|
|
156
|
+
const token = tokenRaw.toLowerCase();
|
|
157
|
+
if (token === NORMAL_KEYWORD) {
|
|
158
|
+
FONT_DESCRIPTOR_KEYS.forEach((prop) => {
|
|
159
|
+
if (!seen[prop]) {
|
|
160
|
+
font[prop] = tokenRaw;
|
|
161
|
+
}
|
|
131
162
|
});
|
|
132
|
-
isLocked = true;
|
|
133
163
|
continue;
|
|
134
164
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
165
|
+
if (FONT_WEIGHT_KEYWORDS.has(token)) {
|
|
166
|
+
if (!seen.weight) {
|
|
167
|
+
font.weight = tokenRaw;
|
|
168
|
+
seen.weight = true;
|
|
139
169
|
}
|
|
140
|
-
font.weight = token;
|
|
141
170
|
continue;
|
|
142
171
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
172
|
+
if (FONT_STYLE_KEYWORDS.has(token)) {
|
|
173
|
+
if (!seen.style) {
|
|
174
|
+
font.style = tokenRaw;
|
|
175
|
+
seen.style = true;
|
|
147
176
|
}
|
|
148
|
-
font.style = token;
|
|
149
177
|
continue;
|
|
150
178
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
179
|
+
if (FONT_VARIANT_KEYWORDS.has(token)) {
|
|
180
|
+
if (!seen.variant) {
|
|
181
|
+
font.variant = tokenRaw;
|
|
182
|
+
seen.variant = true;
|
|
155
183
|
}
|
|
156
|
-
font.stretch = token;
|
|
157
184
|
continue;
|
|
158
185
|
}
|
|
159
|
-
|
|
160
|
-
|
|
186
|
+
if (FONT_STRETCH_KEYWORDS.has(token)) {
|
|
187
|
+
if (!seen.stretch) {
|
|
188
|
+
font.stretch = tokenRaw;
|
|
189
|
+
seen.stretch = true;
|
|
190
|
+
}
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (SIZE_TYPES.has(tokenNode.data.type)) {
|
|
161
194
|
font.size = cssTree.generate(tokenNode.data);
|
|
162
195
|
tokenNode = tokenNode.next;
|
|
163
|
-
if (tokenNode && tokenNode.data.type ==
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
tokenNode = tokenNode.next;
|
|
167
|
-
} else if (tokens.head.data.type == "Operator" && tokens.head.data.value == "/" && tokens.head.next) {
|
|
168
|
-
font.lineHeight = cssTree.generate(tokens.head.next.data);
|
|
169
|
-
tokenNode = tokens.head.next.next;
|
|
196
|
+
if (tokenNode && tokenNode.data.type == OPERATOR_TYPE && tokenNode.data.value == LINE_HEIGHT_SEPARATOR && tokenNode.next) {
|
|
197
|
+
font.lineHeight = cssTree.generate(tokenNode.next.data);
|
|
198
|
+
tokenNode = tokenNode.next.next;
|
|
170
199
|
}
|
|
171
200
|
if (!tokenNode) {
|
|
172
201
|
throw error("Missing required font-family.");
|
|
@@ -174,12 +203,12 @@ function parse(value) {
|
|
|
174
203
|
font.family = [];
|
|
175
204
|
let familyName = "";
|
|
176
205
|
while (tokenNode) {
|
|
177
|
-
while (tokenNode && tokenNode.data.type ==
|
|
206
|
+
while (tokenNode && tokenNode.data.type == OPERATOR_TYPE && tokenNode.data.value == FAMILY_SEPARATOR) {
|
|
178
207
|
tokenNode = tokenNode.next;
|
|
179
208
|
}
|
|
180
209
|
if (tokenNode) {
|
|
181
|
-
if (tokenNode.data.type ==
|
|
182
|
-
while (tokenNode && tokenNode.data.type ==
|
|
210
|
+
if (tokenNode.data.type == IDENTIFIER_TYPE) {
|
|
211
|
+
while (tokenNode && tokenNode.data.type == IDENTIFIER_TYPE) {
|
|
183
212
|
familyName += " " + cssTree.generate(tokenNode.data);
|
|
184
213
|
tokenNode = tokenNode.next;
|
|
185
214
|
}
|
|
@@ -196,15 +225,7 @@ function parse(value) {
|
|
|
196
225
|
}
|
|
197
226
|
return font;
|
|
198
227
|
}
|
|
199
|
-
|
|
200
|
-
if (font.variant !== "normal") {
|
|
201
|
-
throw error("Unknown or unsupported font token: " + font.variant);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (isLocked) {
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
font.variant = token;
|
|
228
|
+
throw error("Unknown or unsupported font token: " + tokenRaw);
|
|
208
229
|
}
|
|
209
230
|
|
|
210
231
|
throw error("Missing required font-size.");
|
|
@@ -215,10 +236,9 @@ function error(message) {
|
|
|
215
236
|
}
|
|
216
237
|
|
|
217
238
|
function removeQuotes(string) {
|
|
218
|
-
if (string
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
string = string.replace(REGEXP_DOUBLE_QUOTES_STRING, "$1");
|
|
239
|
+
if (!string) return string;
|
|
240
|
+
if ((string[0] === "\"" && string[string.length - 1] === "\"") || (string[0] === "'" && string[string.length - 1] === "'")) {
|
|
241
|
+
string = string.slice(1, -1);
|
|
222
242
|
}
|
|
223
|
-
return string.trim();
|
|
243
|
+
return cssUnescape(string).trim();
|
|
224
244
|
}
|