ChromeP - fork of Chrome Extension Async
Chromep is a fork of chrome-extension-async by Keith Henry. The difference of chromep is that it does not modify chrome variable. It can be used as a ES6 module:
;
Chromep provides promise wrapper for the Chrome extension API so that it can be used with async/await rather than callbacks.
The Extension API provided by Chrome uses callbacks.
However, Chrome now supports async
and await
keywords.
This library wraps Chrome extension API callback methods in promises, so that they can be called with async
and await
.
Once activated against the Chrome API each callback function gets a Promise
version.
Chrome supports ES2017 syntax, so in extensions we can take full advantage of it.
Installation
npm i chrome-extension-async
TypeScript definitions for the altered API are in chrome-extension-async.d.ts
You must reference chrome-extension-async.js
before your code attempts to use the features of this, as it needs to run across the Chrome API before you call it. <script async>
is not currently supported, but you can use <script defer>
so long as the scripts that use this are also defer
and after it.
Examples
Using the basic Chrome API, let's:
- Get the current active tab
- Execute a script in that tab
- Do something with the first result of the script
; { // Fire off the tabs query and continue in the callback chromeptabs;}
This works, but the nested callbacks are painful to debug and maintain, and they can quickly lead to 'callback hell'.
Instead, with this library, we can use await
:
{ try // Query the tabs and continue once we have the result const tabs = await chrometabs; const activeTab = tabs0; // Execute the injected script and continue once we have the result const results = await chromeptabs; const firstScriptResult = results0; return firstScriptResult; catcherr // Handle errors from chrome.tabs.query, chrome.tabs.executeScript or my code } // If you want to use the same callback you can use Promise syntax too:;
Some callbacks take multiple parameters - in these cases the Promise
will be a combined object:
{ try // API is chrome.runtime.requestUpdateCheck(function (status, details) { ... }); // Instead we use deconstruction-assignment and await const status details = await chromepruntime; ; catcherr // Handle errors from chrome.runtime.requestUpdateCheck or my code }
This also includes a check against chrome.runtime.lastError
, so that you can use try
-catch
to get exceptions thrown from the Chrome API.
Event Listener API
These are not included.
For instance chrome.browserAction.onClicked.addListener
takes a callback function, but executes it every time the event fires.
It is not suitable for a Promise
or async
call.
chrome.tabs.executeAsyncFunction
Execute Injected Scripts Asynchronously With New in v3.2 is chrome.tabs.executeAsyncFunction
, an enhancement to the tabs API that allows a popup or browser/page action to easily execute asynchronous code in a page. This:
- Adds
chrome.runtime.sendMessage
to the injected script to return the result. - Uses
chrome.runtime.onMessage.addListener
to listen for the injected event. - Fires the script with
chrome.tabs.executeScript
. - Wraps the whole thing in a promise that resolves with the final result.
- Adds all the relevant error handling by rejecting the promise.
const scriptToExecute = { // await promises in the tab} try // The await returns the complete result of the function const results = await chromeptabs; // Additional parameters will be passed to scriptToExecute // results now holds the output of the asynchronous code run in the pagecatcherr // Any error either setting up or executing the script // Note that errors from the page will be re-thrown copies
chrome.tabs.executeAsyncFunction
can take a function
, string
, or executeScript
details with the code
property set. The script must be async
or return a Promise
. Details with a file
property are not supported. Scripts that output multiple values are not supported.
Unlike chrome.tabs.executeScript
this can take a function
, but note that it just converts the function to a string to pass it. This means that it must be self contained (it cannot call other user defined functions) and it cannot be native (as many serialise to function foobar() { [native code] }
).
This is held in its own file: execute-async-function.js
:
This relies on a chrome.runtime.onMessage.addListener
subscription, so it will fail if called from within a listener event.
Supported APIs
This only 'promisifies' API functions that use callbacks and are not marked as deprecated. No backwards compatibility is attempted.
Each API is added manually as JS can't spot deprecated or functions with no callbacks itself.
Supported API:
- chrome.alarms
- chrome.bookmarks
- chrome.browserAction
- chrome.browsingData
- chrome.commands
- chrome.contentSettings ContentSetting
- chrome.contextMenus
- chrome.cookies
- chrome.debugger
- chrome.desktopCapture
- chrome.documentScan
- chrome.downloads
- chrome.enterprise.platformKeys
- chrome.extension
- chrome.fileBrowserHandler
- chrome.fileSystemProvider
- chrome.fontSettings
- chrome.gcm
- chrome.history
- chrome.i18n
- chrome.identity
- chrome.idle
- chrome.input.ime
- chrome.management
- chrome.networking.config
- chrome.notifications
- chrome.pageAction
- chrome.pageCapture
- chrome.permissions
- chrome.platformKeys
- chrome.runtime
- chrome.sessions
- chrome.socket
- chrome.sockets.tcp
- chrome.sockets.tcpServer
- chrome.sockets.udp
- chrome.storage StorageArea
- chrome.system.cpu
- chrome.system.memory
- chrome.system.storage
- chrome.tabCapture
- chrome.tabs
- chrome.topSites
- chrome.tts
- chrome.types
- chrome.wallpaper
- chrome.webNavigation
- chrome.windows
Pull requests with additional API gratefully received.
ES5 Build
Note that you can use an ES5
build version of "Chrome Extension Async".
execute-async-function.es5.js
Sometimes your application has a build process that requires you to use 3rd party libraries that published with ES5
code.
For example, create-react-app will break the build and minification process if one of your dependencies is not published as standard ES5
code.
Release Notes
v3.3
v3.3 adds execute-async-function.es5.js
transpiled ES5 version for toolchains that depend on the older JS syntax.
v3.2
v3.2 adds chrome.tabs.executeAsyncFunction
; this is backwards compatible and opt-in functionality.
v3 Changes
v3 introduces a breaking change from v1 and v2: now the original Chrome API is wrapped by an identical method that can be called with either old or new syntax. Callbacks can still be used on the same methods, and will fire before the promise resolves. Any error thrown inside the callback function will cause the promise to reject.
You can use both a callback and await
if you want to work with existing API code, but also want the try
-catch
support:
{ try // Using await means any exception is passed to the catch, even from the callback await chrometabs; catcherr // Handle errors thrown by the API or by the callback }
Older versions added a ...Async
suffix to either the function (2.0.0) or the API class (1.0.0). These are still available on bower (but not npm) and are not maintained.