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 and bug 1661643.

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 10. Let new be true if windowType is either...", 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. Otherwise, if browser-dependent IsNewWindow(windowFeature) is true, then:
      1. Let the target browsing context be in a new tab in a new window
    4. Otherwise, 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. Otherwise:
        1. Let the target browsing context be in a new tab in a new window.
    5. Otherwise:
      1. Let the target browsing context be in a new tab in the current window.

Additional algorithms

GetWindowFeature(tokenizedFeatures)

  1. Let windowFeature be a new ordered map.
  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", then:
    1. Set windowFeature["width"] to true
  18. If tokenizedFeatures contains an entry with the key "height", 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.

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.

Firefox's behavior

  1. if browser.link.open_newwindow pref is 2, then:
    1. Return true
  2. Otherwise:
    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. Otherwise:
    1. Return false

Safari's behavior

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

old Edge's behavior

  1. Return false

Firefox's behavior

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