Closed Bug 1772949 Opened 2 years ago Closed 2 years ago

Set navigator.share to undefined on YouTube iframe

Categories

(Web Compatibility :: Interventions, task)

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: saschanaz, Unassigned)

References

(Blocks 1 open bug, )

Details

Sharing via embedded YouTube iframes are currently broken (for years on Android):

  1. Make sure dom.webshare.enabled to true on Windows/Android (other platforms are not supported)
  2. Open https://femiwiki.com/w/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8_%EC%84%B8%EC%B9%B4%EC%9D%B4_%EC%BB%AC%EB%9F%AC%ED%92%80_%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%A7%80!_feat._%ED%95%98%EC%B8%A0%EB%84%A4_%EB%AF%B8%EC%BF%A0/%EC%95%85%EA%B3%A1/%EC%95%84%EC%9D%B4%EB%94%94%EC%8A%A4%EB%A7%88%EC%9D%BC
  3. Click 'Share' on the video frame
  4. See it never responds.

Injecting the following makes it fallback to the traditional in-page share popup:

if (window.parent !== window.top) {
  navigator.share = undefined;
}

I request a site intervention to unblock shipping of Web Share. (YouTube has been contacted multiple times and they haven't fix it yet.)

Hi :twisniewski, is this something you can take a look?

Flags: needinfo?(twisniewski)
Blocks: 1776673
Flags: needinfo?(twisniewski)

Shimming this requires a little elbow-grease, as WebExtension content scripts can't efficiently be defined to run only on specific sub_frames on all pages, and we can't just listen with webRequest.onBeforeRequest for the frame's URL, as at that point the window for the frame is still pointing at about:blank, and we can't reliably wait for the document changeover and run a script before all other page-scripts at that point.

So instead I'll use onBeforeRequest to block requests for their www-embed-player.js script, while I undefine navigator.share on its frame. This will also have the benefit that if a user visits the embed's URL directly (via "open frame in a new tab" for instance), the share interface will still fall back to the non-WebShare one.

Shimming this requires a little elbow-grease, as WebExtension content scripts can't efficiently be defined to run only on specific sub_frames on all pages

Can it run on every youtube embed page and check whether it's in an iframe by window.parent? Or would that be inefficient in a significant way?

This will also have the benefit that if a user visits the embed's URL directly (via "open frame in a new tab" for instance), the share interface will still fall back to the non-WebShare one.

I'm not sure that's a benefit, navigator.share in the embed page outside of an iframe works just as expected. We don't need to remove that, or that'd actually be an unexpected behavior.

Can it run on every youtube embed page

We would either need to know every page URL which embeds YT videos (nope) or run the content script speculatively on all pages, which is indeed very inefficient.

navigator.share in the embed page outside of an iframe works just as expected

I see, then I can simply not override it on the top-level page.. that's easy enough (like you did by checking window.top). It will still be more efficient to only run the script when a frame (main or otherwise) loads that script than it will be to do it on all frames.

See Also: → 1737541

I see the intervention is live, should we close this?

Flags: needinfo?(twisniewski)

Yes, I'm going to close all the sub-bugs for the v104 webcompat interventions today.

Status: NEW → RESOLVED
Closed: 2 years ago
Flags: needinfo?(twisniewski)
Resolution: --- → FIXED

Apparently youtube may have changed something on their side now. Could someone try to remove the intervention?

Kagami tested and YT seems to be still broken, but in a different way

The issue is not reproducible, regardless of the status of the Intervention. I am able to share a video via the video frame. Kagami, can you confirm, please?

Tested with:
Operating System: Windows 10 PRO x64
Firefox version: Firefox Nightly 109.0a1 (2022-11-24) (64-bit)
Operating system: Android 11/ Android 12
Firefox version: Firefox Nightly 109.0a1 (2015917611-🦎109.0a1-20221123094429🦎)

Flags: needinfo?(krosylight)

Thanks! I can also confirm it's fixed. Now the script does:

    if (navigator.share) try {
      var e = navigator.share({
        title: c.title,
        url: b
      });
      e instanceof Promise && e.catch(function (f) {
        XKa(a, f)
      })
    } catch (f) {
      f instanceof Error && XKa(this, f)
    } else this.j.Bk(),

... which correctly falls back when navigator.share exists but fails.

Flags: needinfo?(krosylight)
See Also: → 1802339
You need to log in before you can comment on or make changes to this bug.