Git Product home page Git Product logo

document-picture-in-picture's Introduction

Document Picture-in-Picture Explained

2023-10-26

Spec: https://wicg.github.io/document-picture-in-picture/

What's all this then?

There currently exists a Web API for putting an HTMLVideoElement into a Picture-in-Picture window (HTMLVideoElement.requestPictureInPicture()). This limits a website's ability to provide a custom picture-in-picture experience (PiP). We want to expand upon that functionality by giving websites the ability to open a picture-in-picture (i.e., always-on-top) window with a blank document that can be populated with arbitrary HTMLElements instead of only a single HTMLVideoElement.

This new window will be much like a blank same-origin window opened via the existing window.open() API, with some differences:

  • The PiP window will float on top of other windows.
  • The PiP window will never outlive the opening window. This means any navigations that change the opener to a new document (even same-origin navigations) will cause the PiP window to close, similar to the existing HTMLVideoElement.requestPictureInPicture() API.
  • The website cannot set the position of the PiP window.
  • The PiP window cannot be navigated (any window.history or window.location calls that change to a new document will close the PiP window).
  • The website can have only one PiP window open at a time, and the user agent may also restrict how many PiP windows can be open globally, similar to HTMLVideoElement.requestPictureInPicture() API.

Goals

  • Allow a website to display arbitrary HTMLElements in an always-on-top window.
  • To be simple for web developers to use and understand. Note that while allowing websites to call requestPictureInPicture() on any element would be the simplest way, for reasons described below, this isn't feasible.

Non-goals

  • This API is not attempting to handle placeholder content for elements that are moved out of the page (that is the responsibility of the website to handle).
  • Allowing websites to open always-on-top widgets that outlive the webpage (the PiP window will close when the webpage is closed).

Use cases

Custom video player

While the existing Picture-in-Picture API for HTMLVideoElement allows a website to provide a Picture-in-Picture video experience, it is very limited in what inputs the window can take and the look-and-feel of those inputs. With a full Document in Picture-in-Picture, the website can provide custom controls and inputs (e.g. captions, playlists, time scrubber, liking/disliking videos, etc) to improve the user's PiP video experience.

Custom video player wireframe 1 Custom video player wireframe 2

Video conferencing

It is common for users to leave the tab during a video conferencing session for various reasons (e.g. presenting another tab to the call or multitasking) while still wishing to see the call, so it's a prime use case for Picture-in-Picture. As above, the current experience a video conferencing website can provide via the HTMLVideoElement PiP API is limited in style and input. With a full Document in Picture-in-Picture, the website can easily combine multiple video streams into a single PiP window and provide custom controls like sending a message, muting another user, raising a hand, etc.

Video conferencing wireframe 1 Video conferencing wireframe 2

Pomodoro timers

The Pomodoro technique is a time management method that uses a kitchen timer to break work into intervals, typically 25 minutes in length, separated by short breaks. Pomodoro timer apps on desktop and mobile can use the PiP feature to display the current timer permanently on the screen as a floating timer for timed focus management while sat at a desk or while on the go.

Pomodoro timers wireframe 1

Example code

HTML

<body>
  <div id="player-container">
    <div id="player">
      <video id="video" src="foo.webm"></video>
      <!-- More player elements here. -->
    </div>
  </div>
  <input type="button" onclick="enterPiP();" value="Enter PiP" />
</body>

JavaScript

// Handle to the picture-in-picture window.
let pipWindow = null;

async function enterPiP() {
  const player = document.querySelector("#player");

  const pipOptions = {
    width: player.clientWidth,
    height: player.clientHeight,
  };

  pipWindow = await documentPictureInPicture.requestWindow(pipOptions);

  // Style remaining container to imply the player is in PiP.
  const playerContainer = document.querySelector("#player-container");
  playerContainer.classList.add("pip-mode");

  // Add player to the PiP window.
  pipWindow.document.body.append(player);

  // Listen for the PiP closing event to put the video back.
  pipWindow.addEventListener("pagehide", onLeavePiP.bind(pipWindow), {
    once: true,
  });
}

