single-file-core 1.0.0
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/.eslintrc.js +43 -0
- package/LICENSE +661 -0
- package/index.js +86 -0
- package/modules/css-fonts-alt-minifier.js +340 -0
- package/modules/css-fonts-minifier.js +371 -0
- package/modules/css-matched-rules.js +350 -0
- package/modules/css-medias-alt-minifier.js +91 -0
- package/modules/css-rules-minifier.js +146 -0
- package/modules/html-images-alt-minifier.js +109 -0
- package/modules/html-minifier.js +262 -0
- package/modules/html-serializer.js +180 -0
- package/modules/index.js +42 -0
- package/package.json +18 -0
- package/processors/frame-tree/content/content-frame-tree.js +418 -0
- package/processors/hooks/content/content-hooks-frames-web.js +404 -0
- package/processors/hooks/content/content-hooks-frames.js +214 -0
- package/processors/hooks/content/content-hooks-web.js +48 -0
- package/processors/hooks/content/content-hooks.js +39 -0
- package/processors/index.js +34 -0
- package/processors/lazy/content/content-lazy-loader.js +229 -0
- package/single-file-bootstrap.js +33 -0
- package/single-file-core.js +2471 -0
- package/single-file-frames.js +1 -0
- package/single-file-helper.js +557 -0
- package/single-file-util.js +412 -0
- package/vendor/css-font-property-parser.js +343 -0
- package/vendor/css-media-query-parser.js +474 -0
- package/vendor/css-minifier.js +789 -0
- package/vendor/css-tree.js +35 -0
- package/vendor/css-unescape.js +72 -0
- package/vendor/html-srcset-parser.js +339 -0
- package/vendor/index.js +40 -0
- package/vendor/mime-type-parser.js +446 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Author: Gildas Lormeau
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// derived from https://github.com/albell/parse-srcset
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Srcset Parser
|
|
29
|
+
*
|
|
30
|
+
* By Alex Bell | MIT License
|
|
31
|
+
*
|
|
32
|
+
* JS Parser for the string value that appears in markup <img srcset="here">
|
|
33
|
+
*
|
|
34
|
+
* @returns Array [{url: _, d: _, w: _, h:_}, ...]
|
|
35
|
+
*
|
|
36
|
+
* Based super duper closely on the reference algorithm at:
|
|
37
|
+
* https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute
|
|
38
|
+
*
|
|
39
|
+
* Most comments are copied in directly from the spec
|
|
40
|
+
* (except for comments in parens).
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
process
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// 1. Let input be the value passed to this algorithm.
|
|
48
|
+
function process(input) {
|
|
49
|
+
|
|
50
|
+
// UTILITY FUNCTIONS
|
|
51
|
+
|
|
52
|
+
// Manual is faster than RegEx
|
|
53
|
+
// http://bjorn.tipling.com/state-and-regular-expressions-in-javascript
|
|
54
|
+
// http://jsperf.com/whitespace-character/5
|
|
55
|
+
function isSpace(c) {
|
|
56
|
+
return (c === "\u0020" || // space
|
|
57
|
+
c === "\u0009" || // horizontal tab
|
|
58
|
+
c === "\u000A" || // new line
|
|
59
|
+
c === "\u000C" || // form feed
|
|
60
|
+
c === "\u000D"); // carriage return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function collectCharacters(regEx) {
|
|
64
|
+
let chars;
|
|
65
|
+
const match = regEx.exec(input.substring(pos));
|
|
66
|
+
if (match) {
|
|
67
|
+
chars = match[0];
|
|
68
|
+
pos += chars.length;
|
|
69
|
+
return chars;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const inputLength = input.length;
|
|
74
|
+
|
|
75
|
+
// (Don"t use \s, to avoid matching non-breaking space)
|
|
76
|
+
/* eslint-disable no-control-regex */
|
|
77
|
+
const regexLeadingSpaces = /^[ \t\n\r\u000c]+/;
|
|
78
|
+
const regexLeadingCommasOrSpaces = /^[, \t\n\r\u000c]+/;
|
|
79
|
+
const regexLeadingNotSpaces = /^[^ \t\n\r\u000c]+/;
|
|
80
|
+
const regexTrailingCommas = /[,]+$/;
|
|
81
|
+
const regexNonNegativeInteger = /^\d+$/;
|
|
82
|
+
/* eslint-enable no-control-regex */
|
|
83
|
+
|
|
84
|
+
// ( Positive or negative or unsigned integers or decimals, without or without exponents.
|
|
85
|
+
// Must include at least one digit.
|
|
86
|
+
// According to spec tests any decimal point must be followed by a digit.
|
|
87
|
+
// No leading plus sign is allowed.)
|
|
88
|
+
// https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number
|
|
89
|
+
const regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
90
|
+
|
|
91
|
+
let url, descriptors, currentDescriptor, state, c,
|
|
92
|
+
// 2. Let position be a pointer into input, initially pointing at the start
|
|
93
|
+
// of the string.
|
|
94
|
+
pos = 0;
|
|
95
|
+
// 3. Let candidates be an initially empty source set.
|
|
96
|
+
const candidates = [];
|
|
97
|
+
|
|
98
|
+
// 4. Splitting loop: Collect a sequence of characters that are space
|
|
99
|
+
// characters or U+002C COMMA characters. If any U+002C COMMA characters
|
|
100
|
+
// were collected, that is a parse error.
|
|
101
|
+
while (true) { // eslint-disable-line no-constant-condition
|
|
102
|
+
collectCharacters(regexLeadingCommasOrSpaces);
|
|
103
|
+
|
|
104
|
+
// 5. If position is past the end of input, return candidates and abort these steps.
|
|
105
|
+
if (pos >= inputLength) {
|
|
106
|
+
return candidates; // (we"re done, this is the sole return path)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 6. Collect a sequence of characters that are not space characters,
|
|
110
|
+
// and let that be url.
|
|
111
|
+
url = collectCharacters(regexLeadingNotSpaces);
|
|
112
|
+
|
|
113
|
+
// 7. Let descriptors be a new empty list.
|
|
114
|
+
descriptors = [];
|
|
115
|
+
|
|
116
|
+
// 8. If url ends with a U+002C COMMA character (,), follow these substeps:
|
|
117
|
+
// (1). Remove all trailing U+002C COMMA characters from url. If this removed
|
|
118
|
+
// more than one character, that is a parse error.
|
|
119
|
+
if (url.slice(-1) === ",") {
|
|
120
|
+
url = url.replace(regexTrailingCommas, "");
|
|
121
|
+
// (Jump ahead to step 9 to skip tokenization and just push the candidate).
|
|
122
|
+
parseDescriptors();
|
|
123
|
+
|
|
124
|
+
// Otherwise, follow these substeps:
|
|
125
|
+
} else {
|
|
126
|
+
tokenize();
|
|
127
|
+
} // (close else of step 8)
|
|
128
|
+
|
|
129
|
+
// 16. Return to the step labeled splitting loop.
|
|
130
|
+
} // (Close of big while loop.)
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Tokenizes descriptor properties prior to parsing
|
|
134
|
+
* Returns undefined.
|
|
135
|
+
*/
|
|
136
|
+
function tokenize() {
|
|
137
|
+
|
|
138
|
+
// 8.1. Descriptor tokeniser: Skip whitespace
|
|
139
|
+
collectCharacters(regexLeadingSpaces);
|
|
140
|
+
|
|
141
|
+
// 8.2. Let current descriptor be the empty string.
|
|
142
|
+
currentDescriptor = "";
|
|
143
|
+
|
|
144
|
+
// 8.3. Let state be in descriptor.
|
|
145
|
+
state = "in descriptor";
|
|
146
|
+
|
|
147
|
+
while (true) { // eslint-disable-line no-constant-condition
|
|
148
|
+
|
|
149
|
+
// 8.4. Let c be the character at position.
|
|
150
|
+
c = input.charAt(pos);
|
|
151
|
+
|
|
152
|
+
// Do the following depending on the value of state.
|
|
153
|
+
// For the purpose of this step, "EOF" is a special character representing
|
|
154
|
+
// that position is past the end of input.
|
|
155
|
+
|
|
156
|
+
// In descriptor
|
|
157
|
+
if (state === "in descriptor") {
|
|
158
|
+
// Do the following, depending on the value of c:
|
|
159
|
+
|
|
160
|
+
// Space character
|
|
161
|
+
// If current descriptor is not empty, append current descriptor to
|
|
162
|
+
// descriptors and let current descriptor be the empty string.
|
|
163
|
+
// Set state to after descriptor.
|
|
164
|
+
if (isSpace(c)) {
|
|
165
|
+
if (currentDescriptor) {
|
|
166
|
+
descriptors.push(currentDescriptor);
|
|
167
|
+
currentDescriptor = "";
|
|
168
|
+
state = "after descriptor";
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// U+002C COMMA (,)
|
|
172
|
+
// Advance position to the next character in input. If current descriptor
|
|
173
|
+
// is not empty, append current descriptor to descriptors. Jump to the step
|
|
174
|
+
// labeled descriptor parser.
|
|
175
|
+
} else if (c === ",") {
|
|
176
|
+
pos += 1;
|
|
177
|
+
if (currentDescriptor) {
|
|
178
|
+
descriptors.push(currentDescriptor);
|
|
179
|
+
}
|
|
180
|
+
parseDescriptors();
|
|
181
|
+
return;
|
|
182
|
+
|
|
183
|
+
// U+0028 LEFT PARENTHESIS (()
|
|
184
|
+
// Append c to current descriptor. Set state to in parens.
|
|
185
|
+
} else if (c === "\u0028") {
|
|
186
|
+
currentDescriptor = currentDescriptor + c;
|
|
187
|
+
state = "in parens";
|
|
188
|
+
|
|
189
|
+
// EOF
|
|
190
|
+
// If current descriptor is not empty, append current descriptor to
|
|
191
|
+
// descriptors. Jump to the step labeled descriptor parser.
|
|
192
|
+
} else if (c === "") {
|
|
193
|
+
if (currentDescriptor) {
|
|
194
|
+
descriptors.push(currentDescriptor);
|
|
195
|
+
}
|
|
196
|
+
parseDescriptors();
|
|
197
|
+
return;
|
|
198
|
+
|
|
199
|
+
// Anything else
|
|
200
|
+
// Append c to current descriptor.
|
|
201
|
+
} else {
|
|
202
|
+
currentDescriptor = currentDescriptor + c;
|
|
203
|
+
}
|
|
204
|
+
// (end "in descriptor"
|
|
205
|
+
|
|
206
|
+
// In parens
|
|
207
|
+
} else if (state === "in parens") {
|
|
208
|
+
|
|
209
|
+
// U+0029 RIGHT PARENTHESIS ())
|
|
210
|
+
// Append c to current descriptor. Set state to in descriptor.
|
|
211
|
+
if (c === ")") {
|
|
212
|
+
currentDescriptor = currentDescriptor + c;
|
|
213
|
+
state = "in descriptor";
|
|
214
|
+
|
|
215
|
+
// EOF
|
|
216
|
+
// Append current descriptor to descriptors. Jump to the step labeled
|
|
217
|
+
// descriptor parser.
|
|
218
|
+
} else if (c === "") {
|
|
219
|
+
descriptors.push(currentDescriptor);
|
|
220
|
+
parseDescriptors();
|
|
221
|
+
return;
|
|
222
|
+
|
|
223
|
+
// Anything else
|
|
224
|
+
// Append c to current descriptor.
|
|
225
|
+
} else {
|
|
226
|
+
currentDescriptor = currentDescriptor + c;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// After descriptor
|
|
230
|
+
} else if (state === "after descriptor") {
|
|
231
|
+
|
|
232
|
+
// Do the following, depending on the value of c:
|
|
233
|
+
// Space character: Stay in this state.
|
|
234
|
+
if (isSpace(c)) {
|
|
235
|
+
|
|
236
|
+
// EOF: Jump to the step labeled descriptor parser.
|
|
237
|
+
} else if (c === "") {
|
|
238
|
+
parseDescriptors();
|
|
239
|
+
return;
|
|
240
|
+
|
|
241
|
+
// Anything else
|
|
242
|
+
// Set state to in descriptor. Set position to the previous character in input.
|
|
243
|
+
} else {
|
|
244
|
+
state = "in descriptor";
|
|
245
|
+
pos -= 1;
|
|
246
|
+
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Advance position to the next character in input.
|
|
251
|
+
pos += 1;
|
|
252
|
+
|
|
253
|
+
// Repeat this step.
|
|
254
|
+
} // (close while true loop)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Adds descriptor properties to a candidate, pushes to the candidates array
|
|
259
|
+
* @return undefined
|
|
260
|
+
*/
|
|
261
|
+
// Declared outside of the while loop so that it"s only created once.
|
|
262
|
+
function parseDescriptors() {
|
|
263
|
+
|
|
264
|
+
// 9. Descriptor parser: Let error be no.
|
|
265
|
+
let pError = false,
|
|
266
|
+
|
|
267
|
+
// 10. Let width be absent.
|
|
268
|
+
// 11. Let density be absent.
|
|
269
|
+
// 12. Let future-compat-h be absent. (We"re implementing it now as h)
|
|
270
|
+
w, d, h, i,
|
|
271
|
+
desc, lastChar, value, intVal, floatVal;
|
|
272
|
+
const candidate = {};
|
|
273
|
+
|
|
274
|
+
// 13. For each descriptor in descriptors, run the appropriate set of steps
|
|
275
|
+
// from the following list:
|
|
276
|
+
for (i = 0; i < descriptors.length; i++) {
|
|
277
|
+
desc = descriptors[i];
|
|
278
|
+
|
|
279
|
+
lastChar = desc[desc.length - 1];
|
|
280
|
+
value = desc.substring(0, desc.length - 1);
|
|
281
|
+
intVal = parseInt(value, 10);
|
|
282
|
+
floatVal = parseFloat(value);
|
|
283
|
+
|
|
284
|
+
// If the descriptor consists of a valid non-negative integer followed by
|
|
285
|
+
// a U+0077 LATIN SMALL LETTER W character
|
|
286
|
+
if (regexNonNegativeInteger.test(value) && (lastChar === "w")) {
|
|
287
|
+
|
|
288
|
+
// If width and density are not both absent, then let error be yes.
|
|
289
|
+
if (w || d) { pError = true; }
|
|
290
|
+
|
|
291
|
+
// Apply the rules for parsing non-negative integers to the descriptor.
|
|
292
|
+
// If the result is zero, let error be yes.
|
|
293
|
+
// Otherwise, let width be the result.
|
|
294
|
+
if (intVal === 0) { pError = true; } else { w = intVal; }
|
|
295
|
+
|
|
296
|
+
// If the descriptor consists of a valid floating-point number followed by
|
|
297
|
+
// a U+0078 LATIN SMALL LETTER X character
|
|
298
|
+
} else if (regexFloatingPoint.test(value) && (lastChar === "x")) {
|
|
299
|
+
|
|
300
|
+
// If width, density and future-compat-h are not all absent, then let error
|
|
301
|
+
// be yes.
|
|
302
|
+
if (w || d || h) { pError = true; }
|
|
303
|
+
|
|
304
|
+
// Apply the rules for parsing floating-point number values to the descriptor.
|
|
305
|
+
// If the result is less than zero, let error be yes. Otherwise, let density
|
|
306
|
+
// be the result.
|
|
307
|
+
if (floatVal < 0) { pError = true; } else { d = floatVal; }
|
|
308
|
+
|
|
309
|
+
// If the descriptor consists of a valid non-negative integer followed by
|
|
310
|
+
// a U+0068 LATIN SMALL LETTER H character
|
|
311
|
+
} else if (regexNonNegativeInteger.test(value) && (lastChar === "h")) {
|
|
312
|
+
|
|
313
|
+
// If height and density are not both absent, then let error be yes.
|
|
314
|
+
if (h || d) { pError = true; }
|
|
315
|
+
|
|
316
|
+
// Apply the rules for parsing non-negative integers to the descriptor.
|
|
317
|
+
// If the result is zero, let error be yes. Otherwise, let future-compat-h
|
|
318
|
+
// be the result.
|
|
319
|
+
if (intVal === 0) { pError = true; } else { h = intVal; }
|
|
320
|
+
|
|
321
|
+
// Anything else, Let error be yes.
|
|
322
|
+
} else { pError = true; }
|
|
323
|
+
} // (close step 13 for loop)
|
|
324
|
+
|
|
325
|
+
// 15. If error is still no, then append a new image source to candidates whose
|
|
326
|
+
// URL is url, associated with a width width if not absent and a pixel
|
|
327
|
+
// density density if not absent. Otherwise, there is a parse error.
|
|
328
|
+
if (!pError) {
|
|
329
|
+
candidate.url = url;
|
|
330
|
+
if (w) { candidate.w = w; }
|
|
331
|
+
if (d) { candidate.d = d; }
|
|
332
|
+
if (h) { candidate.h = h; }
|
|
333
|
+
candidates.push(candidate);
|
|
334
|
+
} else if (console && console.log) { // eslint-disable-line no-console
|
|
335
|
+
console.log("Invalid srcset descriptor found in \"" + input + "\" at \"" + desc + "\"."); // eslint-disable-line no-console
|
|
336
|
+
}
|
|
337
|
+
} // (close parseDescriptors fn)
|
|
338
|
+
|
|
339
|
+
}
|
package/vendor/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2010-2020 Gildas Lormeau
|
|
3
|
+
* contact : gildas.lormeau <at> gmail.com
|
|
4
|
+
*
|
|
5
|
+
* This file is part of SingleFile.
|
|
6
|
+
*
|
|
7
|
+
* The code in this file is free software: you can redistribute it and/or
|
|
8
|
+
* modify it under the terms of the GNU Affero General Public License
|
|
9
|
+
* (GNU AGPL) as published by the Free Software Foundation, either version 3
|
|
10
|
+
* of the License, or (at your option) any later version.
|
|
11
|
+
*
|
|
12
|
+
* The code in this file is distributed in the hope that it will be useful,
|
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
|
|
15
|
+
* General Public License for more details.
|
|
16
|
+
*
|
|
17
|
+
* As additional permission under GNU AGPL version 3 section 7, you may
|
|
18
|
+
* distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
|
|
19
|
+
* AGPL normally required by section 4, provided you include this license
|
|
20
|
+
* notice and a URL through which recipients can access the Corresponding
|
|
21
|
+
* Source.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import * as fontPropertyParser from "./css-font-property-parser.js";
|
|
25
|
+
import * as mediaQueryParser from "./css-media-query-parser.js";
|
|
26
|
+
import * as cssMinifier from "./css-minifier.js";
|
|
27
|
+
import * as cssTree from "./css-tree.js";
|
|
28
|
+
import * as cssUnescape from "./css-unescape.js";
|
|
29
|
+
import * as srcsetParser from "./html-srcset-parser";
|
|
30
|
+
import { MIMEType } from "./mime-type-parser";
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
fontPropertyParser,
|
|
34
|
+
mediaQueryParser,
|
|
35
|
+
cssMinifier,
|
|
36
|
+
cssTree,
|
|
37
|
+
cssUnescape,
|
|
38
|
+
srcsetParser,
|
|
39
|
+
MIMEType
|
|
40
|
+
};
|