-
Notifications
You must be signed in to change notification settings - Fork 65
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
canShare() is not future compatible #108
Comments
I like that rough idea because I can see that often sites would want to check this up front to determine whether to enable file sharing. Currently we also restrict the mime types and extensions that can be shared to a limited set. canShare could also be useful to determine if the site can share a particular type. So perhaps canShare -> canShareFileTypes([array of file extensions/mime types]). I'm interested in @mgiuca's thoughts here. |
This is somewhat reminiscent of the defunct We might need to restrict the types... or maybe look at how other parts of the platform deals with this? For example, drag and drop must somehow deal with this somehow. And probably other parts of the platform too.... I'm looking at HTML Media Capture, and the interop story there also seems to be not great: https://caniuse.com/#feat=html-media-capture Hmmm... 🤔 |
We simply wanted to avoid specifying the same list of conditions in two different places, to avoid the risk of them ever getting out of sync. I see the following as equivalent:-
The spec can easily be reworded using 2. or 3. instead of 1. It is certainly not anticipated that canShare() would be implemented by calling share(). As I noted in the Mozilla bug, canShare [currently] reveals no information about which file contents/names/MIME types are accepted for sharing on a given device. An implementation might choose to perform asynchronous malware checking in share(), and reject with NotAllowedError if the content is considered dangerous. Such checks are currently not relevant for canShare, which is synchronous. |
Right, but I'm arguing that they are completely different concerns: they do completely different things (so there is zero risk of them getting out of sync as there is no overlap in functionality):
That's not my reading. The spec pretty clearly states that the two are co-dependent (my emphasis): "canShare(data) MUST return true unless share(data) would reject with TypeError, in which case it MUST return false." Clearly, to me, "share(data) would reject with TypeError" moves the risk of things getting out of sync onto implementers. That seems unfortunate and unnecessary.
Which I think is great and a good point that you raised it again. The above proposal prevents us from being tempted to go down the MIME checking route entirely: it only says yea or nay to supporting particular dictionary members.
If we need a malware checker to implement I wonder if we can put in place some provision to only allow some well-known, inert, file types that we all agree to?... probably not... but maybe worth considering?
Agree. But again, this is why I think there should be no overlap between what the two methods do. |
Not required, the spec just doesn't prevent it.
Blink currently supports the following: Audio
Image
Text
Video
|
@ewilligers @mgiuca, I'd like to pick this up again and see if we can simplify the design a bit... I'd like to continue investigating the possibility of only checking on for the member names. We can probably drop the enum and just use a navigator.canShare(["files", "url"]) Which works nice with: navigator.canShare(Object.keys(data)); Alternative is to make it variadic, which might give some flexibility for single checks without needing to create an array. // check all...
navigator.canShare(...Object.keys(data));
// check some...
const supported = memberNames.filter(name => navigator.canShare(name)); |
I'm a bit confused by the intent of this issue. Is this just calling for improving how Assuming the former: I agree, the spec text could be improved. I'd just factor out the algorithm from To validate share data with data and base, run the following steps:
Then it can be called with:
(share() would need to reparse the url, but can Assert that it's not failure) |
I agree this would be a simplification. If the app already has a ShareData, then the current One complication is that, if content currently feature-detects and uses Accepting either form of the argument is not an ideal solution, because there'd be no way to feature test which form of arguments is accepted. |
The idea was that in future there might be more fields, and there should be a way to feature detect if they are supported.
|
This is true, but you still don't know which one is not supported? Is it files or is it url? so you are back to What @othermaciej proposes deals with this problem more elegantly: it allows you to feature detect if you support files for the purpose of feature detection, by virtue that the method name says what it queries: "canShareFiles()". |
I have no concerns about adding Blink would likely retain support for The original PR introducing Blink's Intent to Ship for file sharing was in January 2019. The feature detection recommendation Google shared with web developers in June 2019 was
|
Ok, respectfully, yes the PR was upload and reviewed - but it was by two folks on the same team in the same company. Please understand why that is concerning form a standardization perspective: features should receive wide review and endorsement/support from multiple implementers. We have the PR template for a reason. Same with the other things that were mentioned. The stuff Google did there is great (the intent to ship, the feature recommendation on the Chrome dev site, etc.), but those are very Chrome/Google specific things. |
I think there are two separate questions here:
Hopefully we don't end up with different answers. (2) is one of the reasons it's risky to ship draft standards before getting sufficient input from the group and from other vendors, as @marcoscaceres said. |
According to ChromeStatus data the |
So, it seems I might have left this one too late to change. Safari 14 ships with the checks (though I think File is still pref'ed off). https://github.com/WebKit/webkit/blob/master/Source/WebCore/page/Navigator.cpp#L127 We should move |
@whsieh, @othermaciej, @ericwilligers, @mgiuca, during review of Mozilla's implementation, @saschanaz has found a fundamental flaw with the API that makes this not future compatible. Imagine tomorrow we add const someObj = { url: "someURL", images: [] };
navigator.canShare(someObj); // true! Oh no! Today, all implementations would return true to the above, because "images" is dropped on the floor by IDL layer. That means that they API is only usable if a developer destructs an object and tests it using it component parts. Additionally, file testing is also somewhat flawed (as are the rest of the members), because they presuppose a developer knows what they are going to share before sharing it. Again, for example, to check if navigator.share({files: []}); // false, at least one file needed - but might confuse people into thinking it's not supported
// so developers need to create fake empty files
navigator.share({files: [new File([], "name")]}); // maybe true I understand that the API has shipped, but again, the API demonstrably flawed and will could lead to confusion. I'd strongly urge us to:
Thoughts? |
The simplest approach might be to add I started to spec it, but would appreciate feedback on the approach before I refine it. |
@whsieh, @othermaciej, @ericwilligers, @mgiuca, we are kinda at an impasse here with Mozilla (@saschanaz) rightfully pointing out the current design is broken: Is there a willingness to fix or update |
One way to fix that is to change the signature to |
Yeah, that's not overly offensive - using |
If no one responds, I think it's okay to proceed with |
We would need to still need to send patches and get implementer agreement, but you are right that it should be trivial. Worst case, we patch Gecko only, which gives a compatibility path forward for now (and update other implementations when this becomes an actual issue in the future). |
Reopened so we can keep bouncing ideas here. |
I wonder if we can simplify canShare() a bit... right now, canShare() conflates type checking behavior by intertwining the method call with share(). This is problematic because share() returns a promise, not TypeErrors.
Over on Mozilla’s bugzilla, @ericwilligers mentioned that the intent of canShare() is to avoid having to do UA sniffing. As such, why don’t we this instead:
That greatly simplifies things by deferring the support checking to the IDL layer. That causes the IDL layer to throw if passed some unsupported Shareable type. The result being that it either returns true or throws.
If throwing is not palatable, then an alternative would be to take a sequence of DOMStrings, then return false if the names don’t match a supported member type.
The text was updated successfully, but these errors were encountered: