Bjorn's Web App Picker
Easy sending data to web apps
- a web app -
The WAP implements a popup window that allows web apps to easily share data with other web apps.
Making it trivial to find web apps to share data with.
Normally you have to install an app for you to be able to share data with it, the WAP allows you to share data with any app registered with the WAC - the Web App Central.
You're not a dev? - you can skip the rest of this page :-)
For this to work developers need to register their apps with the WAC and this is trivial, you just point the WAC to the app. In fact, the developer doesn't have to, you can register any app that you like.
The other thing needed is for app developer to integrate with the WAP and this is made trivial with a small javascript file that handles the communication with the WAP. See the sample app below that also shows the source code of the WAP integration.
Simply link to the WAP client and hook up events. Add a link to run the "share with..." UX.
<script src="https://www.backlund.org/WebAppPickerSample/_app_webapppickerclient.release.js"</script> <script> function shareWithTheWap() { webAppPickerClient.selectedText = "Share this text"; webAppPickerClient.picker.run(["text/plain"]); } </script> <div><a href="javascript:shareWithTheWap()">Share with...</a></div>
The WAP supports on-demand data. Say that your app can export a large CSV file but you don't want to generate the CSV until requsted by the app the data is shared with. This is easily handled by hooking up an event handler to the webAppPickerClient that is called when the chosen target app has been launched and is ready for your CSV. The sample above has a case for this scenario.
The WAP itself is a PWA, you can run it as normal web page and share data with apps you find interesting.
Sharing (or sending data) to a target app is done either via url
params or via sending a message with window.postMessage()
.
An app declares (in the regular PWA manifest) a number of share targets with a name,
a description and an action urls which is invoked when data is shared,
eg. https://www.mypwacompany.com/app.htm
In most cases the action_url is probably the same url as the app url.
If you want the sharing params to be passed as part of the fragment,
just add ?# to the end of the action_url, e.g. /app.htm?#
{ wac_share_targets: [ { "name": "Create a word cloud", "description": "Creates a word cloud based on the text shared", "action_url": "/app.htm" "action_name": "createcloud" } ] }
The share target also declares how data should be sent using the two fields, both defining an array of mime types.
The accepts_via_param variant is suitable for shorter textual sharing and accepts_via_postmessage must be used for binary data (e.g. image) sharing.
The share target below defines it wants text data as url params and CSV data via a post message.
{ wac_share_targets: [ { "name": "Create a word cloud", "description": "Creates a word cloud based on the text shared", "action_url": "/app.htm", "action_name": "createcloud", "accepts_via_param": [ "text/plain" ], "accepts_via_postmessage": [ "text/csv" ], } ] }
A share target can also declare icons to be used by the picker UX. If no icons defined, the picker will use an icon defined for the app itself.
{ wac_share_targets: [ { "name": "Create a word cloud", "description": "Creates a word cloud based on the text shared", "action_url": "/app.htm", "action_name": "createcloud", "accepts_via_param": [ "text/plain" ], "accepts_via_postmessage": [ "text/csv" ], icons: [ { "src": "/icons/createcloud.png" "sizes": "64x64" } ] } ] }
When it's time to share the data with the app, the action_url is appended with the params "wacsharedata", "wacsharetimetype" and "wacshareaction".
https://www.mypwacompany.com/app.htm?wacsharedata=thetext&wacsharetimetype=text/plain&wacshareaction=createcloud
pickerApp sends -> wap_senddata -> sourceApp sourceApp sends -> wap_invokeaction -> pickerApp pickerApp launches targetApp.htm?wacsharepostmessage targetApp sends -> wap_targetlaunched -> pickerApp pickerApp sends -> wap_incomingdata -> targetApp targetApp sends -> wap_dataconsumed -> pickerApp
If the calling (source) app hasn't provided any data for the selected mime type, the picker first sends the source app the message "wap_senddata".
const msg = { "id": "wap_senddata", "returnid": "wap_invokeaction", "body": { mimeType: "text/csv" } } sourceApp.postMessage(msg, {targetOrigin: "*"});
The source app should then respond with the data in a message formatted like this. Two sample are shown, one sending a blob, the other one sending text.
const blob = ... const msg = { "id": "wap_invokeaction", "body": { files: [blob] mimeType: blob.type } } sourceApp.postMessage(msg, {targetOrigin: "*"});
const msg = { "id": "wap_invokeaction", "body": { data: "some,sample,csv", mimeType: "text/csv" } } sourceApp.postMessage(msg, {targetOrigin: "*"});
The picker will then launch the app with the defined action_url and the param "wacsharepostmessage".
https://www.mypwacompany.com/app.htm?wacsharepostmessage
The picker then waits for the a message object with id "wap_targetlaunched" from the target app, the target app essentially using this code:
const msg = { "id": "wap_targetlaunched" } window.opener.postMessage(msg, {targetOrigin: "*"});
The picker will then respond with the message "wap_incomingdata" and a message body formatted as follows, first sample using a blob, second sample sending textual data.
const blob = ... const msg = { "id": "wap_incomingdata", "body": { msg.body.files: [ blob ]; msg.body.mimeType: "image/png" } } targetApp.postMessage(msg, {targetOrigin: "*"});
const msg = { "id": "wap_incomingdata", "body": { msg.body.data = "hello,world,this,is,some,data"; msg.body.mimeType: "text/csv"; } } targetApp.postMessage(msg, {targetOrigin: "*"});
The target app should then consume the data and respond with "wap_dataconsumed", executing code like this:
const msg = { "id": "wap_dataconsumed" } window.opener.postMessage(msg, {targetOrigin: "*"});
We are working on an extension to the PWA manifest so that an app can declare what it can produce and an end user can find apps that produce what he or she is looking for. If you have an idea on how to do this, let us know. (support@backlund.org)
{ wac_exports: [ EXPORT_TYPE* ] }
Some sample export types:
qrcode/*/image/png exporting qrcodes as PNGs qrcode/standard/image/png exporting standard qrcodes as PNGs qrcode/standard/image/svg exporting standard qrcodes as SVGs barcode/*/image/png exporting barcodes as PNGs barcode/end-13 exporting EAN-13 in unspecified formatThis sample declares that the app can export qr-codes and barcodes in the PNG format.
{ wac_exports: [ "qrcode/*/image/png" "barcode/*/image/png" ] }
Check out this short YouTube video.
Launch the app.
You might also be interested in these other apps or add-ons.
Bjorn's Web App Central - a web app
The independent central for web apps
This web app can be used FREE of charge.
Please report bugs here or reach out 2 me with questions @ support@backlund.org.
Follow me at Instagram @bjornsplayground and check out more videos at my YouTube channel.
You can view our privacy policy here.