// Called when the PiP window has closed.
function onLeavePiP() {
  if (this !== pipWindow) {
    return;
  }

  // Remove PiP styling from the container.
  const playerContainer = document.querySelector("#player-container");
  playerContainer.classList.remove("pip-mode");

  // Add the player back to the main window.
  const pipPlayer = pipWindow.document.querySelector("#player");
  playerContainer.append(pipPlayer);

  pipWindow = null;
}

Key scenarios

Accessing elements on the PiP window

const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.loop = true;

Listening to events on the PiP window

As part of creating an improved picture-in-picture experience, websites will often want customize buttons and controls that need to respond to user input events such as clicks.

const pipVideo = pipWindow.document.querySelector("#video");
const pipMuteButton = pipWindow.document.createElement("button");
pipMuteButton.textContent = "Toggle mute";
pipMuteButton.addEventListener("click", () => {
  pipVideo.muted = !pipVideo.muted;
});
pipWindow.document.body.append(pipMuteButton);

Exiting PiP

The website may decide to close the DocumentPictureInPicture window without the user explicitly clicking on the window's close button. They can do this by using the close() method on the Window object:

// This will close the PiP window and trigger our existing onLeavePiP()
// listener.
pipWindow.close();

Getting elements out of the PiP window when it closes

When the PiP window is closed for any reason (either because the website initiated it or the user closed it), the website will often want to get the elements back out of the PiP window. The website can perform this in an event handler for the pagehide event on the Window object. This is shown in the onLeavePiP() handler in Example code section above and is copied below:

// Called when the PiP window has closed.
function onLeavePiP() {
  if (this !== pipWindow) {
    return;
  }

  // Remove PiP styling from the container.
  const playerContainer = document.querySelector("#player-container");
  playerContainer.classList.remove("pip-mode");

  // Add the player back to the main window.
  const pipPlayer = pipWindow.document.querySelector("#player");
  playerContainer.append(pipPlayer);

  pipWindow = null;
}

Programatically resize the PiP window

The document picture-in-picture window supports the resizeTo() and resizeBy() APIs, but only with a user gesture on the PiP window:

const expandButton = pipWindow.document.createElement('button');
expandButton.textContent = 'Expand PiP Window';
expandButton.addEventListener('click', () => {
  // Expand the PiP window's width by 20px and height by 30px.
  pipWindow.resizeBy(20, 30);
});
pipWindow.document.body.append(expandButton);

Detailed design discussion

Why not extend the HTMLVideoElement.requestPictureInPicture() idea to allow it to be called on any HTMLElement?

Any API where the UA is taking elements out of the page and then reinserting them ends up with tricky questions on what to show in the current document when those elements are gone (do elements shift around? Is there a placeholder? What magic needs to happen when things resize? etc). By leaving it up to websites to move their own elements, the API contract between the UA and website is much clearer and simpler to understand.

Since this is pretty close to window.open(), why not just add an alwaysOnTop flag to window.open()?

The main reason we decided to have a completely separate API is to make it easier for websites to detect it (since in most cases, falling back to a standard window would be undesirable and websites would rather use HTMLVideoElement PiP instead). Additionally, it also works differently enough from window.open() (e.g., never outliving the opener) that having it separate makes sense.

Why not give the website more control over the size/position of the window?

Giving websites less control over the size/position of the window will help prevent, e.g., phishing attacks where a website pops a small always-on-top window over an input element to steal your password.

Considered alternatives

Surface Element was a proposal where the website would wrap PiP-able content in advance with a new type of iframe-like element that could be pulled out into a separate window when requested. This had some downsides including always requiring the overhead of a separate document (even in the most common case of never entering picture-in-picture).

We also considered a similar approach to the one in this document, but with no input allowed in the DOM (only allowlisted controls from a predetermined list in a similar fashion to the existing HTMLVideoElement PiP). One issue with this approach is that it really didn't help websites do much more than they already can today, since a website can draw anything in a canvas element and PiP a video with the canvas as a source. Having HTMLElements that can actually be interacted with is what makes the Document Picture-in-Picture feature worth implementing.

References and acknowledgements

Many thanks to Frank Liberato, Mark Foltz, Klaus Weidner, François Beaufort, Charlie Reis, Joe DeBlasio, Domenic Denicola, and Yiren Wang for their comments and contributions to this document and to the discussions that have informed it. Special thanks to Mikaela Watson and Glen Anderson for the initial wireframes.

