Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new FirefoxCom.requestAsync method, to simplify the code in web/firefoxcom.js #12802

Merged
merged 2 commits into from
Jan 2, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 98 additions & 110 deletions web/firefoxcom.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,69 +25,78 @@ if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
);
}

const FirefoxCom = (function FirefoxComClosure() {
return {
/**
* Creates an event that the extension is listening for and will
* synchronously respond to.
* NOTE: It is reccomended to use request() instead since one day we may not
* be able to synchronously reply.
* @param {string} action - The action to trigger.
* @param {string} [data] - The data to send.
* @returns {*} The response.
*/
requestSync(action, data) {
const request = document.createTextNode("");
document.documentElement.appendChild(request);

const sender = document.createEvent("CustomEvent");
sender.initCustomEvent("pdf.js.message", true, false, {
action,
data,
sync: true,
});
request.dispatchEvent(sender);
const response = sender.detail.response;
request.remove();

return response;
},

/**
* Creates an event that the extension is listening for and will
* asynchronously respond by calling the callback.
* @param {string} action - The action to trigger.
* @param {string} [data] - The data to send.
* @param {Function} [callback] - Response callback that will be called
* with one data argument.
*/
request(action, data, callback) {
const request = document.createTextNode("");
if (callback) {
request.addEventListener(
"pdf.js.response",
event => {
const response = event.detail.response;
event.target.remove();

callback(response);
},
{ once: true }
);
}
document.documentElement.appendChild(request);

const sender = document.createEvent("CustomEvent");
sender.initCustomEvent("pdf.js.message", true, false, {
action,
data,
sync: false,
responseExpected: !!callback,
});
return request.dispatchEvent(sender);
},
};
})();
class FirefoxCom {
/**
* Creates an event that the extension is listening for and will
* synchronously respond to.
* NOTE: It is recommended to use requestAsync() instead since one day we may
* not be able to synchronously reply.
* @param {string} action - The action to trigger.
* @param {Object|string} [data] - The data to send.
* @returns {*} The response.
*/
static requestSync(action, data) {
const request = document.createTextNode("");
document.documentElement.appendChild(request);

const sender = document.createEvent("CustomEvent");
sender.initCustomEvent("pdf.js.message", true, false, {
action,
data,
sync: true,
});
request.dispatchEvent(sender);
const response = sender.detail.response;
request.remove();

return response;
}

/**
* Creates an event that the extension is listening for and will
* asynchronously respond to.
* @param {string} action - The action to trigger.
* @param {Object|string} [data] - The data to send.
* @returns {Promise<any>} A promise that is resolved with the response data.
*/
static requestAsync(action, data) {
return new Promise(resolve => {
this.request(action, data, resolve);
});
}

/**
* Creates an event that the extension is listening for and will, optionally,
* asynchronously respond to.
* @param {string} action - The action to trigger.
* @param {Object|string} [data] - The data to send.
*/
static request(action, data, callback = null) {
const request = document.createTextNode("");
if (callback) {
request.addEventListener(
"pdf.js.response",
event => {
const response = event.detail.response;
event.target.remove();

callback(response);
},
{ once: true }
);
}
document.documentElement.appendChild(request);

const sender = document.createEvent("CustomEvent");
sender.initCustomEvent("pdf.js.message", true, false, {
action,
data,
sync: false,
responseExpected: !!callback,
});
request.dispatchEvent(sender);
}
}

class DownloadManager {
downloadUrl(url, filename) {
Expand All @@ -101,58 +110,42 @@ class DownloadManager {
const blobUrl = URL.createObjectURL(
new Blob([data], { type: contentType })
);
const onResponse = err => {

FirefoxCom.requestAsync("download", {
blobUrl,
originalUrl: blobUrl,
filename,
isAttachment: true,
}).then(error => {
URL.revokeObjectURL(blobUrl);
};

FirefoxCom.request(
"download",
{
blobUrl,
originalUrl: blobUrl,
filename,
isAttachment: true,
},
onResponse
);
});
}

download(blob, url, filename, sourceEventType = "download") {
const blobUrl = URL.createObjectURL(blob);
const onResponse = err => {
if (err && this.onerror) {
this.onerror(err);

FirefoxCom.requestAsync("download", {
blobUrl,
originalUrl: url,
filename,
sourceEventType,
}).then(error => {
if (error && this.onerror) {
this.onerror(error);
}
URL.revokeObjectURL(blobUrl);
};

FirefoxCom.request(
"download",
{
blobUrl,
originalUrl: url,
filename,
sourceEventType,
},
onResponse
);
});
}
}

class FirefoxPreferences extends BasePreferences {
async _writeToStorage(prefObj) {
return new Promise(function (resolve) {
FirefoxCom.request("setPreferences", prefObj, resolve);
});
return FirefoxCom.requestAsync("setPreferences", prefObj);
}

async _readFromStorage(prefObj) {
return new Promise(function (resolve) {
FirefoxCom.request("getPreferences", prefObj, function (prefStr) {
const readPrefs = JSON.parse(prefStr);
resolve(readPrefs);
});
});
const prefStr = await FirefoxCom.requestAsync("getPreferences", prefObj);
return JSON.parse(prefStr);
}
}

Expand Down Expand Up @@ -258,13 +251,10 @@ class FirefoxComDataRangeTransport extends PDFDataRangeTransport {

class FirefoxScripting {
static async createSandbox(data) {
return new Promise(resolve => {
FirefoxCom.request("createSandbox", data, resolve);
}).then(success => {
if (!success) {
throw new Error("Cannot create sandbox.");
}
});
const success = await FirefoxCom.requestAsync("createSandbox", data);
if (!success) {
throw new Error("Cannot create sandbox.");
}
}

static async dispatchEventInSandbox(event) {
Expand Down Expand Up @@ -347,9 +337,7 @@ class FirefoxExternalServices extends DefaultExternalServices {
}

static async fallback(data) {
return new Promise(resolve => {
FirefoxCom.request("fallback", data, resolve);
});
return FirefoxCom.requestAsync("fallback", data);
}

static reportTelemetry(data) {
Expand Down