diff --git a/.gitmodules b/.gitmodules
index d7fef096be..e8708c5cf6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -29,3 +29,6 @@
[submodule "resource/SingleFileZ"]
path = resource/SingleFileZ
url = https://github.com/gildas-lormeau/SingleFileZ.git
+[submodule "resource/SingleFile"]
+ path = resource/SingleFile
+ url = https://github.com/gildas-lormeau/SingleFile.git
diff --git a/chrome/content/zotero/about.xul b/chrome/content/zotero/about.xul
index 9cdcfd195b..d37faa6c84 100644
--- a/chrome/content/zotero/about.xul
+++ b/chrome/content/zotero/about.xul
@@ -80,7 +80,7 @@
-
+
diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js
index efbc438692..4921bd9578 100644
--- a/chrome/content/zotero/xpcom/attachments.js
+++ b/chrome/content/zotero/xpcom/attachments.js
@@ -349,8 +349,8 @@ Zotero.Attachments = new function(){
}
return attachmentItem;
});
-
-
+
+
/**
* @param {Object} options
* @param {Integer} options.libraryID
@@ -400,14 +400,6 @@ Zotero.Attachments = new function(){
var browser = Zotero.HTTP.loadDocuments(
url,
Zotero.Promise.coroutine(function* () {
- let channel = browser.docShell.currentDocumentChannel;
- if (channel && (channel instanceof Components.interfaces.nsIHttpChannel)) {
- if (channel.responseStatus < 200 || channel.responseStatus >= 400) {
- reject(new Error("Invalid response " + channel.responseStatus + " "
- + channel.responseStatusText + " for '" + url + "'"));
- return false;
- }
- }
try {
let attachmentItem = yield Zotero.Attachments.importFromDocument({
libraryID,
@@ -428,7 +420,9 @@ Zotero.Attachments = new function(){
}
}),
undefined,
- undefined,
+ (e) => {
+ reject(e);
+ },
true,
cookieSandbox
);
@@ -764,8 +758,11 @@ Zotero.Attachments = new function(){
&& Zotero.Translate.DOMWrapper.unwrap(document) instanceof Ci.nsIDOMDocument) {
if (document.defaultView.window) {
// If we have a full hidden browser, use SingleFile
- Zotero.debug('Saving document with saveHTMLDocument()');
- yield Zotero.Utilities.Internal.saveHTMLDocument(document, tmpFile);
+ Zotero.debug('Getting snapshot with snapshotDocument()');
+ let snapshotContent = yield Zotero.Utilities.Internal.snapshotDocument(document);
+
+ // Write main HTML file to disk
+ yield Zotero.File.putContentsAsync(tmpFile, snapshotContent);
}
else {
// Fallback to nsIWebBrowserPersist
@@ -846,22 +843,22 @@ Zotero.Attachments = new function(){
/**
- * Save a snapshot from a page data given by SingleFileZ
+ * Save a snapshot from HTML page content given by SingleFile
*
* @param {Object} options
* @param {String} options.url
- * @param {Object} options.pageData - PageData object from SingleFileZ
+ * @param {Object} options.snapshotContent - HTML content from SingleFile
* @param {Integer} [options.parentItemID]
* @param {Integer[]} [options.collections]
* @param {String} [options.title]
* @param {Object} [options.saveOptions] - Options to pass to Zotero.Item::save()
* @return {Promise} - A promise for the created attachment item
*/
- this.importFromPageData = async (options) => {
- Zotero.debug("Importing attachment item from PageData");
+ this.importFromSnapshotContent = async (options) => {
+ Zotero.debug("Importing attachment item from Snapshot Content");
let url = options.url;
- let pageData = options.pageData;
+ let snapshotContent = options.snapshotContent;
let parentItemID = options.parentItemID;
let collections = options.collections;
let title = options.title;
@@ -879,9 +876,7 @@ Zotero.Attachments = new function(){
try {
let fileName = Zotero.File.truncateFileName(this._getFileNameFromURL(url, contentType), 100);
let tmpFile = OS.Path.join(tmpDirectory, fileName);
- await Zotero.File.putContentsAsync(tmpFile, pageData.content);
-
- await Zotero.Utilities.Internal.saveSingleFileResources(tmpDirectory, pageData.resources, "");
+ await Zotero.File.putContentsAsync(tmpFile, snapshotContent);
// If we're using the title from the document, make some adjustments
// Remove e.g. " - Scaled (-17%)" from end of images saved from links,
diff --git a/chrome/content/zotero/xpcom/connector/server_connector.js b/chrome/content/zotero/xpcom/connector/server_connector.js
index 9df1d4a9cd..179423d6e5 100644
--- a/chrome/content/zotero/xpcom/connector/server_connector.js
+++ b/chrome/content/zotero/xpcom/connector/server_connector.js
@@ -163,8 +163,8 @@ Zotero.Server.Connector.SaveSession = function (id, action, requestData) {
};
-Zotero.Server.Connector.SaveSession.prototype.addPageData = function (pageData) {
- this._requestData.data.pageData = pageData;
+Zotero.Server.Connector.SaveSession.prototype.addSnapshotContent = function (snapshotContent) {
+ this._requestData.data.snapshotContent = snapshotContent;
};
@@ -398,41 +398,6 @@ Zotero.Server.Connector.SaveSession.prototype._updateRecents = function () {
};
-Zotero.Server.Connector.Utilities = {
-
- /**
- * Helper function to insert form data back into SingleFileZ pageData object
- *
- * SingleFileZ creates a single object containing all page data including all
- * resource files. We turn that into a multipart/form-data request for upload
- * and here we insert the form resources back into the SingleFileZ object.
- *
- * @param {Object} resources - Resources object inside SingleFileZ pageData object
- * @param {Object} formData - Multipart form data as a keyed object
- */
- insertSnapshotResources: function (resources, formData) {
- for (let resourceType in resources) {
- for (let resource of resources[resourceType]) {
- // Frames have whole new set of resources
- // We handle these by recursion
- if (resourceType === "frames") {
- Zotero.Server.Connector.Utilities.insertSnapshotResources(resource.resources, formData);
- return;
- }
- // UUIDs are marked by a prefix
- if (resource.content.startsWith('binary-')) {
- // Replace content with actual content indexed in formData
- // by the UUID stored in the content
- resource.content = formData.find(
- element => element.params.name === resource.content
- ).body;
- }
- }
- }
- }
-};
-
-
/**
* Lists all available translators, including code for translators that should be run on every page
*
@@ -901,12 +866,12 @@ Zotero.Server.Connector.SaveItems.prototype = {
}
);
if (session.pendingAttachments.length > 0) {
- // If the session has pageData already (from switching to a `filesEditable` library
+ // If the session has snapshotContent already (from switching to a `filesEditable` library
// then we can save `pendingAttachments` now
- if (data.pageData) {
+ if (data.snapshotContent) {
await itemSaver.saveSnapshotAttachments(
session.pendingAttachments,
- data.pageData,
+ data.snapshotContent,
function (attachment, progress, error) {
session.onProgress(attachment, progress, error);
},
@@ -943,7 +908,7 @@ Zotero.Server.Connector.SaveSingleFile = function () {};
Zotero.Server.Endpoints["/connector/saveSingleFile"] = Zotero.Server.Connector.SaveSingleFile;
Zotero.Server.Connector.SaveSingleFile.prototype = {
supportedMethods: ["POST"],
- supportedDataTypes: ["multipart/form-data"],
+ supportedDataTypes: ["application/json", "multipart/form-data"],
permitBookmarklet: true,
/**
@@ -951,9 +916,22 @@ Zotero.Server.Connector.SaveSingleFile.prototype = {
*/
init: async function (requestData) {
// Retrieve payload
- let data = JSON.parse(Zotero.Utilities.Internal.decodeUTF8(
- requestData.data.find(e => e.params.name === "payload").body
- ));
+ let data = requestData.data;
+
+ // For a brief while the connector used SingleFileZ to save web pages, but we
+ // switched to using SingleFile. If the user is using that connector, the request
+ // will be multipart, which results in an array being passed in. In that case we
+ // want to mark this a legacySnapshot so we can ignore the snapshot content we have
+ // been given and save our own. This results in a double save, which takes a long
+ // time and is not ideal, but hopefully with auto-update of extensions it will be
+ // not be in use for many people for long.
+ let legacySnapshot = false;
+ if (Array.isArray(data)) {
+ legacySnapshot = true;
+ data = JSON.parse(Zotero.Utilities.Internal.decodeUTF8(
+ requestData.data.find(e => e.params.name === "payload").body
+ ));
+ }
if (!data.sessionID) {
return [400, "application/json", JSON.stringify({ error: "SESSION_ID_NOT_PROVIDED" })];
@@ -965,7 +943,57 @@ Zotero.Server.Connector.SaveSingleFile.prototype = {
return [400, "application/json", JSON.stringify({ error: "SESSION_NOT_FOUND" })];
}
- if (!data.pageData) {
+ let snapshotContent;
+ if (legacySnapshot) {
+ // Retrieve our snapshot content inside a hidden browser
+ let cookieSandbox = data.uri
+ ? new Zotero.CookieSandbox(
+ null,
+ data.uri,
+ data.detailedCookies ? "" : data.cookie || "",
+ requestData.headers["User-Agent"]
+ )
+ : null;
+ if (cookieSandbox && data.detailedCookies) {
+ cookieSandbox.addCookiesFromHeader(data.detailedCookies);
+ }
+
+ // Get the URL from the first pending attachment
+ if (!session.pendingAttachments.length) {
+ session.savingDone = true;
+
+ return [200, 'text/plain', 'Legacy snapshot has no pending attachments.'];
+ }
+
+ let url = session.pendingAttachments[0][1].url;
+
+ snapshotContent = await new Zotero.Promise(function (resolve, reject) {
+ var browser = Zotero.HTTP.loadDocuments(
+ url,
+ Zotero.Promise.coroutine(function* () {
+ try {
+ resolve(yield Zotero.Utilities.Internal.snapshotDocument(browser.contentDocument));
+ }
+ catch (e) {
+ Zotero.logError(e);
+ reject(e);
+ }
+ finally {
+ Zotero.Browser.deleteHiddenBrowser(browser);
+ }
+ }),
+ undefined,
+ undefined,
+ true,
+ cookieSandbox
+ );
+ });
+ }
+ else {
+ snapshotContent = data.snapshotContent;
+ }
+
+ if (!snapshotContent) {
// Connector SingleFile has failed so if we re-save attachments (via
// updateSession) then we want to inform saveItems and saveSnapshot that they
// do not need to use pendingAttachments because those have failed.
@@ -977,36 +1005,30 @@ Zotero.Server.Connector.SaveSingleFile.prototype = {
session.savingDone = true;
- return 200;
+ return [200, 'text/plain', 'No snapshot content attached.'];
}
- // Rebuild SingleFile object from multipart/form-data
- Zotero.Server.Connector.Utilities.insertSnapshotResources(
- data.pageData.resources,
- requestData.data
- );
-
// Add to session data, in case `saveSnapshot` is called again by the session
- session.addPageData(data.pageData);
+ session.addSnapshotContent(snapshotContent);
// We do this after adding to session because if we switch to a `filesEditable`
- // library we need to have access to the pageData.
+ // library we need to have access to the snapshotContent.
let { library, collection } = Zotero.Server.Connector.getSaveTarget();
if (!library.filesEditable) {
session.savingDone = true;
- return 200;
+ return [200, 'text/plain', 'Library is not editable.'];
}
// Retrieve all items in the session that need a snapshot
if (session._action === 'saveSnapshot') {
await Zotero.Promise.all(
session.pendingAttachments.map((pendingAttachment) => {
- return Zotero.Attachments.importFromPageData({
+ return Zotero.Attachments.importFromSnapshotContent({
title: data.title,
url: data.url,
parentItemID: pendingAttachment[0],
- pageData: data.pageData
+ snapshotContent
});
})
);
@@ -1038,7 +1060,7 @@ Zotero.Server.Connector.SaveSingleFile.prototype = {
await itemSaver.saveSnapshotAttachments(
session.pendingAttachments,
- data.pageData,
+ snapshotContent,
function (attachment, progress, error) {
session.onProgress(attachment, progress, error);
},
@@ -1171,12 +1193,12 @@ Zotero.Server.Connector.SaveSnapshot.prototype = {
// Save snapshot
if (!data.skipSnapshot) {
// If called from session update, requestData may already have SingleFile data
- if (library.filesEditable && data.pageData) {
- await Zotero.Attachments.importFromPageData({
+ if (library.filesEditable && data.snapshotContent) {
+ await Zotero.Attachments.importFromSnapshotContent({
title: data.title,
url: data.url,
parentItemID: itemID,
- pageData: data.pageData
+ snapshotContent: data.snapshotContent
});
}
// Otherwise, connector will POST SingleFile data at later time
diff --git a/chrome/content/zotero/xpcom/http.js b/chrome/content/zotero/xpcom/http.js
index 3530ca0882..d1b03466c0 100644
--- a/chrome/content/zotero/xpcom/http.js
+++ b/chrome/content/zotero/xpcom/http.js
@@ -1211,6 +1211,21 @@ Zotero.HTTP = new function() {
Zotero.debug("Zotero.HTTP.loadDocuments: " + url + " loaded");
hiddenBrowser.removeEventListener("load", onLoad, true);
hiddenBrowser.zotero_loaded = true;
+
+ let channel = hiddenBrowser.docShell.currentDocumentChannel;
+ if (channel && (channel instanceof Components.interfaces.nsIHttpChannel)) {
+ if (channel.responseStatus < 200 || channel.responseStatus >= 400) {
+ let e = new Error("Invalid response " + channel.responseStatus + " "
+ + channel.responseStatusText + " for '" + url + "'");
+ if (onError) {
+ onError(e);
+ }
+ else {
+ throw e;
+ }
+ return;
+ }
+ }
var maybePromise;
var error;
diff --git a/chrome/content/zotero/xpcom/singlefile.js b/chrome/content/zotero/xpcom/singlefile.js
index 52972369fd..2f163376da 100644
--- a/chrome/content/zotero/xpcom/singlefile.js
+++ b/chrome/content/zotero/xpcom/singlefile.js
@@ -24,8 +24,8 @@
*/
Zotero.SingleFile = {
- // These are defaults from SingleFileZ
- // Located in: zotero/resources/SingleFileZ/extension/core/bg/config.js
+ // These are defaults from SingleFile
+ // Located in: zotero/resources/SingleFile/extension/core/bg/config.js
CONFIG: {
removeHiddenElements: true,
removeUnusedStyles: true,
@@ -84,24 +84,5 @@ Zotero.SingleFile = {
replaceBookmarkURL: true,
saveFavicon: true,
includeBOM: false
- },
-
- runUserScripts: function () {
- let modifiedElements = [];
- window.dispatchEvent(new CustomEvent('single-filez-user-script-init'));
-
- window.addEventListener('single-filez-on-before-capture-request', () => {
- const elements = document.querySelectorAll("img[crossorigin], link[crossorigin]");
- elements.forEach((element) => {
- modifiedElements.push([element, element.getAttribute('crossorigin')]);
- element.removeAttribute('crossorigin');
- });
- });
-
- window.addEventListener('single-filez-on-after-capture-request', () => {
- modifiedElements.forEach(([element, attribute]) => {
- element.setAttribute('crossorigin', attribute);
- });
- });
}
};
diff --git a/chrome/content/zotero/xpcom/translation/translate_item.js b/chrome/content/zotero/xpcom/translation/translate_item.js
index 8e0c0cb6e6..b68fdd87ba 100644
--- a/chrome/content/zotero/xpcom/translation/translate_item.js
+++ b/chrome/content/zotero/xpcom/translation/translate_item.js
@@ -359,13 +359,13 @@ Zotero.Translate.ItemSaver.prototype = {
* Save pending snapshot attachments to disk and library
*
* @param {Array} pendingAttachments - A list of snapshot attachments
- * @param {Object} pageData - Snapshot data from SingleFile
+ * @param {Object} content - Snapshot content from SingleFile
* @param {Function} attachmentCallback - Callback with progress of attachments
*/
- saveSnapshotAttachments: Zotero.Promise.coroutine(function* (pendingAttachments, pageData, attachmentCallback) {
+ saveSnapshotAttachments: Zotero.Promise.coroutine(function* (pendingAttachments, snapshotContent, attachmentCallback) {
for (let [parentItemID, attachment] of pendingAttachments) {
- if (pageData) {
- attachment.pageData = pageData;
+ if (snapshotContent) {
+ attachment.snapshotContent = snapshotContent;
}
yield this._saveAttachment(
attachment,
@@ -899,16 +899,16 @@ Zotero.Translate.ItemSaver.prototype = {
attachmentCallback(attachment, 0);
- // Import from SingleFileZ Page Data
- if (attachment.pageData) {
- Zotero.debug('Importing attachment from SingleFileZ');
+ // Import from SingleFile content
+ if (attachment.snapshotContent) {
+ Zotero.debug('Importing attachment from SingleFile');
- return Zotero.Attachments.importFromPageData({
+ return Zotero.Attachments.importFromSnapshotContent({
libraryID: this._libraryID,
title,
url: attachment.url,
parentItemID,
- pageData: attachment.pageData,
+ snapshotContent: attachment.snapshotContent,
collections: !parentItemID ? this._collections : undefined,
saveOptions: this._saveOptions
});
diff --git a/chrome/content/zotero/xpcom/utilities_internal.js b/chrome/content/zotero/xpcom/utilities_internal.js
index 3a068c4028..71495092d6 100644
--- a/chrome/content/zotero/xpcom/utilities_internal.js
+++ b/chrome/content/zotero/xpcom/utilities_internal.js
@@ -555,9 +555,9 @@ Zotero.Utilities.Internal = {
* extension to save the page as one single file without JavaScript.
*
* @param {Object} document
- * @param {String} destFile - Path for file to write to
+ * @return {String} Snapshot of the page as a single file
*/
- saveHTMLDocument: async function (document, destFile) {
+ snapshotDocument: async function (document) {
// Create sandbox for SingleFile
var view = document.defaultView;
var sandbox = new Components.utils.Sandbox(view, { wantGlobalProperties: ["XMLHttpRequest", "fetch"] });
@@ -569,7 +569,7 @@ Zotero.Utilities.Internal = {
sandbox.Zotero = Components.utils.cloneInto({ HTTP: {} }, sandbox);
sandbox.Zotero.debug = Components.utils.exportFunction(Zotero.debug, sandbox);
// Mostly copied from:
- // resources/SingleFileZ/extension/lib/single-file/fetch/bg/fetch.js::fetchResource
+ // resources/SingleFile/extension/lib/single-file/fetch/bg/fetch.js::fetchResource
sandbox.coFetch = Components.utils.exportFunction(
function (url, onDone) {
const xhrRequest = new XMLHttpRequest();
@@ -604,7 +604,7 @@ Zotero.Utilities.Internal = {
// First we try regular fetch, then proceed with fetch outside sandbox to evade CORS
// restrictions, partly from:
- // resources/SingleFileZ/extension/lib/single-file/fetch/content/content-fetch.js::fetch
+ // resources/SingleFile/extension/lib/single-file/fetch/content/content-fetch.js::fetch
Components.utils.evalInSandbox(
`
ZoteroFetch = async function (url) {
@@ -675,9 +675,9 @@ Zotero.Utilities.Internal = {
Zotero.debug('Injecting single file scripts');
// Run all the scripts of SingleFile scripts in Sandbox
SCRIPTS.forEach(
- script => loadSubScript('resource://zotero/SingleFileZ/' + script, sandbox)
+ script => loadSubScript('resource://zotero/SingleFile/' + script, sandbox)
);
- // Import config and user scripts
+ // Import config
loadSubScript('chrome://zotero/content/xpcom/singlefile.js', sandbox);
// In the client we turn off this auto-zooming feature because it does not work
@@ -691,122 +691,18 @@ Zotero.Utilities.Internal = {
// Use SingleFile to retrieve the html
const pageData = await Components.utils.evalInSandbox(
- `Zotero.SingleFile.runUserScripts();
- this.singlefile.lib.getPageData(
+ `this.singlefile.lib.getPageData(
Zotero.SingleFile.CONFIG,
{ fetch: ZoteroFetch }
);`,
sandbox
);
-
- // Write main HTML file to disk
- await Zotero.File.putContentsAsync(destFile, pageData.content);
-
- // Write resources to disk
- let tmpDirectory = OS.Path.dirname(destFile);
- await this.saveSingleFileResources(tmpDirectory, pageData.resources, "");
-
+
+ // Clone so we can nuke the sandbox
+ let content = pageData.content;
Components.utils.nukeSandbox(sandbox);
- },
-
- /**
- * Save all resources to support SingleFile webpage
- *
- * @param {String} tmpDirectory - Path to location of attachment root
- * @param {Object} resources - Resources from SingleFile pageData object
- * @param {String} prefix - Recursive structure that is initially blank
- */
- saveSingleFileResources: async function (tmpDirectory, resources, prefix) {
- // This looping/recursion structure comes from:
- // SingleFileZ/extension/core/bg/compression.js::addPageResources
- await Zotero.Promise.all(Object.keys(resources).map(
- (resourceType) => {
- return Zotero.Promise.all(resources[resourceType].map(
- async (data) => {
- // Frames have whole new set of resources
- // We handle these by recursion
- if (resourceType === "frames") {
- // Save frame HTML
- await Zotero.Utilities.Internal._saveSingleFileResource(
- data.content,
- tmpDirectory,
- prefix + data.name + "index.html",
- data.binary
- );
- // Save frame resources
- return Zotero.Utilities.Internal.saveSingleFileResources(tmpDirectory, data.resources, prefix + data.name);
- }
- return Zotero.Utilities.Internal._saveSingleFileResource(
- data.content,
- tmpDirectory,
- prefix + data.name,
- data.binary
- );
- }
- ));
- }
- ));
- },
-
-
- /**
- * Save a individual resource from a SingleFile attachment
- *
- * @param {String} resource - The actual content to save to file
- * @param {String} tmpDirectory - Path to location of attachment root
- * @param {String} fileName - Filename for the piece to save under
- * @param {Boolean} binary - Whether the resource string is binary or not
- */
- _saveSingleFileResource: async (resource, tmpDirectory, fileName, binary) => {
- Zotero.debug('Saving resource: ' + fileName);
-
- // Fix slashes on Windows
- fileName = OS.Path.join(...fileName.split('/'));
-
- // This seems weird, but it is because SingleFileZ gives us path filenames
- // (e.g. images/0.png). We want to know if the directory 'images' exists.
- let filePath = OS.Path.join(tmpDirectory, fileName);
- let fileDirectory = OS.Path.dirname(filePath);
-
- // If the directory doesn't exist, make it
- await OS.File.makeDir(fileDirectory, {
- unixMode: 0o755,
- from: tmpDirectory
- });
-
- // Binary string from Connector
- if (typeof resource === "string" && binary) {
- Components.utils.importGlobalProperties(["Blob"]);
- let resourceBlob = new Blob([Zotero.Utilities.Internal._decodeToUint8Array(resource)]);
- await Zotero.File.putContentsAsync(
- filePath,
- resourceBlob
- );
- }
- // Uint8Array from hidden browser sandbox
- else if (Object.prototype.toString.call(resource) === "[object Uint8Array]") {
- let data = Components.utils.waiveXrays(resource);
- // Write to disk
- let is = Components.classes["@mozilla.org/io/arraybuffer-input-stream;1"]
- .createInstance(Components.interfaces.nsIArrayBufferInputStream);
- is.setData(data.buffer, 0, data.byteLength);
- // Write to disk
- await Zotero.File.putContentsAsync(
- filePath,
- is
- );
- }
- else if (resource === undefined) {
- Zotero.debug('Error saving resource: ' + fileName);
- }
- else {
- // Otherwise a normal string
- await Zotero.File.putContentsAsync(
- filePath,
- resource
- );
- }
+ return content;
},
diff --git a/resource/SingleFile b/resource/SingleFile
new file mode 160000
index 0000000000..349b849c55
--- /dev/null
+++ b/resource/SingleFile
@@ -0,0 +1 @@
+Subproject commit 349b849c55be12c8aee37bcf7f5a7d928ee6d963
diff --git a/scripts/babel-worker.js b/scripts/babel-worker.js
index 7bc2363004..8f839e1156 100644
--- a/scripts/babel-worker.js
+++ b/scripts/babel-worker.js
@@ -48,52 +48,27 @@ async function babelWorker(ev) {
.replace('document.body.removeChild(scrollDiv)', 'document.documentElement.removeChild(scrollDiv)');
}
- // Note about Single File helper and util patching:
- // I think this has something to do with the hidden browser being an older version or possibly
- // it is an issue with the sandbox, but it fails to find addEventListener and the fetch does
- // not work even if replace it properly in initOptions.
-
- // Patch single-file-helper
- else if (sourcefile === 'resource/SingleFileZ/lib/single-file/single-file-helper.js') {
+ // Patch content-frame-tree
+ // In Chrome sometimes frames would not have access to the browser object. I could
+ // not replicate this in firefox so is possibly a bug with injected content_scripts
+ // in Chrome that was easier to work around than track down. SingleFile has this
+ // backup mechanism for message so we simply remove the check that implies that if
+ // the top window has the browser object the frame will as well.
+ else if (sourcefile === 'resource/SingleFile/lib/single-file/processors/frame-tree/content/content-frame-tree.js') {
transformed = contents
- .replace('dispatchEvent(', 'window.dispatchEvent(')
- .replace(/addEventListener\(/g, 'window.addEventListener(');
- }
-
- // Patch index.js - This is a SingleFileZ issue. SingleFileZ does not typically use
- // use this code from SingleFile so the namespace is screwed up.
- else if (sourcefile === 'resource/SingleFileZ/lib/single-file/index.js') {
- transformed = contents
- .replace('this.frameTree.content.frames.getAsync',
- 'this.processors.frameTree.content.frames.getAsync')
- .replace('this.lazy.content.loader.process',
- 'this.processors.lazy.content.loader.process');
- }
-
- // Patch single-file-core
- // This style element trick was not working in the hidden browser, so we ignore it
- else if (sourcefile === 'resource/SingleFileZ/lib/single-file/single-file-core.js') {
- transformed = contents.replace('if (workStylesheet.sheet.cssRules.length) {', 'if (true) {');
- }
-
- // Patch content-lazy-loader
- else if (sourcefile === 'resource/SingleFileZ/lib/single-file/processors/lazy/content/content-lazy-loader.js') {
- transformed = contents
- .replace(
- 'if (scrollY <= maxScrollY && scrollX <= maxScrollX)',
- 'if (window.scrollY <= maxScrollY && window.scrollX <= maxScrollX)'
- );
+ .replace('} else if ((!browser || !browser.runtime) && message.method == INIT_RESPONSE_MESSAGE) {',
+ '} else if (message.method == INIT_RESPONSE_MESSAGE) {');
}
// Patch single-file
- else if (sourcefile === 'resource/SingleFileZ/lib/single-file/single-file.js') {
+ else if (sourcefile === 'resource/SingleFile/lib/single-file/single-file.js') {
// We need to add this bit that is done for the cli implementation of singleFile
// See resource/SingleFile/cli/back-ends/common/scripts.js
const WEB_SCRIPTS = [
"lib/single-file/processors/hooks/content/content-hooks-web.js",
"lib/single-file/processors/hooks/content/content-hooks-frames-web.js"
];
- let basePath = 'resource/SingleFileZ/';
+ let basePath = 'resource/SingleFile/';
function readScriptFile(path, basePath) {
return new Promise((resolve, reject) =>
diff --git a/scripts/config.js b/scripts/config.js
index 162b51dd2a..3e9137e986 100644
--- a/scripts/config.js
+++ b/scripts/config.js
@@ -34,15 +34,11 @@ const symlinkFiles = [
'!resource/react-virtualized.js',
// Only include lib directory of singleFile
// Also do a little bit of manipulation similar to React
- '!resource/SingleFileZ/**/*',
- 'resource/SingleFileZ/lib/**/*',
- 'resource/SingleFileZ/extension/lib/single-file/fetch/content/content-fetch.js',
- 'resource/SingleFileZ/extension/lib/single-file/index.js',
- '!resource/SingleFileZ/lib/single-file/single-file-helper.js',
- '!resource/SingleFileZ/lib/single-file/index.js',
- '!resource/SingleFileZ/lib/single-file/single-file-core.js',
- '!resource/SingleFileZ/lib/single-file/processors/lazy/content/content-lazy-loader.js',
- '!resource/SingleFileZ/lib/single-file/single-file.js',
+ '!resource/SingleFile/**/*',
+ 'resource/SingleFile/lib/**/*',
+ 'resource/SingleFile/extension/lib/single-file/fetch/content/content-fetch.js',
+ '!resource/SingleFile/lib/single-file/processors/frame-tree/content/content-frame-tree.js',
+ '!resource/SingleFile/lib/single-file/single-file.js',
'update.rdf'
];
@@ -95,11 +91,8 @@ const jsFiles = [
'resource/react.js',
'resource/react-dom.js',
'resource/react-virtualized.js',
- 'resource/SingleFileZ/lib/single-file/single-file-helper.js',
- 'resource/SingleFileZ/lib/single-file/index.js',
- 'resource/SingleFileZ/lib/single-file/single-file-core.js',
- 'resource/SingleFileZ/lib/single-file/processors/lazy/content/content-lazy-loader.js',
- 'resource/SingleFileZ/lib/single-file/single-file.js'
+ 'resource/SingleFile/lib/single-file/processors/frame-tree/content/content-frame-tree.js',
+ 'resource/SingleFile/lib/single-file/single-file.js'
];
const scssFiles = [
diff --git a/test/tests/attachmentsTest.js b/test/tests/attachmentsTest.js
index 5e297ec353..9ae0289bab 100644
--- a/test/tests/attachmentsTest.js
+++ b/test/tests/attachmentsTest.js
@@ -331,8 +331,8 @@ describe("Zotero.Attachments", function() {
await defer.promise;
});
- it("should save a document with embedded files", function* () {
- var item = yield createDataObject('item');
+ it("should save a document with embedded files", async function () {
+ var item = await createDataObject('item');
var uri = OS.Path.join(getTestDataDirectory().path, "snapshot");
httpd.registerDirectory("/" + prefix + "/", new FileUtils.File(uri));
@@ -340,9 +340,9 @@ describe("Zotero.Attachments", function() {
var deferred = Zotero.Promise.defer();
win.addEventListener('pageshow', () => deferred.resolve());
win.loadURI(testServerPath + "/index.html");
- yield deferred.promise;
+ await deferred.promise;
- var attachment = yield Zotero.Attachments.importFromDocument({
+ var attachment = await Zotero.Attachments.importFromDocument({
document: win.content.document,
parentItemID: item.id
});
@@ -350,31 +350,27 @@ describe("Zotero.Attachments", function() {
assert.equal(attachment.getField('url'), testServerPath + "/index.html");
// Check indexing
- var matches = yield Zotero.Fulltext.findTextInItems([attachment.id], 'share your research');
+ var matches = await Zotero.Fulltext.findTextInItems([attachment.id], 'share your research');
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
- // Check for embedded files
var storageDir = Zotero.Attachments.getStorageDirectory(attachment).path;
- var file = yield attachment.getFilePathAsync();
+ var file = await attachment.getFilePathAsync();
assert.equal(OS.Path.basename(file), 'index.html');
- assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, 'images', '1.gif')));
// Check attachment html file contents
let path = OS.Path.join(storageDir, 'index.html');
- assert.isTrue(yield OS.File.exists(path));
- let contents = yield Zotero.File.getContentsAsync(path);
- assert.isTrue(contents.startsWith("