single-file-core 1.5.28 → 1.5.30

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 CHANGED
@@ -1298,6 +1298,7 @@ class Processor {
1298
1298
  options.saveFilenameTemplateData = false;
1299
1299
  options.selected = false;
1300
1300
  options.embeddedImage = null;
1301
+ options.embeddedPdf = null;
1301
1302
  options.url = frameData.baseURI;
1302
1303
  options.windowId = frameWindowId;
1303
1304
  options.content = frameData.content;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.5.28",
3
+ "version": "1.5.30",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",
@@ -43,21 +43,29 @@ const NO_COMPRESSION_EXTENSIONS = [".jpg", ".jpeg", ".png", ".avi", ".apng", ".p
43
43
  const SCRIPT_PATH = "/lib/single-file-zip.min.js";
44
44
  const EXTRA_DATA_TAGS = [
45
45
  ["<noscript>", "</noscript>"],
46
+ ["<noframes>", "</noframes>"],
47
+ ["<noembed>", "</noembed>"],
46
48
  ["<script type=sfz-data>", "</script>"],
49
+ ["<style type=sfz-data>", "</style>"],
50
+ ["<iframe>", "</iframe>"],
47
51
  ["<xmp>", "</xmp>"],
48
52
  ["<plaintext>", "</plaintext>"]
49
53
  ];
50
- const EMBEDDED_IMAGE_DATA_TAGS = [
54
+ const EMBEDDED_DATA_TAGS = [
51
55
  ["<!--", "-->"],
52
56
  ...EXTRA_DATA_TAGS,
53
57
  ];
54
58
  const EXTRA_DATA_REGEXPS = [
55
59
  [/<noscript/i, /<\/noscript>/i],
60
+ [/<noframes/i, /<\/noframes>/i],
61
+ [/<noembed/i, /<\/noembed>/i],
56
62
  [/<script/i, /<\/script>/i],
63
+ [/<style/i, /<\/style>/i],
64
+ [/<iframe/i, /<\/iframe>/i],
57
65
  [/<xmp/i, /<\/xmp>/i],
58
66
  [/<plaintext/i, /<\/plaintext>/i]
59
67
  ];
60
- const EMBEDDED_IMAGE_DATA_REGEXPS = [
68
+ const EMBEDDED_DATA_REGEXPS = [
61
69
  [/<!--/i, /-->/i],
62
70
  ...EXTRA_DATA_REGEXPS,
63
71
  ];
@@ -96,13 +104,17 @@ async function process(pageData, options, lastModDate = new Date()) {
96
104
  await writeData(zipDataWriter.writable, options.embeddedImage.slice(0, PNG_SIGNATURE_LENGTH + PNG_IHDR_LENGTH));
97
105
  if (options.selfExtractingArchive) {
98
106
  const embeddedImageText = embeddedImageData.reduce((text, charCode) => text + String.fromCharCode(charCode), "");
99
- const tagIndex = EMBEDDED_IMAGE_DATA_REGEXPS.findIndex(tests => !embeddedImageText.match(tests[1]));
107
+ const tagIndex = EMBEDDED_DATA_REGEXPS.findIndex(tests => !embeddedImageText.match(tests[1]));
100
108
  let startTag;
101
- [startTag, endTag] = tagIndex == -1 ? ["", ""] : EMBEDDED_IMAGE_DATA_TAGS[tagIndex];
102
- const html = getHTMLStartData(pageData, options) + startTag;
103
- const hmtlData = new Uint8Array([...getLength(html.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x4e, 0x47, 0], ...new TextEncoder().encode(html)]);
109
+ [startTag, endTag] = tagIndex == -1 ? ["", ""] : EMBEDDED_DATA_TAGS[tagIndex];
110
+ const htmlArray = getStartHTMLArray(pageData, options, startTag);
111
+ const hmtlData = new Uint8Array([...getLength(htmlArray.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x4e, 0x47, 0], ...htmlArray]);
104
112
  await writeData(zipDataWriter.writable, hmtlData);
105
113
  await writeData(zipDataWriter.writable, getCRC32(hmtlData, 4));
114
+ } else if (options.embeddedPdf) {
115
+ const data = new Uint8Array([...getLength(options.embeddedPdf.length + 4), ...[0x74, 0x45, 0x58, 0x74, 0x50, 0x44, 0x46, 0], ...new Uint8Array(options.embeddedPdf)]);
116
+ await writeData(zipDataWriter.writable, data);
117
+ await writeData(zipDataWriter.writable, getCRC32(data, 4));
106
118
  }
107
119
  await writeData(zipDataWriter.writable, embeddedImageData);
108
120
  await writeData(zipDataWriter.writable, new Uint8Array(4));
@@ -114,6 +126,8 @@ async function process(pageData, options, lastModDate = new Date()) {
114
126
  }
115
127
  if (options.selfExtractingArchive) {
116
128
  extraDataOffset = await prependHTMLData(pageData, zipDataWriter, script, options);
129
+ } else if (!options.embeddedImage && options.embeddedPdf) {
130
+ await writeData(zipDataWriter.writable, new Uint8Array(options.embeddedPdf));
117
131
  }
118
132
  const zipWriter = new ZipWriter(zipDataWriter, { bufferedWrite: true, keepOrder: false, lastModDate });
119
133
  const startOffset = zipDataWriter.offset;
@@ -225,7 +239,7 @@ function setUint32(data, value) {
225
239
  async function prependHTMLData(pageData, zipDataWriter, script, options) {
226
240
  let pageContent = "";
227
241
  if (!options.embeddedImage) {
228
- pageContent += getHTMLStartData(pageData, options);
242
+ await writeData(zipDataWriter.writable, getStartHTMLArray(pageData, options));
229
243
  }
230
244
  pageContent += "<div id=sfz-wait-message>Please wait...</div>";
231
245
  if (!options.extractDataFromPage) {
@@ -281,17 +295,38 @@ async function prependHTMLData(pageData, zipDataWriter, script, options) {
281
295
  return extraDataOffset;
282
296
  }
283
297
 
284
- function getHTMLStartData(pageData, options) {
285
- let pageContent = "";
298
+ function getStartHTMLArray(pageData, options, startTag = "") {
299
+ let html = "";
286
300
  if (options.includeBOM && !options.extractDataFromPage && !options.embeddedImage) {
287
- pageContent += "\ufeff";
301
+ html += "\ufeff";
288
302
  }
303
+ html += options.embeddedImage ? "" : pageData.doctype;
304
+ html += "<html data-sfz>";
305
+ html += pageData.comment && !options.embeddedImage ? "<!--" + pageData.comment + "-->" : "";
289
306
  const charset = options.extractDataFromPage ? "windows-1252" : "utf-8";
307
+ html += "<meta charset=" + charset + ">";
308
+ const htmlHeadData = getHTMLHeadData(pageData, options);
309
+ let htmlArray;
310
+ if (options.embeddedPdf) {
311
+ const embeddedPdfText = options.embeddedPdf.reduce((text, charCode) => text + String.fromCharCode(charCode), "");
312
+ const pdfTagIndex = EMBEDDED_DATA_REGEXPS.findIndex(tests => !embeddedPdfText.match(tests[1]));
313
+ const [pdfStartTag, pdfEndTag] = pdfTagIndex == -1 ? ["", ""] : EMBEDDED_DATA_TAGS[pdfTagIndex];
314
+ const htmlArray1 = new TextEncoder().encode(html + pdfStartTag);
315
+ const htmlArray2 = new TextEncoder().encode(pdfEndTag + htmlHeadData + startTag);
316
+ htmlArray = new Uint8Array(htmlArray1.length + htmlArray2.length + options.embeddedPdf.length);
317
+ htmlArray.set(htmlArray1);
318
+ htmlArray.set(options.embeddedPdf, htmlArray1.length);
319
+ htmlArray.set(htmlArray2, htmlArray1.length + options.embeddedPdf.length);
320
+ } else {
321
+ htmlArray = new TextEncoder().encode(html + htmlHeadData + startTag);
322
+ }
323
+ return htmlArray;
324
+ }
325
+
326
+ function getHTMLHeadData(pageData, options) {
327
+ let pageContent = "";
290
328
  const title = options.extractDataFromPage ? "" : getPageTitle(pageData);
291
- pageContent += options.embeddedImage ? "" : pageData.doctype;
292
- pageContent += "<html data-sfz>";
293
- pageContent += pageData.comment && !options.embeddedImage ? "<!--" + pageData.comment + "-->" : "";
294
- pageContent += "<meta charset=" + charset + "><title>" + title + "</title>";
329
+ pageContent += "<title>" + title + "</title>";
295
330
  if (options.insertCanonicalLink) {
296
331
  pageContent += "<link rel=canonical href=\"" + options.url + "\">";
297
332
  }
package/single-file.js CHANGED
@@ -119,7 +119,8 @@ async function getPageData(options = {}, initOptions, doc = globalThis.document,
119
119
  insertMetaCSP: options.insertMetaCSP,
120
120
  password: options.password,
121
121
  zipScript: options.zipScript,
122
- embeddedImage: options.embeddedImage
122
+ embeddedImage: options.embeddedImage,
123
+ embeddedPdf: options.embeddedPdf
123
124
  });
124
125
  delete pageData.resources;
125
126
  const reader = new globalThis.FileReader();