Implement Web Share API on Fenix
Categories
(GeckoView :: General, enhancement, P1)
Tracking
(Webcompat Priority:?, firefox-esr68 wontfix, firefox68 wontfix, firefox69 wontfix, firefox70 wontfix, firefox71 wontfix, firefox72 fixed)
People
(Reporter: divjot94, Assigned: droeh, Mentored)
References
Details
(Keywords: dev-doc-needed, Whiteboard: [webcompat] [geckoview:m1909] [geckoview:m1910])
Attachments
(3 files)
Comment 1•7 years ago
|
||
Comment 2•7 years ago
|
||
Comment 3•7 years ago
|
||
Comment 4•7 years ago
|
||
Comment 5•7 years ago
|
||
Comment 6•7 years ago
|
||
Comment 8•7 years ago
|
||
Comment 9•7 years ago
|
||
Updated•6 years ago
|
Comment 12•6 years ago
|
||
In the conversation above there was uncertainty about Apple adopting. Web Share Level 1 is now implemented, Supported in Preview.
(Level 2 adds canShare() and the ability to share files.)
Comment 13•6 years ago
|
||
Apple is shipping Web Share in iOS 12.2, which is coming out in the coming months.
Updated•6 years ago
|
Comment 14•6 years ago
|
||
Twitter is now using this in their mobile site, and users have noticed that Firefox isn't getting the same "Share" option that Chrome is getting: https://webcompat.com/issues/27191
Comment 15•6 years ago
|
||
Migrating Webcompat whiteboard priorities to project flags. See bug 1547409.
Comment 16•6 years ago
|
||
See bug 1547409. Migrating whiteboard priority tags to program flags.
Comment 17•5 years ago
|
||
Also on Desktop Chrome v75. Even if https://caniuse.com/#feat=web-share does not list that yet.
Also opened https://github.com/mozilla/platform-status/issues/581 to get this on the status page.
Comment 18•5 years ago
|
||
Also on Desktop Chrome v75.
No, Chrome is only shipping this on Android for now.
Comment 19•5 years ago
|
||
I am proposing we do this via the PromptDelegate.
The sequence of events for DOM should be as follows:
share()
- Web page calls
navigator.share({...})
- Navigator class handles call:
-- - Returns promise.
-- - Checks that at least one oftitle
,url
,text
orfiles
are present. Rejects promise withTypeError
if not.
-- - Checks that theurl
is valid and meets criteria defined in spec. Rejects promise withTypeError
if not.
-- - Checks that the call was triggered by user interaction, rejects promise with"NotAllowedError" DOMException
if not.
-- - Checks for file types that are blocked due to security considerations, rejects promise with"NotAllowedError" DOMException
if any are found.
-- - Creates ansIPromptService
instance and calls share withurl
,text
,files
andtitle
as arguments.
-- - waits for response from prompt. If prompt fails (aSuccess == false
), reject promise with"AbortError" DOMException
. If prompt succeeds (aSuccess == true
), resolve promise withundefined
.
canShare()
- Web page calls
navigator.canShare({...})
- Navigator class handles call:
-- - Checks that at least one oftitle
,url
,text
orfiles
are present. Returnsfalse
if not.
-- - Checks that theurl
is valid and meets criteria defined in spec. Returnsfalse
if not.
-- -returnstrue
A new function needs to be added to nsIPromptService
called
boolean share(in mozIDOMWindowProxy aParent,
in wstring aTitle,
in wstring aText,
inout wstring aUrl,
in File[] aFiles,
out boolean aSuccess);
An equivalent method needs to be added to GeckoViewPrompt.js
.
This method will need to send a GeckoView:Prompt
event with the following message:
{
type: "prompt",
options: {
title: aTitle,
text: aText,
url: aUrl,
files:[file1,...]
},
}
If the prompt response is null
, an error has occured and aSuccess
should be set to false. If prompt response is true
, the share succeeded and aSuccess
should be set to true
.
In Java, a new class will be required to encapsulate share data:
ShareData
class ShareData {
private String mTitle;
private String mText;
private String mUrl;
private File[] mFiles;
public ShareData(GeckoBundle bundle);
}
A new callback interface is required to provide callback methods.
ShareCallback
interface ShareCallback extends AlertCallback {
@UiThread
default void abort() {}
default void success() {}
}
PromptCallback
should be extended to implement ShareCallback
@Override
public void abort() {
mCallback.sendError("abort");
}
@Override
public void success() {
mCallback.sendSuccess(true);
}
GeckoSession.PromptDelegate
will need to handle the share prompt and callback
default void onSharePrompt(@NonNull GeckoSession session, @NonNull ShareData data, @NonNull ShareCallback callback)
GeckoSession#handlePromptEvent
will need to be updated to listen to handle the new prompt
case. When received, the data needs to be tranformed into a ShareData
and sent, along with the callback, to the PromptDelegate
set by the consumer.
case "share": {
GeckoBundle data = message.getBundle("data");
ShareData shareData = new ShareData(data);
delegate.onSharePrompt(session, shareData, cb);
}
I am not sure what format the Files
will be sent through from Navigator, and therefore am unsure what format they will need to be converted into once they hit JS/Java. Maybe :mcaceres can answer that one.
Feedback requested, :mcaceres, :snorp.
Comment 20•5 years ago
|
||
This seems broadly fine to me. Some comments below:
(In reply to Emily Toop (:fluffyemily) from comment #19)
- Navigator class handles call:
-- - Returns promise.
-- - Checks that at least one oftitle
,url
,text
orfiles
are present. Rejects promise withTypeError
if not.
I don't see files
in the spec anywhere. Is this some pending change that we're expecting?
A new function needs to be added to
nsIPromptService
calledboolean share(in mozIDOMWindowProxy aParent, in wstring aTitle, in wstring aText, inout wstring aUrl, in File[] aFiles, out boolean aSuccess);
Like the other methods in nsIPromptService
, this is synchronous, but our web API and the way GV works is async. I think we should use a Promise here as well.
An equivalent method needs to be added to
GeckoViewPrompt.js
.This method will need to send a
GeckoView:Prompt
event with the following message:{ type: "prompt",
"share" probably?
options: {
title: aTitle,
text: aText,
url: aUrl,
files:[file1,...]
},
}If the prompt response is `null`, an error has occured and `aSuccess` should be set to false. If prompt response is `true`, the share succeeded and `aSuccess` should be set to `true`. In Java, a new class will be required to encapsulate share data: `ShareData`
class ShareData {
private String mTitle;
private String mText;
private String mUrl;
private File[] mFiles;public ShareData(GeckoBundle bundle);
}
A new callback interface is required to provide callback methods. `ShareCallback`
interface ShareCallback extends AlertCallback {
@UiThread
default void abort() {}
default void success() {}
}
There has been a plan to convert all of these callbacks to just use GeckoResult
(bug 1499394). We should try to do that here too.
PromptCallback
should be extended to implementShareCallback
@Override public void abort() { mCallback.sendError("abort"); } @Override public void success() { mCallback.sendSuccess(true); }
GeckoSession.PromptDelegate
will need to handle the share prompt and callbackdefault void onSharePrompt(@NonNull GeckoSession session, @NonNull ShareData data, @NonNull ShareCallback callback)
GeckoSession#handlePromptEvent
will need to be updated to listen to handle the newprompt
case. When received, the data needs to be tranformed into aShareData
and sent, along with the callback, to thePromptDelegate
set by the consumer.case "share": { GeckoBundle data = message.getBundle("data"); ShareData shareData = new ShareData(data); delegate.onSharePrompt(session, shareData, cb); }
I am not sure what format the
Files
will be sent through from Navigator, and therefore am unsure what format they will need to be converted into once they hit JS/Java. Maybe :mcaceres can answer that one.
I'd guess it would be one of these: https://developer.mozilla.org/en-US/docs/Web/API/File
We'd probably need some special handling for these, since they don't necessarily map to files on the disk. We may need to write temp files or some other such nonsense.
What's the testing story like here? Do we have existing mochitests or wpt?
Comment 22•5 years ago
|
||
I don't see files in the spec anywhere. Is this some pending change that we're expecting?
files (and canShare) arrived in Level 2: https://wicg.github.io/web-share-target/level-2/
Chrome for Android recently shipped Level 2. Both Chrome for Android and Safari had earlier shipped Level 1.
What's the testing story like here?
There are some WPTs in https://github.com/web-platform-tests/wpt/tree/master/web-share - most are either testing for expected failures, or are manual tests.
Updated•5 years ago
|
Comment 23•5 years ago
|
||
This seems great Emily. I've put in the DOM infrastructure based on your proposal, but as James pointed out, we will need to coordinate a bit more on the async aspects. I'm sending an "intent to experiment" to dev-platform for now, as we sort out how to implement this on GeckoView. Once we are happy with the architectural design, we can do a proper "intent to implement".
@Eric Willigers, let's pick up the level-2 stuff over on Github, but we should make those pull request on "level 1" (and hopefully get rid of the levels!).
I'll implement .canShare()
as "chrome-only" for now as I need to review that part of the spec more closely. I have finger-printing concerns.
Comment 24•5 years ago
|
||
I am not sure what format the Files will be sent through from Navigator, and therefore am unsure what format they will need to be converted into once they hit JS/Java. Maybe :mcaceres can answer that one.
@baku, you might recall we talked briefly about this at the AllHands... you had some suggestions for what we could use to get the files over to GeckoView. Would you mind providing some guidance again? The IDL from [1]:
dictionary ShareData {
USVString title;
USVString text;
USVString url;
FrozenArray<File> files;
};
(i.e., so it's File
as per FileAPI)
[1] https://wicg.github.io/web-share/level-2/#sharedata-dictionary
Updated•5 years ago
|
Comment 25•5 years ago
|
||
Un-assigning myself... we have an old DOM specific bug for this. I'll assign myself to that and block with this one on.
Intent to experiment:
https://groups.google.com/d/msg/mozilla.dev.platform/RHk3QJbV_7o/YCDCWRCCCgAJ
Updated•5 years ago
|
Updated•5 years ago
|
Comment 26•5 years ago
|
||
I'll implement .canShare() as "chrome-only" for now as I need to review that part of the spec more closely. I have finger-printing concerns.
It is intended to allow feature detection, so sites don't need to parse user agent strings.
If the browser does not support file sharing, then it detects the absence of title, text and url fields.
If the browser does support file sharing, then it detects the absence of title, text, url and files fields.
It also detects invalid URLs.
canShare reveals no information about which file contents/names/MIME types are accepted for sharing on a given device.
Comment 27•5 years ago
|
||
(In reply to Eric Willigers from comment #26)
canShare reveals no information about which file contents/names/MIME types are accepted for sharing on a given device.
Thanks, and that's great to hear! Let's pick this up over in the repo so we can have a more detailed discussion there about this.
Comment 28•5 years ago
|
||
FrozenArray<File> files;
};(i.e., so it's `File` as per FileAPI)
A file can be a anything: a in-memory chunk of data, a fetch/xhr response, a real OS File, a remote Blob (IPCBlob). Each DOM File can be read using nsIInputStream. See Blob::CreateInputStream(). The real question is: in which format do we want the File to be for GeckoView? Is it OK to have an nsIInputStream, a length and a type?
In case we need a real file, we can probably use MutableBlobStorage which can create a temporary OS File.
Marcos, are you going to work on the geckoview part too? Do you know how geckoview consumes the File objects?
Comment 29•5 years ago
|
||
(In reply to Andrea Marchesini [:baku] from comment #28)
Marcos, are you going to work on the geckoview part too? Do you know how geckoview consumes the File objects?
I think just the DOM side. But can pass whatever GeckoView needs/consumes... I guess we will need to figure that out between Emily, Snorp, and I.
I seem to recall form the AllHands there was some precedence to write temporary files and then pass file paths to read on the Android side, but I can't recall which project had done that.
Comment 30•5 years ago
|
||
After chatting with :marcosc it seems that there are questions over the security of sharing files, so we're going to move to a level 1 implementation only to start with and we will move to a level 2 implementation once the issues have been resolved: https://github.com/WICG/web-share/issues/108.
This involves removing canShare
from the spec and not supporting the sharing of files in share
.
Updated•5 years ago
|
Comment 32•5 years ago
|
||
Was playing around a bit with nsIPromptService and trying to add share()
to it.
I think we should use a Promise here as well.
Ol' funky .idl doesn't seem to know about Promise
as a primitive type... and there is no nsIPromise
type. I'm generally not inclined to implement a new Promise type. Anyone know of any precedence around making these things async? I see there is a asyncPromptAuth
, but also returns a boolean.
Assignee | ||
Comment 33•5 years ago
|
||
(In reply to Marcos Caceres [:marcosc] from comment #32)
Was playing around a bit with nsIPromptService and trying to add
share()
to it.I think we should use a Promise here as well.
Ol' funky .idl doesn't seem to know about
Promise
as a primitive type... and there is nonsIPromise
type. I'm generally not inclined to implement a new Promise type. Anyone know of any precedence around making these things async? I see there is aasyncPromptAuth
, but also returns a boolean.
I think .idl does support Promise
as a primitive -- see https://searchfox.org/mozilla-central/source/docshell/base/nsIDocShell.idl#1194 for example.
Comment 34•5 years ago
|
||
(In reply to Dylan Roeh (:droeh) (he/him) from comment #33)
I think .idl does support
Promise
as a primitive -- see https://searchfox.org/mozilla-central/source/docshell/base/nsIDocShell.idl#1194 for example.
Yeah, the docs were wrong... promise
was in lowercase, so I tried WebIDL style Promise<type>
. Anyway, working now. Fixed docs.
Comment 35•5 years ago
|
||
I have a question about how we are implementing this.... with regards to:
Promise share(in mozIDOMWindowProxy aParent, ... other stuff);
If I'm understanding nsIPromptService correctly, mozIDOMWindowProxy aParent
will be the outer window container, which assumes the share prompt will be bound to the outer window. That might be fine on Android, for instance - where we likely don't want "right-click" style popup, but rather a modal share selector.
However, on Desktop, we probably want the share() menu to appear where the user activated the share. For example, in Safari (screenshot):
<script>
async function share(){
await navigator.share({ url: window.location.href, title: document.title })
}
</script>
<button onclick="share()">Share this article</button>
Will passing mozIDOMWindowProxy aParent
allow us to get back to the child window? If yes, then 👍. Otherwise, we might want to just pass in the current window, and then either use the outer window to prompt on Android or the inner window on Desktop.
Comment 36•5 years ago
|
||
Assigning to Dylan because Emily said he will be working on Web Share for GeckoView.
Comment 37•5 years ago
|
||
Moving from Fennec's Bugzilla component to GV's.
Updated•5 years ago
|
Updated•5 years ago
|
Comment 38•5 years ago
|
||
Changing whiteboard tag to [geckoview:m1909]
because Emily expects WebShare will land in September.
firefox70=wontfix because we can't uplift WebShare GV APIs without the WebShare DOM APIs (bug 1312422) and we're unlikely to uplift new DOM APIs to Beta.
Comment 39•5 years ago
|
||
WebShare is in Fenix's "want for Q4" list.
A-C issue: https://github.com/mozilla-mobile/android-components/issues/3486
Comment 40•5 years ago
|
||
Setting priority P1 since we're working on this bug for September.
Comment 41•5 years ago
|
||
(In reply to Chris Peterson [:cpeterson] from comment #39)
WebShare is in Fenix's "want for Q4" list.
Chris, I haven't seen Web Share show up in any of the Q4 Product OKRs. Do you know who/what is driving this?
Comment 42•5 years ago
|
||
(In reply to Mike Conca [:mconca] from comment #41)
(In reply to Chris Peterson [:cpeterson] from comment #39)
WebShare is in Fenix's "want for Q4" list.
Chris, I haven't seen Web Share show up in any of the Q4 Product OKRs. Do you know who/what is driving this?
Good question. WebShare is in the Fenix team's "Items needed for Fenix Q4" bug list, but I don't see it in Fenix's Q4 OKRs.
Leaving needinfo until I get clarification.
Comment 43•5 years ago
|
||
(In reply to Chris Peterson [:cpeterson] from comment #42)
Good question. WebShare is in the Fenix team's "Items needed for Fenix Q4" bug list, but I don't see it in Fenix's Q4 OKRs.
Leaving needinfo until I get clarification.
The Fenix team says they will have more information by the end of next week. They have a Q4 planning week next week, including a session about Fenix's plans for PWA support (which is an umbrella term covering many different APIs and features to be delivered in phases).
Comment 44•5 years ago
|
||
WebShare is listed in the GeckoView Q3 OKRs. That said, it is probably more of a "should" than a "must".
Comment 45•5 years ago
|
||
Emily recommends we move Web Share out of our September sprint and back to the top of our October backlog. GV work is still blocked waiting for DOM Web Share bug 1312422.
Comment 46•5 years ago
|
||
Tentatively adding to GV's October sprint.
Updated•5 years ago
|
Assignee | ||
Comment 48•5 years ago
|
||
Comment 49•5 years ago
|
||
Comment 50•5 years ago
|
||
firefox71=wontfix because Fenix doesn't need us to uplift Web Share to GV 71 Beta.
Comment 51•5 years ago
|
||
bugherder |
Comment 52•5 years ago
|
||
bugherder landing |
Updated•5 years ago
|
Comment 53•5 years ago
|
||
I don't think there is any documentation to do right now, as GeckoView/Fenix is not available yet, right?
For any such items that we'll need to update when Fenix is available, we are storing them at the following issue: https://github.com/mdn/browser-compat-data/issues/4983
We will then action these when Fenix is available.
Updated•5 years ago
|
Updated•4 years ago
|
Description
•