From d423db1328bd3262580fc40c94396f12389a3c54 Mon Sep 17 00:00:00 2001 From: Ng Guoyou Date: Mon, 20 May 2019 16:33:19 +0800 Subject: [PATCH] Add support for onMessageExternal --- CHANGELOG.md | 2 + src/messaging.js | 184 +++++++++++++++++++++++++++++------------------ 2 files changed, 117 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a19ec0..1c25ea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # 3.5.0 * Make options page support dark mode for Firefox (#112) +* Add unofficially (unsupported) onMessageExternal listener for use with other extensions such as Foxy Gestures (#110) + See wiki at https://github.com/gyng/save-in/wiki/Use-with-Foxy-Gestures # 3.4.1 diff --git a/src/messaging.js b/src/messaging.js index 8cd8146..3219ae9 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -1,5 +1,119 @@ /* eslint-disable no-case-declarations */ +const Messaging = { + // Fires off and does not expect a return value + emit: { + downloaded: state => { + browser.runtime.sendMessage({ + type: MESSAGE_TYPES.DOWNLOADED, + body: { state } + }); + } + }, + + // Returns a Promise + send: { + fetchViaContent: state => + new Promise((resolve, reject) => { + browser.tabs + .query({ + currentWindow: true, + active: true + }) + .then(tabs => { + browser.tabs + .sendMessage(tabs[0].id, { + type: MESSAGE_TYPES.FETCH_VIA_CONTENT, + body: { state } + }) + .then(resolve) + .catch(err => { + if (window.SI_DEBUG) { + console.log(err); // eslint-disable-line + } + reject(err); + }); + }); + }) + }, + + /** + * This is an unofficial, unsupported method for use with external extensions. + * Please use this at your own risk and without any warranty. PRs are welcome. + * + * See: https://github.com/gyng/save-in/wiki/Use-with-Foxy-Gestures + * + * In Foxy Gestures: + * + * const source = data.element.mediaInfo && data.element.mediaInfo.source; + * + * if (source) { + * const payload = { + * type: "DOWNLOAD", + * body: { + * url: source, + * // You can use `comment` for targeting in routing rules + * info: { pageUrl: `${window.location}`, srcUrl: source, comment: "foo" } + * } + * }; + * + * // ID obtained from manifest.json + * browser.runtime.sendMessage("{72d92df5-2aa0-4b06-b807-aa21767545cd}", payload); + * } + */ + handleDownloadMessage: (request, sender, sendResponse) => { + const { url, info, comment } = request.body; + const last = window.lastDownloadState || { + path: new Path.Path("."), + scratch: {}, + info: {} + }; + + const opts = { + currentTab, // Global + now: new Date(), + pageUrl: info.pageUrl, + selectionText: info.selectionText, + sourceUrl: info.srcUrl, + url, + context: DOWNLOAD_TYPES.CLICK + }; + + // Useful for passing in from external extensions + if (comment) { + opts.comment = comment; + } + + const clickState = { + path: last.path || new Path.Path("."), + scratch: last.scratch, + route: last.route, + info: Object.assign({}, last.info, opts, info) + }; + + requestedDownloadFlag = true; + Download.renameAndDownload(clickState); + + sendResponse({ + type: MESSAGE_TYPES.DOWNLOAD, + body: { status: MESSAGE_TYPES.OK } + }); + } +}; + +browser.runtime.onMessageExternal.addListener( + (request, sender, sendResponse) => { + switch (request.type) { + case MESSAGE_TYPES.DOWNLOAD: + Messaging.handleDownloadMessage(request, sender, sendResponse); + break; + default: + // noop + break; + } + } +); + browser.runtime.onMessage.addListener((request, sender, sendResponse) => { switch (request.type) { case MESSAGE_TYPES.OPTIONS: @@ -55,81 +169,13 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { }); break; case MESSAGE_TYPES.DOWNLOAD: - const { url, info } = request.body; - const last = window.lastDownloadState || { - path: new Path.Path("."), - scratch: {}, - info: {} - }; - - const opts = { - currentTab, // Global - now: new Date(), - pageUrl: info.pageUrl, - selectionText: info.selectionText, - sourceUrl: info.srcUrl, - url, - context: DOWNLOAD_TYPES.CLICK - }; - - const clickState = { - path: last.path || new Path.Path("."), - scratch: last.scratch, - route: last.route, - info: Object.assign({}, last.info, opts, info) - }; - - requestedDownloadFlag = true; - Download.renameAndDownload(clickState); - - sendResponse({ - type: MESSAGE_TYPES.DOWNLOAD, - body: { status: MESSAGE_TYPES.OK } - }); + Messaging.handleDownloadMessage(request, sender, sendResponse); break; default: break; // noop } }); -const Messaging = { - // Fires off and does not expect a return value - emit: { - downloaded: state => { - browser.runtime.sendMessage({ - type: MESSAGE_TYPES.DOWNLOADED, - body: { state } - }); - } - }, - - // Returns a Promise - send: { - fetchViaContent: state => - new Promise((resolve, reject) => { - browser.tabs - .query({ - currentWindow: true, - active: true - }) - .then(tabs => { - browser.tabs - .sendMessage(tabs[0].id, { - type: MESSAGE_TYPES.FETCH_VIA_CONTENT, - body: { state } - }) - .then(resolve) - .catch(err => { - if (window.SI_DEBUG) { - console.log(err); // eslint-disable-line - } - reject(err); - }); - }); - }) - } -}; - // Export for testing if (typeof module !== "undefined") { module.exports = Messaging;