document-picture-in-picture's People

Contributors

anssiko avatar beaufortfrancois avatar cwilso avatar foolip avatar steimelchrome avatar tomayac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

document-picture-in-picture's Issues

"Pomodoro timers" seems overly specific

I loved the Pomodoro timer example as a non-video use case.
But I think that any kind of timer would be a valid use case. e.g. for a time tracking app, it'd be great to have an always-on-top tiny window that tells me it's running, and enables me to change the thing I'm currently doing. I'm sure there are other forms of timers that can make use of this.

So, please consider expanding the use case :)

Move pip window to current virtual desktop

Thanks for bringing such great features to the web!
I'm a web developer and I would love to use the document pip feature, but there's one major disadvantage compared to video-pip windows. As a mac user I'm used to work with virtual desktops and the video pip-window is always shown on the current virtual desktop. Unfortunately, the document-pip window does not follow along, it just stays at the virtual desktop where it was opened. That makes no sense to me. The main purpose of such a window is to be always present to the user. With the current behaviour, it is just an advanced popup window.
I would love to see a requirement in the spec saying that it must be always visible to the user and therefor be present on the current active desktop.
Thanks in advance!

How to prevent ad popups shown always on top?

The Document PiP could become a "wet dream" for all kinds of aggressive advertisers, which could serve always-on-top intrusive ad popups disturbing users while browsing web pages. How will you prevent such an unpleasant behavior?

`initialAspectRatio` should size window contents

Setting the aspect ratio is important for content that has a natural aspect ratio, like a video.

The value of initialAspectRatio (or width and height) currently sizes the complete outer window, including its title bar, resulting in a window too wide for the content. The title bar height could vary by OS, font settings, locale, and eventually browser.

Users using picture-in-picture generally want to move the video out of the way of something else to multitask. Having an inappropriately sized window displaying black padding around the video will be an annoyance.

The window should be sized so that the window content is the requested aspect ratio; the browser can determine on the overall size of the window accommodating title bar within whatever constraints or preferences apply.

allow origin to open PiP window from inactive tab (with previous explicit consent by the user)

Hello,

For some use cases related to Video conferencing (one of the cited use cases for this new feature) it would be great if the PictureInPicture could be triggered programmatically.
eg. when receiving an incoming video call in a web-based videoconference solution.
or showing call controls for an inbound call that is automatically accepted (call center agent)

Popups created programmatically with windows.open are blocked by default but a notification is shown to let the user allow popups if needed.

Screenshot 2023-07-24 at 2 27 04 PM

Could PiP behave in the same way? this would enable use cases that are not currently possible on web apps but are used in desktop applications.

Security considerations

Hi! This proposal ended up in the Chromium security&privacy triage queue, and I had a look at it.

I'm a bit concerned about the potential of this proposal to bypass security directives. This might have to replicate all the inheritance mechanisms used by popups initial empty documents. Examples include sandboxing, Permissions Policy, COOP, etc.

Third party iframes opening popups have also been a security nightmare in the past, and the feature should probably be completely off for them.

Thanks,
Arthur

Not working in sidePanel webextension

I'm working on a webextension and tried documentPictureInPicture.requestWindow() from within a sidePanel. Unfortunately it doesn't work from there (onenter and window attributes are both null).

How to share javascript logic & CSS from parent to children PiP windows?

Hey, let's say I got many buttons, components and its functionality attached to them and this PiP window needs to inherit.

How can I properly pass it? Because I tried adding a console.log to the play button in a handler function but is not being triggered within the PiP window. It seems I can only share some of the CSS styles and inner DOM elements, but not actual Javascript and all the styling I added to custom buttons.

Here's the test code:


const VideoPlayer = (): JSX.Element => {
  // Handle to the picture-in-picture window.
  const pipWindow = useRef(null);
  const videoContainerRef = useRef(null);
  const playerRef = useRef(null);
  // const [isPip, setIsPip] = useState(false);

  const handlePlay = () => {
    console.log("playyyyy");
  };

  const enterPiP = async () => {
    const pipOptions = {
      width: playerRef.current.clientWidth,
      height: playerRef.current.clientHeight,
      copyStyleSheets: true,
    };

    // @ts-ignore
    pipWindow.current = await documentPictureInPicture.requestWindow(
      pipOptions
    );

    // Style remaining container to imply the player is in PiP.
    if (videoContainerRef.current) {
      // setIsPip(true);
      playerRef.current.classList.add("pip-mode");

      // Add player to the PiP window.
      pipWindow?.current?.document.body.append(playerRef.current);

      // Listen for the PiP closing event to put the video back.
      pipWindow?.current?.addEventListener(
        "pagehide",
        onLeavePiP.bind(pipWindow.current),
        {
          once: true,
        }
      );
    }
  };

  // Called when the PiP window has closed.
  const onLeavePiP = () => {
    // Remove PiP styling from the container.
    if (videoContainerRef.current) {
      // setIsPip(false);
      playerRef.current.classList.remove("pip-mode");

      // Add the player back to the main window.
      videoContainerRef.current.append(playerRef.current);

      pipWindow.current = null;
    }
  };

  return (
    <div ref={videoContainerRef} className="videoContainer">
      <div ref={playerRef} className="videoPlayer">
        <video
          id="video"
          autoPlay
          muted
          playsInline
          loop
          src="https://storage.googleapis.com/media-session/sintel/trailer.mp4"
        ></video>
        <div className="videoControls">
          <button className="videoControlButton" onClick={handlePlay}>
            Play
          </button>
          <button className="videoControlButton">CC</button>
          <button className="videoControlButton" onClick={enterPiP}>
            Open PiP
          </button>
        </div>
      </div>
    </div>
  );
};

export default VideoPlayer;

"is a DocumentPictureInPicture Window" is not well-defined

It sounds like the model here is that every Window has a boolean, "is document picture-in-picture", which is either true or false, false by default. Or maybe it should belong to a navigable instead? Or a top-level traversable?

Then you should check that boolean.

Add `x` and `y` to `DocumentPictureInPictureOptions`

Since DocumentPictureInPicture.requestWindow() returns a Window which exposes moveTo(), I expected it to work, but in practice it doesn't. My use case is that I have a PiP dashboard that I like to move to a particular area of the screen, which of course is different from the default position in the lower right. Should this work? I was unsure whether to file a Chromium bug or a spec Issue, similar to #33. Sorry if it's more of an implementation problem.

A Document PiP-specific display mode

We've implemented Document PiP in Whereby, and were wondering if it could be an idea to consider Picture-in-Picture as a type of "display mode". For reference, display modes are used with e.g. PWAs, which can have display modes of e.g. standalone or fullscreen, reflecting their window state. In a similar way, Picture-in-Picture can be considered a (more temporary) type of display mode.

https://www.w3.org/TR/mediaqueries-5/#display-mode defines "display mode" as follows:

A display mode represents how the web application is being presented within the context of an OS (e.g., in fullscreen, etc.). Display modes correspond to user interface (UI) metaphors and functionality in use on a given platform.

This seems to match with how PiP windows behave and what they do. A display-mode media feature for picture-in-picture would then allow us to write specific CSS rules that are only applied when (part of the) the application is shown in picture-in-picture mode. For example:

@media all and (display-mode: picture-in-picture) {
  body {
    margin: 0;
  }
  h1 {
    font-size: 0.8em;
  }
}

In this example, we're adding a modification that removes margins on the body element, and reduces the font-size of titles when in PiP mode — this could be done in an attempt to better fit the content in question inside the PiP window, while the rest of the CSS is just applied as normal.

NB: there is already a :picture-in-picture pseudo class, but in my opinion, it's more for one-off adjustments; if a number of rules need to be modified, a special display mode seems to be a better fit.

Possible to open multiple pip windows?

I noticed that every call to the window.documentPictureInPicture.requestWindow creates a new pip window but destroys the previous one. Is that intentional? Is there a way to create multiple windows?

target browsing context is not a window

Steps 14 and 15 treat target browsing context like a Window object. It is not. You need to go from a browsing context (or traversable navigable, per recent updates) to the Window object.

Operating in parallel / on promises

Migrated from steimelchrome/steimelchrome.github.io#7

From domenic@:

"
Check out https://html.spec.whatwg.org/#event-loop-for-spec-authors .

You cannot throw from in parallel. You cannot look at a document's style sheets in parallel. You cannot manipulate promises in parallel. You cannot create new DocumentPictureInPictureSession objects, or even Window objects, in parallel.

Basically, you need to clearly separate the stuff that's on the main thread, and happens before you go in parallel, from the stuff that's in the "browser process", in parallel. And carefully post tasks when you need to sync back to the main thread.

This also applies when navigating to existing concepts. E.g. you use "associated Document" a lot---but whose associated Document? Associated Document is, by definition, the property of a Window object. So presumably, you need to navigate from the one object you have a handle to---the this value inside your method steps---pass that along to the "open DocumentPictureInPictureSession algorithm", then look at documentPictureInPicture's relevant global object's associated Document.
"

Avoid monkeypatching/action at a distance

Migrated from steimelchrome/steimelchrome.github.io#8

From domenic@:

"
Your spec includes two normative monkeypatches (see W3C TAG design principles and Anne's blog for more on why this is bad):

https://steimelchrome.github.io/draft_spec.html#one-pip-window monkeypatches other parts of the spec, with a normative "must" requirement. Instead, that requirement needs to be incorporated (and made precise---what are "appropriate events"??) in the place where picture-in-picture statuses change.

https://steimelchrome.github.io/draft_spec.html#relative-urls monkeypatches the entire web platform's URL resolution. This is quite bad! And probably not what you intended. I suspect instead you want to create the new browsing context / Window / Document with an overridden base URL of some sort.
"

Remove `initialAspectRatio`

With lockAspectRatio gone, I think we should remove initialAspectRatio from the spec and tell web developers to only use width and height to set the desired PiP window size. We could make sure that the aspect ratio is respected as well when specifying those implementation wise.

const pipWindow = await documentPictureInPicture.requestWindow({
  initialAspectRatio: player.clientWidth / player.clientHeight,
});

can be replaced with

const pipWindow = await documentPictureInPicture.requestWindow({
  width: player.clientWidth,
  height: player.clientHeight,
});

@steimelchrome
What do you think?

PiP starts lagging when using a video background.

Chrome: v114
OS: MacOS Ventura 13.4.1
Video Background processor: https://www.npmjs.com/package/@twilio/video-processors

This video background processor is based on Google implementation.

These processors run TensorFlow Lite using MediaPipe Selfie Segmentation Landscape Model and requires WebAssembly SIMD support in order to achieve the best performance.

STR:
1. Start a video and apply the video background from tab1
2. Activate Picture and Picture functionality
3. Click on tab2 and check the video inside PiP

Actual result: video is extremely lagging
Expected result: video is playing

Note: When I deactivate the video background feature, the video inside PiP works fine again

pip_video_background

Relative URL confusion tracking issue

In #10 we discussed relative URL resolution. You said

I was able to just remove the relative URLs section since that is actually taken care of for free by the "creating a new auxiliary browsing context and document" algorithm.

I checked and... I think you're right? But, the HTML spec's behavior doesn't seem to match any browsers?? I filed whatwg/html#9310 to track the potential HTML spec bug.

So, either HTML has a bug, and fixing it will break this spec. (I.e., it will mean that document PiP windows get an about:blank base URL instead of your desired inherited base URL.) Or, there's something subtle about HTML that we both missed, and this spec is currently broken.

I suspect what we'll have to do here is monkeypatch https://html.spec.whatwg.org/#fallback-base-url to have a case for checking if document's navigable is a document-picture. (See w3ctag/design-principles#441 for some in-progress guidance on how to do that well, from this spec.) But probably first we need to resolve my confusion about what HTML says...

Be more clear about what owns what

Migrated issue from steimelchrome/steimelchrome.github.io#6

From domenic@:

"
It seems like maybe browsing contexts own DocumentPictureInPictureSessions? If so that should be declared somewhere. But it's a surprising choice; do you really want a PiP session to last if the user navigates from https://example.com/ to https://other.example/? (A browsing context is like a browser tab.)

In general, you want to declare up-front what types of objects own what other types of objects, and add definitions for that ownership. Then, when you access an object, you need to traverse the ownership graph. An example from https://wicg.github.io/navigation-api/ is how it declares each Window owns a navigation API (an instance of Navigation), and each Navigation owns an entry list.
"

Browsing context creation

Migrated from steimelchrome/steimelchrome.github.io#9

From domenic@:

"
You currently say

Let target browsing context be a new browsing context navigated to the about:blank URL.

This is not really enough. For example, you arguably haven't created a Window or a Document. And we don't generally navigate to about:blank; it's the initial location on which a browsing context starts. And this gives no info on the browsing context group or agent cluster of the created browsing context.

Instead, use https://html.spec.whatwg.org/#creating-a-new-auxiliary-browsing-context . You can get a sense from reading that and the algorithms it calls, all the details you're missing. Thankfully you should just be able to call that algorithm and have it taken care of for you :).
"

Javascript and Events Support

Do PiP windows have the ability to insert JS into them? For example, if I want to display a test alert:
pipWindow.innerHTML += "<script>alert("hello world")</script>"

I tried this on Chrome 114 (Mac OS) with the experimental flags on, but it did not seem to recognize the JS.

Thanks!

React components support?

Hey guys, I need to create a specific custom Layout UI for the PiP window with React custom components, along with their business logic from hooks, state control and their styles. But I can't seem to find a proper way to do it. Is this even supported by now?

When I tried to move a button element wrapper from parent document to children window, that had event listeners attached to it such as onClick, the event got lost in the process. All the logic behind it as well for like switching visibility or controlled rendering based on some component state. It even replaced it for "null" for a different state rendering in the button. (Simple "Play" | "Pause" button element switching)

Any help related to this matter would be greatly appreciated. Keep up the good work!

Style sheet copying

Migrated from steimelchrome/steimelchrome.github.io#10

From domenic@:

"
The style sheet copying text currently says:

the CSS style sheets applied the current associated Document should be copied and applied to the target browsing context’s associated Document.

First, I suspect "should" is not intended here (i.e., the behavior is not optional).

Second, there often is more than one CSS style sheet applied to a document. There can be many, in fact: some from <style>, some from , some from adoptedStyleSheets... Which ones do you want to copy? As per steimelchrome/steimelchrome.github.io#6, you need to navigate to each of these collections in a precise manner, and gather up the appropriate objects to copy over.

Third, what exactly are the appropriate objects to copy over, and what does copying mean? Are you going to insert a <style> for each source <style>, a for each source , etc.? What if some of them failed to load? Are you going to copy over the text exactly, including e.g. syntax errors and exact whitespace, or will you instead copy over some serialization and then deserialize it? All of these things are observable.
"

WindowControlOverlay for Document PiP API

Can we have a option to customize the titlebar (like WindowControlOverlay) if it's in a PWA?
image

For example, can we customize the yellow area like WindowControlOverlay (with keeping blue area).

"The PiP window will never outlive the opening window" is not specified

I found this by chance reading the non-normative introduction.

What exactly is meant by "opening window"? Is it the exact Window object, so e.g. if I navigate the opener from one page to a different one, the PiP window should close? Or is it the navigable (~ browser tab), so I could go across multiple pages and keep the PiP window open? Or something in between?

window getter steps not precise enough

Return the last Window opened by this if it exists and is still open. Otherwise, return null.

This Window should be stored on the DocumentPictureInPicture object, so you can do something like "Return this's last-opened window."

Then, that "last-opened window" field can be updated at clear points in time, probably right before the last step of requestWindow()? Or maybe as part of the queued task in step 15? (The difference is observable, by synchronously checking documentPictureInPicture.window after calling requestWindow().)

"The PiP window cannot be navigated" is not specified

I only found this by accident by reading the non-normative introduction:

The PiP window cannot be navigated (any window.history or window.location calls that change to a new document will close the PiP window).

Is this still intended to be implemented? If so, we've got some fun ahead of us, figuring out how to spec it. Some questions to answer:

  • Are same-document navigations, e.g. history.pushState() or location.hash = "foo", OK?
  • What about navigations that target a Content-Disposition: attachment or status-code 204/205 destination? Those never actually move to a new document. (But, we only find out after doing a network round trip.)

Support smaller sizes than 300x300

Hi, since the spec doesn't have a limitation on the minimum size, would it be possible to allow creating a window smaller than 300x300?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.