window.open with features

This document describes how the features parameter of window.open interacts with where the newly created browsing context is opened.

The purpose of this document is to simplify the Firefox's behavior, which is tracked in bug 1507375.

This document is created based on observation (with testcase) and some code reading, if you found any issue, feel free to file an issue.

Modify window open steps

After "step 8. Let target browsing context and new be...", insert:

  1. If new is true, then:
    1. Let windowFeature be GetWindowFeature(tokenizedFeatures)
    2. If browser-dependent IsPopup(windowFeature) is true, then:
      1. Let the target browsing context be in a new popup
    3. Else:
      1. If browser-dependent IsNewWindow(windowFeature) is true, then:
        1. Let the target browsing context be in a new tab in a new window
      2. Else if browser-dependent IsNewTab(windowFeature) is true, then:
        1. If the current window is a popup, then:
          1. If browser-dependent UseMostRecentWindow() is true, then:
            1. Let the target browsing context be in a new tab in the most recent window.
          2. Else:
            1. Let the target browsing context be in a new tab in a new window.
        2. Else:
          1. Let the target browsing context be in a new tab in the current window.
      3. Else:
        1. Let the target browsing context be in the current tab

Additional algorithms

GetWindowFeature(tokenizedFeatures)

  1. Let windowFeature be a new Record.
  2. If tokenizedFeatures is empty, then:
    1. Set windowFeature.[[location]] to true.
    2. Set windowFeature.[[menubar]] to true.
    3. Set windowFeature.[[resizable]] to true.
    4. Set windowFeature.[[scrollbars]] to true.
    5. Set windowFeature.[[status]] to true.
    6. Set windowFeature.[[toolbar]] to true.
    7. Set windowFeature.[[width]] to false.
    8. Set windowFeature.[[height]] to false.
    9. Return windowFeature.
  3. Set windowFeature.[[location]] to false.
  4. Set windowFeature.[[menubar]] to false.
  5. Set windowFeature.[[resizable]] to true.
  6. Set windowFeature.[[scrollbars]] to false.
  7. Set windowFeature.[[status]] to false.
  8. Set windowFeature.[[toolbar]] to false.
  9. Set windowFeature.[[width]] to false.
  10. Set windowFeature.[[height]] to false.
  11. If tokenizedFeatures contains an entry with the key "location", then:
    1. Set windowFeature.[[location]] to the result of parsing tokenizedFeatures["location"] as a boolean feature.
  12. If tokenizedFeatures contains an entry with the key "menubar", then:
    1. Set windowFeature.[[menubar]] to the result of parsing tokenizedFeatures["menubar"] as a boolean feature.
  13. If tokenizedFeatures contains an entry with the key "resizable", then:
    1. Set windowFeature.[[resizable]] to the result of parsing tokenizedFeatures["resizable"] as a boolean feature.
  14. If tokenizedFeatures contains an entry with the key "scrollbars", then:
    1. Set windowFeature.[[scrollbars]] to the result of parsing tokenizedFeatures["scrollbars"] as a boolean feature.
  15. If tokenizedFeatures contains an entry with the key "status", then:
    1. Set windowFeature.[[status]] to the result of parsing tokenizedFeatures["status"] as a boolean feature.
  16. If tokenizedFeatures contains an entry with the key "toolbar", then:
    1. Set windowFeature.[[toolbar]] to the result of parsing tokenizedFeatures["toolbar"] as a boolean feature.
  17. If tokenizedFeatures contains an entry with the key "width" or "innerWidth", then:
    1. Set windowFeature.[[width]] to true
  18. If tokenizedFeatures contains an entry with the key "height" or "innerHeight", then:
    1. Set windowFeature.[[height]] to true
  19. Return windowFeature.

browser-dependent IsPopup(windowFeature)

Chrome's behavior / new Edge's behavior

  1. If windowFeature.[[location]] and windowFeature.[[toolbar]] are both false, then:
    1. Return true.
  2. If windowFeature.[[menubar]] is false, then:
    1. Return true.
  3. If windowFeature.[[resizable]] is false, then:
    1. Return true.
  4. If windowFeature.[[scrollbars]] is false, then:
    1. Return true.
  5. If windowFeature.[[status]] is false, then:
    1. Return true.
  6. Return false.

Safari's behavior

  1. If windowFeature.[[width]] is true, then:
    1. Return true.
  2. Return false.

old Edge's behavior

  1. If windowFeature.[[location]] is false, then:
    1. Return true.
  2. If windowFeature.[[menubar]] is false, then:
    1. Return true.
  3. If windowFeature.[[toolbar]] is false, then:
    1. Return true.
  4. If windowFeature.[[resizable]] is false, then:
    1. Return true.
  5. If windowFeature.[[scrollbars]] is false, then:
    1. Return true.
  6. If windowFeature.[[status]] is false, then:
    1. Return true.
  7. Return false.

Proposed Firefox's behavior

  1. If windowFeature.[[location]] and windowFeature.[[toolbar]] are both false, then:
    1. Return true.
  2. If windowFeature.[[menubar]] is false, then:
    1. Return true.
  3. If windowFeature.[[resizable]] is false, then:
    1. Return true.
  4. If windowFeature.[[scrollbars]] is false, then:
    1. Return true.
  5. If windowFeature.[[status]] is false, then:
    1. Return true.
  6. If windowFeature.[[width]] is true, then:
    1. Return true.
  7. Return false.

browser-dependent IsNewWindow(windowFeature)

Chrome's behavior / new Edge's behavior

  1. Return false.

Safari's behavior

  1. If windowFeature.[[scrollbars]] is false, then:
    1. Return true.
  2. If windowFeature.[[status]] is false, then:
    1. Return true.
  3. If windowFeature.[[toolbar]] is false, then:
    1. Return true.
  4. If windowFeature.[[height]] is true, then:
    1. Return true.
  5. Return false.

old Edge's behavior

  1. Return false.

Proposed Firefox's behavior

  1. if browser.link.open_newwindow pref is 2, then:
    1. Return true
  2. Else
    1. Return false

browser-dependent IsNewTab(windowFeature)

Chrome's behavior / new Edge's behavior

  1. Return true.

Safari's behavior

  1. Return true.

old Edge's behavior

  1. Return true.

Proposed Firefox's behavior

  1. if browser.link.open_newwindow pref is 3 (default value), then:
    1. Return true
  2. Else
    1. Return false

Opening a new popup

  1. Open a popup which with browser-dependent popup style.
  2. Scrollbars are shown if necessary.
  3. The popup is resizable.
  4. tokenizedFeatures and windowFeature don't affect UI parts. except position and size (step 10 in window open steps).

  1. A popup has only title bar and location bar as UI parts.
  1. A popup has only title bar as UI parts.
  1. A popup has only title bar and location bar as UI parts.
  1. A popup has only title bar and location bar as UI parts.

Opening a new window

  1. Open a normal window which has all UI parts.

    tokenizedFeatures and windowFeature don't affect UI parts.

browser-dependent UseMostRecentWindow()

Chrome's behavior / new Edge's behavior

  1. If there's other window, then:
    1. Return true
  2. Else:
    1. Return false

Safari's behavior

  1. If there's other window, then:
    1. Return true
  2. Else:
    1. Return false

old Edge's behavior

  1. Return false

Proposed Firefox's behavior

  1. If there's other window, then:
    1. Return true
  2. Else:
    1. Return false