├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── 0-new-issue.yml │ ├── 1-new-feature.yml │ └── config.yml └── workflows │ └── build.yml ├── .gitignore ├── .pr-preview.json ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── fullscreen.bs └── review-drafts ├── 2018-07.bs ├── 2019-01.bs ├── 2019-07.bs ├── 2020-01.bs ├── 2020-07.bs ├── 2021-01.bs ├── 2022-01.bs ├── 2023-01.bs ├── 2023-07.bs └── 2024-07.bs /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_size = 2 8 | indent_style = space 9 | trim_trailing_whitespace = true 10 | max_line_length = 100 11 | 12 | [Makefile] 13 | indent_style = tab 14 | 15 | [*.md] 16 | max_line_length = off 17 | 18 | [*.bs] 19 | indent_size = 1 20 | 21 | [*.py] 22 | indent_size = 4 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.bs diff=html linguist-language=HTML 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/0-new-issue.yml: -------------------------------------------------------------------------------- 1 | name: New issue 2 | description: File a new issue against the Fullscreen API Standard. 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct). You might also find the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) useful. 8 | 9 | If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). 10 | - type: textarea 11 | attributes: 12 | label: "What is the issue with the Fullscreen API Standard?" 13 | validations: 14 | required: true 15 | - type: markdown 16 | attributes: 17 | value: "Thank you for taking the time to improve the Fullscreen API Standard!" 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-new-feature.yml: -------------------------------------------------------------------------------- 1 | name: New feature 2 | description: Request a new feature in the Fullscreen API Standard. 3 | labels: ["addition/proposal", "needs implementer interest"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct), [FAQ](https://whatwg.org/faq), and [Working Mode](https://whatwg.org/working-mode). They help with setting expectations and making sure you know what is required. The FAQ ["How should I go about proposing new features to WHATWG standards?"](https://whatwg.org/faq#adding-new-features) is especially relevant. 9 | 10 | If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). 11 | - type: textarea 12 | attributes: 13 | label: "What problem are you trying to solve?" 14 | validations: 15 | required: true 16 | - type: textarea 17 | attributes: 18 | label: "What solutions exist today?" 19 | - type: textarea 20 | attributes: 21 | label: "How would you solve it?" 22 | - type: textarea 23 | attributes: 24 | label: "Anything else?" 25 | - type: markdown 26 | attributes: 27 | value: "Thank you for taking the time to improve the Fullscreen API Standard!" 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Chat 4 | url: https://whatwg.org/chat 5 | about: Please do reach out with questions and feedback! 6 | - name: Stack Overflow 7 | url: https://stackoverflow.com/ 8 | about: If you're having trouble building a web page, this is not the right repository. Consider asking your question on Stack Overflow instead. 9 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | name: Build 15 | runs-on: ubuntu-22.04 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 2 20 | - uses: actions/setup-python@v5 21 | with: 22 | python-version: "3.11" 23 | - run: pip install bikeshed && bikeshed update 24 | # Note: `make deploy` will do a deploy dry run on PRs. 25 | - run: make deploy 26 | env: 27 | SERVER: ${{ secrets.MARQUEE_SERVER }} 28 | SERVER_PUBLIC_KEY: ${{ secrets.MARQUEE_PUBLIC_KEY }} 29 | SERVER_DEPLOY_KEY: ${{ secrets.MARQUEE_DEPLOY_KEY }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /fullscreen.spec.whatwg.org/ 2 | /deploy.sh 3 | /fullscreen.html 4 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "fullscreen.bs", 3 | "type": "bikeshed", 4 | "params": { 5 | "force": 1, 6 | "md-status": "LS-PR", 7 | "md-Text-Macro": "PR-NUMBER {{ pull_request.number }}" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please see the [contributor guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md). 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 2 | 3 | This work is licensed under a Creative Commons Attribution 4.0 International 4 | License. To the extent portions of it are incorporated into source code, 5 | such portions in the source code are licensed under the BSD 3-Clause License instead. 6 | 7 | - - - - 8 | 9 | Creative Commons Attribution 4.0 International Public License 10 | 11 | By exercising the Licensed Rights (defined below), You accept and agree 12 | to be bound by the terms and conditions of this Creative Commons 13 | Attribution 4.0 International Public License ("Public License"). To the 14 | extent this Public License may be interpreted as a contract, You are 15 | granted the Licensed Rights in consideration of Your acceptance of 16 | these terms and conditions, and the Licensor grants You such rights in 17 | consideration of benefits the Licensor receives from making the 18 | Licensed Material available under these terms and conditions. 19 | 20 | 21 | Section 1 -- Definitions. 22 | 23 | a. Adapted Material means material subject to Copyright and Similar 24 | Rights that is derived from or based upon the Licensed Material 25 | and in which the Licensed Material is translated, altered, 26 | arranged, transformed, or otherwise modified in a manner requiring 27 | permission under the Copyright and Similar Rights held by the 28 | Licensor. For purposes of this Public License, where the Licensed 29 | Material is a musical work, performance, or sound recording, 30 | Adapted Material is always produced where the Licensed Material is 31 | synched in timed relation with a moving image. 32 | 33 | b. Adapter's License means the license You apply to Your Copyright 34 | and Similar Rights in Your contributions to Adapted Material in 35 | accordance with the terms and conditions of this Public License. 36 | 37 | c. Copyright and Similar Rights means copyright and/or similar rights 38 | closely related to copyright including, without limitation, 39 | performance, broadcast, sound recording, and Sui Generis Database 40 | Rights, without regard to how the rights are labeled or 41 | categorized. For purposes of this Public License, the rights 42 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 43 | Rights. 44 | 45 | d. Effective Technological Measures means those measures that, in the 46 | absence of proper authority, may not be circumvented under laws 47 | fulfilling obligations under Article 11 of the WIPO Copyright 48 | Treaty adopted on December 20, 1996, and/or similar international 49 | agreements. 50 | 51 | e. Exceptions and Limitations means fair use, fair dealing, and/or 52 | any other exception or limitation to Copyright and Similar Rights 53 | that applies to Your use of the Licensed Material. 54 | 55 | f. Licensed Material means the artistic or literary work, database, 56 | or other material to which the Licensor applied this Public 57 | License. 58 | 59 | g. Licensed Rights means the rights granted to You subject to the 60 | terms and conditions of this Public License, which are limited to 61 | all Copyright and Similar Rights that apply to Your use of the 62 | Licensed Material and that the Licensor has authority to license. 63 | 64 | h. Licensor means the individual(s) or entity(ies) granting rights 65 | under this Public License. 66 | 67 | i. Share means to provide material to the public by any means or 68 | process that requires permission under the Licensed Rights, such 69 | as reproduction, public display, public performance, distribution, 70 | dissemination, communication, or importation, and to make material 71 | available to the public including in ways that members of the 72 | public may access the material from a place and at a time 73 | individually chosen by them. 74 | 75 | j. Sui Generis Database Rights means rights other than copyright 76 | resulting from Directive 96/9/EC of the European Parliament and of 77 | the Council of 11 March 1996 on the legal protection of databases, 78 | as amended and/or succeeded, as well as other essentially 79 | equivalent rights anywhere in the world. 80 | 81 | k. You means the individual or entity exercising the Licensed Rights 82 | under this Public License. Your has a corresponding meaning. 83 | 84 | 85 | Section 2 -- Scope. 86 | 87 | a. License grant. 88 | 89 | 1. Subject to the terms and conditions of this Public License, 90 | the Licensor hereby grants You a worldwide, royalty-free, 91 | non-sublicensable, non-exclusive, irrevocable license to 92 | exercise the Licensed Rights in the Licensed Material to: 93 | 94 | a. reproduce and Share the Licensed Material, in whole or 95 | in part; and 96 | 97 | b. produce, reproduce, and Share Adapted Material. 98 | 99 | 2. Exceptions and Limitations. For the avoidance of doubt, where 100 | Exceptions and Limitations apply to Your use, this Public 101 | License does not apply, and You do not need to comply with 102 | its terms and conditions. 103 | 104 | 3. Term. The term of this Public License is specified in Section 105 | 6(a). 106 | 107 | 4. Media and formats; technical modifications allowed. The 108 | Licensor authorizes You to exercise the Licensed Rights in 109 | all media and formats whether now known or hereafter created, 110 | and to make technical modifications necessary to do so. The 111 | Licensor waives and/or agrees not to assert any right or 112 | authority to forbid You from making technical modifications 113 | necessary to exercise the Licensed Rights, including 114 | technical modifications necessary to circumvent Effective 115 | Technological Measures. For purposes of this Public License, 116 | simply making modifications authorized by this Section 2(a) 117 | (4) never produces Adapted Material. 118 | 119 | 5. Downstream recipients. 120 | 121 | a. Offer from the Licensor -- Licensed Material. Every 122 | recipient of the Licensed Material automatically 123 | receives an offer from the Licensor to exercise the 124 | Licensed Rights under the terms and conditions of this 125 | Public License. 126 | 127 | b. No downstream restrictions. You may not offer or impose 128 | any additional or different terms or conditions on, or 129 | apply any Effective Technological Measures to, the 130 | Licensed Material if doing so restricts exercise of the 131 | Licensed Rights by any recipient of the Licensed 132 | Material. 133 | 134 | 6. No endorsement. Nothing in this Public License constitutes or 135 | may be construed as permission to assert or imply that You 136 | are, or that Your use of the Licensed Material is, connected 137 | with, or sponsored, endorsed, or granted official status by, 138 | the Licensor or others designated to receive attribution as 139 | provided in Section 3(a)(1)(A)(i). 140 | 141 | b. Other rights. 142 | 143 | 1. Moral rights, such as the right of integrity, are not 144 | licensed under this Public License, nor are publicity, 145 | privacy, and/or other similar personality rights; however, to 146 | the extent possible, the Licensor waives and/or agrees not to 147 | assert any such rights held by the Licensor to the limited 148 | extent necessary to allow You to exercise the Licensed 149 | Rights, but not otherwise. 150 | 151 | 2. Patent and trademark rights are not licensed under this 152 | Public License. 153 | 154 | 3. To the extent possible, the Licensor waives any right to 155 | collect royalties from You for the exercise of the Licensed 156 | Rights, whether directly or through a collecting society 157 | under any voluntary or waivable statutory or compulsory 158 | licensing scheme. In all other cases the Licensor expressly 159 | reserves any right to collect such royalties. 160 | 161 | 162 | Section 3 -- License Conditions. 163 | 164 | Your exercise of the Licensed Rights is expressly made subject to the 165 | following conditions. 166 | 167 | a. Attribution. 168 | 169 | 1. If You Share the Licensed Material (including in modified 170 | form), You must: 171 | 172 | a. retain the following if it is supplied by the Licensor 173 | with the Licensed Material: 174 | 175 | i. identification of the creator(s) of the Licensed 176 | Material and any others designated to receive 177 | attribution, in any reasonable manner requested by 178 | the Licensor (including by pseudonym if 179 | designated); 180 | 181 | ii. a copyright notice; 182 | 183 | iii. a notice that refers to this Public License; 184 | 185 | iv. a notice that refers to the disclaimer of 186 | warranties; 187 | 188 | v. a URI or hyperlink to the Licensed Material to the 189 | extent reasonably practicable; 190 | 191 | b. indicate if You modified the Licensed Material and 192 | retain an indication of any previous modifications; and 193 | 194 | c. indicate the Licensed Material is licensed under this 195 | Public License, and include the text of, or the URI or 196 | hyperlink to, this Public License. 197 | 198 | 2. You may satisfy the conditions in Section 3(a)(1) in any 199 | reasonable manner based on the medium, means, and context in 200 | which You Share the Licensed Material. For example, it may be 201 | reasonable to satisfy the conditions by providing a URI or 202 | hyperlink to a resource that includes the required 203 | information. 204 | 205 | 3. If requested by the Licensor, You must remove any of the 206 | information required by Section 3(a)(1)(A) to the extent 207 | reasonably practicable. 208 | 209 | 4. If You Share Adapted Material You produce, the Adapter's 210 | License You apply must not prevent recipients of the Adapted 211 | Material from complying with this Public License. 212 | 213 | 214 | Section 4 -- Sui Generis Database Rights. 215 | 216 | Where the Licensed Rights include Sui Generis Database Rights that 217 | apply to Your use of the Licensed Material: 218 | 219 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 220 | to extract, reuse, reproduce, and Share all or a substantial 221 | portion of the contents of the database; 222 | 223 | b. if You include all or a substantial portion of the database 224 | contents in a database in which You have Sui Generis Database 225 | Rights, then the database in which You have Sui Generis Database 226 | Rights (but not its individual contents) is Adapted Material; and 227 | 228 | c. You must comply with the conditions in Section 3(a) if You Share 229 | all or a substantial portion of the contents of the database. 230 | 231 | For the avoidance of doubt, this Section 4 supplements and does not 232 | replace Your obligations under this Public License where the Licensed 233 | Rights include other Copyright and Similar Rights. 234 | 235 | 236 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 237 | 238 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 239 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 240 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 241 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 242 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 243 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 244 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 245 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 246 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 247 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 248 | 249 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 250 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 251 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 252 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 253 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 254 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 255 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 256 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 257 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 258 | 259 | c. The disclaimer of warranties and limitation of liability provided 260 | above shall be interpreted in a manner that, to the extent 261 | possible, most closely approximates an absolute disclaimer and 262 | waiver of all liability. 263 | 264 | 265 | Section 6 -- Term and Termination. 266 | 267 | a. This Public License applies for the term of the Copyright and 268 | Similar Rights licensed here. However, if You fail to comply with 269 | this Public License, then Your rights under this Public License 270 | terminate automatically. 271 | 272 | b. Where Your right to use the Licensed Material has terminated under 273 | Section 6(a), it reinstates: 274 | 275 | 1. automatically as of the date the violation is cured, provided 276 | it is cured within 30 days of Your discovery of the 277 | violation; or 278 | 279 | 2. upon express reinstatement by the Licensor. 280 | 281 | For the avoidance of doubt, this Section 6(b) does not affect any 282 | right the Licensor may have to seek remedies for Your violations 283 | of this Public License. 284 | 285 | c. For the avoidance of doubt, the Licensor may also offer the 286 | Licensed Material under separate terms or conditions or stop 287 | distributing the Licensed Material at any time; however, doing so 288 | will not terminate this Public License. 289 | 290 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 291 | License. 292 | 293 | 294 | Section 7 -- Other Terms and Conditions. 295 | 296 | a. The Licensor shall not be bound by any additional or different 297 | terms or conditions communicated by You unless expressly agreed. 298 | 299 | b. Any arrangements, understandings, or agreements regarding the 300 | Licensed Material not stated herein are separate from and 301 | independent of the terms and conditions of this Public License. 302 | 303 | 304 | Section 8 -- Interpretation. 305 | 306 | a. For the avoidance of doubt, this Public License does not, and 307 | shall not be interpreted to, reduce, limit, restrict, or impose 308 | conditions on any use of the Licensed Material that could lawfully 309 | be made without permission under this Public License. 310 | 311 | b. To the extent possible, if any provision of this Public License is 312 | deemed unenforceable, it shall be automatically reformed to the 313 | minimum extent necessary to make it enforceable. If the provision 314 | cannot be reformed, it shall be severed from this Public License 315 | without affecting the enforceability of the remaining terms and 316 | conditions. 317 | 318 | c. No term or condition of this Public License will be waived and no 319 | failure to comply consented to unless expressly agreed to by the 320 | Licensor. 321 | 322 | d. Nothing in this Public License constitutes or may be interpreted 323 | as a limitation upon, or waiver of, any privileges and immunities 324 | that apply to the Licensor or You, including from the legal 325 | processes of any jurisdiction or authority. 326 | 327 | - - - - 328 | 329 | BSD 3-Clause License 330 | 331 | Redistribution and use in source and binary forms, with or without 332 | modification, are permitted provided that the following conditions are met: 333 | 334 | 1. Redistributions of source code must retain the above copyright notice, this 335 | list of conditions and the following disclaimer. 336 | 337 | 2. Redistributions in binary form must reproduce the above copyright notice, 338 | this list of conditions and the following disclaimer in the documentation 339 | and/or other materials provided with the distribution. 340 | 341 | 3. Neither the name of the copyright holder nor the names of its 342 | contributors may be used to endorse or promote products derived from 343 | this software without specific prior written permission. 344 | 345 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 346 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 347 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 348 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 349 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 350 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 351 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 352 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 353 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 354 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 355 | 356 | - - - - 357 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL=/bin/bash -o pipefail 2 | .PHONY: local remote deploy 3 | 4 | remote: fullscreen.bs 5 | @ (HTTP_STATUS=$$(curl https://api.csswg.org/bikeshed/ \ 6 | --output fullscreen.html \ 7 | --write-out "%{http_code}" \ 8 | --header "Accept: text/plain, text/html" \ 9 | -F die-on=warning \ 10 | -F md-Text-Macro="COMMIT-SHA LOCAL COPY" \ 11 | -F file=@fullscreen.bs) && \ 12 | [[ "$$HTTP_STATUS" -eq "200" ]]) || ( \ 13 | echo ""; cat fullscreen.html; echo ""; \ 14 | rm -f fullscreen.html; \ 15 | exit 22 \ 16 | ); 17 | 18 | local: fullscreen.bs 19 | bikeshed spec fullscreen.bs fullscreen.html --md-Text-Macro="COMMIT-SHA LOCAL-COPY" 20 | 21 | deploy: fullscreen.bs 22 | curl --remote-name --fail https://resources.whatwg.org/build/deploy.sh 23 | bash ./deploy.sh 24 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | - [ ] At least two implementers are interested (and none opposed): 10 | * … 11 | * … 12 | - [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at: 13 | * … 14 | - [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed: 15 | * Chromium: … 16 | * Gecko: … 17 | * WebKit: … 18 | - [ ] [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: … 19 | - [ ] The top of this comment includes a [clear commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md) to use. 20 | 21 | (See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.) 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository hosts the [Fullscreen API Standard](https://fullscreen.spec.whatwg.org/). 2 | 3 | ## Code of conduct 4 | 5 | We are committed to providing a friendly, safe, and welcoming environment for all. Please read and respect the [Code of Conduct](https://whatwg.org/code-of-conduct). 6 | 7 | ## Contribution opportunities 8 | 9 | Folks notice minor and larger issues with the Fullscreen API Standard all the time and we'd love your help fixing those. Pull requests for typographical and grammar errors are also most welcome. 10 | 11 | Issues labeled ["good first issue"](https://github.com/whatwg/fullscreen/labels/good%20first%20issue) are a good place to get a taste for editing the Fullscreen API Standard. Note that we don't assign issues and there's no reason to ask for availability either, just provide a pull request. 12 | 13 | If you are thinking of suggesting a new feature, read through the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) documents to get yourself familiarized with the process. 14 | 15 | We'd be happy to help you with all of this [on Chat](https://whatwg.org/chat). 16 | 17 | ## Pull requests 18 | 19 | In short, change `fullscreen.bs` and submit your patch, with a [good commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md). 20 | 21 | Please add your name to the Acknowledgments section in your first pull request, even for trivial fixes. The names are sorted lexicographically. 22 | 23 | To ensure your patch meets all the necessary requirements, please also see the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md). Editors of the Fullscreen API Standard are expected to follow the [Maintainer Guidelines](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md). 24 | 25 | ## Tests 26 | 27 | Tests are an essential part of the standardization process and will need to be created or adjusted as changes to the standard are made. Tests for the Fullscreen API Standard can be found in the `fullscreen/` directory of [`web-platform-tests/wpt`](https://github.com/web-platform-tests/wpt). 28 | 29 | A dashboard showing the tests running against browser engines can be seen at [wpt.fyi/results/fullscreen](https://wpt.fyi/results/fullscreen). 30 | 31 | ## Building "locally" 32 | 33 | For quick local iteration, run `make`; this will use a web service to build the standard, so that you don't have to install anything. See more in the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md#building). 34 | -------------------------------------------------------------------------------- /fullscreen.bs: -------------------------------------------------------------------------------- 1 |
  2 | Group: WHATWG
  3 | H1: Fullscreen API
  4 | Shortname: fullscreen
  5 | Text Macro: TWITTER fullscreenapi
  6 | Text Macro: LATESTRD 2024-07
  7 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
  8 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
  9 | Translation: zh-Hans https://htmlspecs.com/fullscreen/
 10 | Markup Shorthands: css no
 11 | 
12 | 13 | 25 | 26 |
 27 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 28 |     type: dfn
 29 |         text: triggered by a user generated orientation change
 30 | 
31 | 32 |
 33 | {
 34 |     "CSS": {
 35 |         "aliasOf": "CSS2"
 36 |     },
 37 |     "SVG": {
 38 |         "aliasOf": "SVG11"
 39 |     }
 40 | }
 41 | 
42 | 43 | 44 | 45 |

Terminology

46 | 47 |

This specification depends on the Infra Standard. [[!INFRA]] 48 | 49 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 50 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 51 | 52 | 53 | 54 |

Model

55 | 56 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 57 | unset. 58 | 59 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 60 | stated otherwise it is unset. 61 | 62 |

All documents have an associated fullscreen element. The 63 | fullscreen element is the topmost element in the document's 64 | top layer whose fullscreen flag is set, if any, and null otherwise. 65 | 66 |

All documents have an associated list of pending fullscreen events, which 67 | is an ordered set of (string, element) tuples. It is initially empty. 68 | 69 |

To fullscreen an element: 70 | 71 |

    72 |
  1. Let hideUntil be the result of running topmost popover ancestor given 73 | element, null, and false. 74 | 75 |

  2. If hideUntil is null, then set hideUntil to element's 76 | node document. 77 | 78 |

  3. Run hide all popovers until given hideUntil, false, and true. 79 | 80 |

  4. Set element's fullscreen flag. 81 | 82 |

  5. Remove from the top layer immediately given element. 83 | 84 |

  6. Add to the top layer given element. 85 |
86 | 87 |

To unfullscreen an element, unset element's 88 | fullscreen flag and iframe fullscreen flag (if any), and 89 | remove from the top layer immediately given element. 90 | 91 |

To unfullscreen a document, 92 | unfullscreen all elements, within document's 93 | top layer, whose fullscreen flag is set. 94 | 95 |


96 | 97 |
98 |

To fully exit fullscreen a document document, run these steps: 99 | 100 |

    101 |
  1. If document's fullscreen element is null, terminate these steps. 102 | 103 |

  2. Unfullscreen elements whose fullscreen flag is 104 | set, within document's top layer, except for document's 105 | fullscreen element. 106 | 107 |

  3. Exit fullscreen document. 108 |

109 |
110 | 111 |
112 |

Whenever the removing steps run with a removedNode, run 113 | these steps: 114 | 115 |

    116 |
  1. Let document be removedNode's node document. 117 | 118 |

  2. Let nodes be removedNode's 119 | shadow-including inclusive descendants that have their fullscreen flag set, in 120 | shadow-including tree order. 121 | 122 |

  3. 123 |

    For each node in nodes: 124 | 125 |

      126 |
    1. If node is document's fullscreen element, 127 | exit fullscreen document. 128 | 129 |

    2. Otherwise, unfullscreen node. 130 | 131 |

    3. 132 |

      If document's top layer contains node, 133 | remove from the top layer immediately given node. 134 | 135 |

      Other specifications can add and remove elements from top layer, so 136 | node might not be document's fullscreen element. For example, 137 | node could be an open <{dialog}> element. 138 |

    139 |
140 |
141 | 142 |

Whenever the unloading document cleanup steps run with a document, 143 | fully exit fullscreen document. 144 | 145 |


146 | 147 |

Fullscreen is supported if there is no previously-established user preference, 148 | security risk, or platform limitation. 149 | 150 |


151 | 152 |
153 |

To run the fullscreen steps for a document document, run these 154 | steps: 155 | 156 |

    157 |
  1. Let pendingEvents be document's 158 | list of pending fullscreen events. 159 | 160 |

  2. Empty document's list of pending fullscreen events. 161 | 162 |

  3. 163 |

    For each (type, element) in pendingEvents: 164 | 165 |

      166 |
    1. Let target be element if element is connected 167 | and its node document is document, and otherwise let target be 168 | document. 169 | 170 |

    2. Fire an event named type, with its {{Event/bubbles}} and 171 | {{Event/composed}} attributes set to true, at target. 172 |

    173 |
174 | 175 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 176 |

177 | 178 | 179 | 180 |

API

181 | 182 |
183 | enum FullscreenNavigationUI {
184 |   "auto",
185 |   "show",
186 |   "hide"
187 | };
188 | 
189 | dictionary FullscreenOptions {
190 |   FullscreenNavigationUI navigationUI = "auto";
191 | };
192 | 
193 | partial interface Element {
194 |   Promise<undefined> requestFullscreen(optional FullscreenOptions options = {});
195 | 
196 |   attribute EventHandler onfullscreenchange;
197 |   attribute EventHandler onfullscreenerror;
198 | };
199 | 
200 | partial interface Document {
201 |   [LegacyLenientSetter] readonly attribute boolean fullscreenEnabled;
202 |   [LegacyLenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
203 | 
204 |   Promise<undefined> exitFullscreen();
205 | 
206 |   attribute EventHandler onfullscreenchange;
207 |   attribute EventHandler onfullscreenerror;
208 | };
209 | 
210 | partial interface mixin DocumentOrShadowRoot {
211 |   [LegacyLenientSetter] readonly attribute Element? fullscreenElement;
212 | };
213 | 
214 | 216 | 217 |
218 |
promise = element . requestFullscreen([options]) 219 |
220 | Displays element fullscreen and resolves promise when done. 221 | 222 | When supplied, options's {{FullscreenOptions/navigationUI}} member indicates whether 223 | showing navigation UI while in fullscreen is preferred or not. If set to 224 | "{{FullscreenNavigationUI/show}}", navigation simplicity is preferred over screen space, and if 225 | set to "{{FullscreenNavigationUI/hide}}", more screen space is preferred. User agents are always 226 | free to honor user preference over the application's. The default value 227 | "{{FullscreenNavigationUI/auto}}" indicates no application preference. 228 | 229 |
document . {{Document/fullscreenEnabled}} 230 |

Returns true if document has the ability to display elements fullscreen 231 | and fullscreen is supported, or false otherwise. 232 | 233 |

promise = document . {{Document/exitFullscreen()}} 234 |

Stops document's fullscreen element from being displayed fullscreen and 235 | resolves promise when done. 236 | 237 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 238 |

Returns document's fullscreen element. 239 | 240 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 241 |

Returns shadowroot's fullscreen element. 242 |

243 | 244 |

A fullscreen element ready check for an element element returns true 245 | if all of the following are true, and false otherwise: 246 | 247 |

258 | 259 |
260 |

The requestFullscreen(options) method steps 261 | are: 262 | 263 |

    264 |
  1. Let pendingDoc be this's node document. 265 | 266 |

  2. Let promise be a new promise. 267 | 268 |

  3. If pendingDoc is not fully active, then reject promise with a 269 | {{TypeError}} exception and return promise. 270 | 271 |

  4. Let error be false. 272 | 273 |

  5. 274 |

    If any of the following conditions are false, then set error to true: 275 | 276 |

    292 | 293 |
  6. If error is false, then consume user activation given 294 | pendingDoc's relevant global object. 295 | 296 |

  7. Return promise, and run the remaining steps in parallel. 297 | 298 |

  8. 299 |

    If error is false, then resize pendingDoc's node navigable's 300 | top-level traversable's active document's viewport's 301 | dimensions, optionally taking into account 302 | options["{{FullscreenOptions/navigationUI}}"]: 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 |
    valueviewport dimensions
    "hide"full dimensions of the screen of the output device
    "show"dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls
    "auto"user-agent defined, but matching one of the above
    327 | 328 |

    Optionally display a message how the end user can revert this. 329 | 330 |

  9. 331 |

    If any of the following conditions are false, then set error to true: 332 | 333 |

    339 | 340 |
  10. 341 |

    If error is true: 342 | 343 |

      344 |
    1. Append ({{fullscreenerror}}, this) to 345 | pendingDoc's list of pending fullscreen events. 346 | 347 |

    2. Reject promise with a {{TypeError}} exception and terminate these 348 | steps. 349 |

    350 | 351 |
  11. Let fullscreenElements be an ordered set initially consisting of 352 | this. 353 | 354 |

  12. 355 |

    While true: 356 | 357 |

      358 |
    1. Let last be the last item of fullscreenElements. 359 | 360 |

    2. Let container be last's node navigable's 361 | container. 362 | 363 |

    3. If container is null, then break. 364 | 365 |

    4. Append container to fullscreenElements. 366 |

    367 |
  13. 368 | 369 | 370 |
  14. 371 |

    For each element in fullscreenElements: 372 | 373 |

      374 |
    1. Let doc be element's node document. 375 | 376 |

    2. 377 |

      If element is doc's fullscreen element, continue. 378 | 379 |

      No need to notify observers when nothing has changed. 380 | 381 |

    3. If element is this and this is an <{iframe}> 382 | element, then set element's iframe fullscreen flag. 383 | 384 |

    4. Fullscreen element within doc. 385 | 386 |

    5. Append ({{fullscreenchange}}, element) to 387 | doc's list of pending fullscreen events. 388 |

    389 | 390 |

    The order in which elements are fullscreened 391 | is not observable, because run the fullscreen steps is invoked in tree order. 392 | 393 |

  15. Resolve promise with undefined. 394 |

395 | 396 |

Implementations with out-of-process navigables are left as an exercise 397 | to the reader. Input welcome on potential improvements. 398 |

399 | 400 |

The fullscreenEnabled getter steps are to return 401 | true if this is allowed to use the "fullscreen" feature and fullscreen is supported, and 403 | false otherwise. 404 | 405 |

The fullscreen getter steps are to return false if 406 | this's fullscreen element is null, and true otherwise. 407 | 408 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 409 | 410 |

411 |

The 412 | fullscreenElement 413 | getter steps are: 414 | 415 |

    416 |
  1. If this is a shadow root and its host is not 417 | connected, then return null. 418 | 419 |

  2. Let candidate be the result of retargeting fullscreen element 420 | against this. 421 | 422 |

  3. If candidate and this are in the same tree, then return 423 | candidate. 424 | 425 |

  4. Return null. 426 |

427 |
428 | 429 |

A document is said to be a simple fullscreen document if there is exactly one 430 | element in its top layer that has its fullscreen flag set. 431 | 432 |

A document with two elements in its top layer can be a 433 | simple fullscreen document. For example, in addition to the fullscreen element there 434 | could be an open <{dialog}> element. 435 | 436 |

437 |

To collect documents to unfullscreen given doc, run these steps: 438 | 439 |

    440 |
  1. Let docs be an ordered set consisting of doc. 441 | 442 |

  2. 443 |

    While true: 444 | 445 |

      446 |
    1. Let lastDoc be docs's last document. 447 | 448 |

    2. Assert: lastDoc's fullscreen element is not null. 449 | 450 |

    3. If lastDoc is not a simple fullscreen document, break. 451 | 452 |

    4. Let container be lastDoc's node navigable's 453 | container. 454 | 455 |

    5. If container is null, then break. 456 | 457 |

    6. If container's iframe fullscreen flag is set, break. 458 | 459 |

    7. Append container's node document to docs. 460 |

    461 | 462 |
  3. Return docs. 463 | 464 |

    This is the set of documents for which the fullscreen element will be 465 | unfullscreened, but the last document in docs might 466 | have more than one element in its top layer with the fullscreen flag set, 467 | in which case that document will still remain in fullscreen. 468 |

469 |
470 | 471 |
472 |

To exit fullscreen a document doc, run these steps: 473 | 474 |

    475 |
  1. Let promise be a new promise. 476 | 477 |

  2. If doc is not fully active or doc's fullscreen element 478 | is null, then reject promise with a {{TypeError}} exception and return 479 | promise. 480 | 481 |

  3. Let resize be false. 482 | 483 |

  4. Let docs be the result of 484 | collecting documents to unfullscreen given 485 | doc. 486 | 487 | 488 |

  5. Let topLevelDoc be doc's node navigable's 489 | top-level traversable's active document. 490 | 491 | 492 |

  6. If topLevelDoc is in docs, and it is a 493 | simple fullscreen document, then set doc to topLevelDoc and 494 | resize to true. 495 | 496 |

  7. If doc's fullscreen element is not connected: 497 |

      498 |
    1. Append ({{fullscreenchange}}, doc's fullscreen element) 499 | to doc's list of pending fullscreen events. 500 | 501 |

    2. Unfullscreen doc's fullscreen 502 | element. 503 |

    504 | 505 |
  8. Return promise, and run the remaining steps in parallel. 506 | 507 |

  9. Run the [=fully unlock the screen orientation steps=] with doc. 508 | 509 |

  10. If resize is true, resize doc's viewport to its "normal" dimensions. 510 | 511 |

  11. If doc's fullscreen element is null, then resolve promise with 512 | undefined and terminate these steps. 513 | 514 |

  12. Let exitDocs be the result of 515 | collecting documents to unfullscreen given 516 | doc. 517 | 518 | 519 |

  13. Let descendantDocs be an ordered set consisting of doc's 520 | descendant navigables' active documents whose 521 | fullscreen element is non-null, if any, in tree order. 522 | 523 | 524 |

  14. 525 |

    For each exitDoc in exitDocs: 526 | 527 |

      528 |
    1. Append ({{fullscreenchange}}, exitDoc's 529 | fullscreen element) to exitDoc's list of pending fullscreen events. 530 | 531 |

    2. If resize is true, unfullscreen 532 | exitDoc. 533 | 534 |

    3. Otherwise, unfullscreen exitDoc's 535 | fullscreen element. 536 |

    537 | 538 |
  15. 539 |

    For each descendantDoc in descendantDocs: 540 | 541 |

      542 |
    1. Append ({{fullscreenchange}}, descendantDoc's 543 | fullscreen element) to descendantDoc's 544 | list of pending fullscreen events. 545 | 546 |

    2. Unfullscreen descendantDoc. 547 |

    548 | 549 |

    The order in which documents are unfullscreened 550 | is not observable, because run the fullscreen steps is invoked in tree order. 551 | 552 |

  16. Resolve promise with undefined. 553 |

554 |
555 | 556 |

The exitFullscreen() method steps are to return the 557 | result of running exit fullscreen on this. 558 | 559 |


560 | 561 |

The following are the event handlers (and their corresponding 562 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 563 | event handler IDL attributes: 564 | 565 | 566 | 567 | 568 | 571 | 572 | 575 |
event handler 569 | event handler event type 570 |
onfullscreenchange 573 | fullscreenchange 574 |
onfullscreenerror 576 | fullscreenerror 577 |
578 | 579 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 580 | corresponding event handler content attributes for {{Element}} objects in any namespace. 581 | 582 | 583 | 584 |

UI

585 | 586 |

User agents are encouraged to implement native media fullscreen controls in terms of 587 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 588 | 589 |

If the end user instructs the user agent to end a fullscreen session initiated via 590 | {{Element/requestFullscreen()}}, fully exit fullscreen given the 591 | top-level traversable's active document. 592 | 593 |

The user agent may end any fullscreen session without instruction from the end user 594 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 595 | 596 | 597 | 598 |

Rendering

599 | 600 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 601 | 602 | 603 |

:fullscreen pseudo-class

604 | 605 |

The :fullscreen pseudo-class must match any 606 | element element for which one of the following conditions is true: 607 | 608 |

614 | 615 |

This makes it different from the 616 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 617 | 618 |

User-agent level style sheet defaults

619 | 620 | 621 |
622 | @namespace "http://www.w3.org/1999/xhtml";
623 | 
624 | *|*:not(:root):fullscreen {
625 |   position:fixed !important;
626 |   inset:0 !important;
627 |   margin:0 !important;
628 |   box-sizing:border-box !important;
629 |   min-width:0 !important;
630 |   max-width:none !important;
631 |   min-height:0 !important;
632 |   max-height:none !important;
633 |   width:100% !important;
634 |   height:100% !important;
635 |   transform:none !important;
636 | 
637 |   /* intentionally not !important */
638 |   object-fit:contain;
639 | }
640 | 
641 | iframe:fullscreen {
642 |   border:none !important;
643 |   padding:0 !important;
644 | }
645 | 
646 | *|*:not(:root):fullscreen::backdrop {
647 |   background:black;
648 | }
649 | 
650 | 651 | 652 | 653 |

Permissions Policy 654 | Integration

655 | 656 |

This specification defines a policy-controlled feature identified by the string 657 | "fullscreen". Its default allowlist is 658 | 'self'. 659 | 660 |

661 |

A document's permissions policy determines whether any content in that 662 | document is allowed to go fullscreen. If disabled in any document, no content in the document will 663 | be allowed to use fullscreen. 664 | 665 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 666 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 667 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 668 | allow="fullscreen *">, as described in 669 | [[permissions-policy#iframe-allowfullscreen-attribute]]. 670 |

671 | 672 | 673 | 674 |

Security and Privacy Considerations

675 | 676 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 677 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 678 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 679 | user agent or even operating system environment when fullscreen. See also the definition of 680 | {{Element/requestFullscreen()}}. 681 | 682 |

To enable content in a child navigable to go fullscreen, it needs to be specifically 683 | allowed via permissions policy, either through the <{iframe/allowfullscreen}> attribute of the HTML 684 | <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the HTML 685 | <{iframe}> element, or through a `Permissions-Policy` HTTP header 686 | delivered with the document through which it is nested. 687 | 688 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 689 | 690 | 691 | 692 |

693 | 694 | This specification previously hosted the definitions of ::backdrop 695 | and the concept of the document's top layer. 696 | 697 | 698 | 699 |

Acknowledgments

700 | 701 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 702 | 703 | 704 |

Thanks to 705 | Andy Earnshaw, 706 | Changwan Hong, 707 | Chris Pearce, 708 | Darin Fisher, 709 | Dave Tapuska, 710 | fantasai, 711 | Giuseppe Pascale, 712 | Glenn Maynard, 713 | Ian Clelland, 714 | Ian Hickson, 715 | Ignacio Solla, 716 | João Eiras, 717 | Josh Soref, 718 | Kagami Sascha Rosylight, 719 | Matt Falkenhagen, 720 | Mihai Balan, 721 | Mounir Lamouri, 722 | Øyvind Stenhaug, 723 | Pat Ladd, 724 | Rafał Chłodnicki, 725 | Riff Jiang, 726 | Rune Lillesveen, 727 | Sigbjørn Vik, 728 | Simon Pieters, 729 | Tab Atkins-Bittner, 730 | Takayoshi Kochi, 731 | Theresa O'Connor, 732 | triple-underscore, 733 | Vincent Scheib, and 734 | Xidorn Quan 735 | for also being awesome. 736 | 737 |

This standard is edited by Philip Jägenstedt 738 | (Google, 739 | philip@foolip.org). It was originally written by 740 | Anne van Kesteren 741 | (Apple, annevk@annevk.nl). 742 | Tantek Çelik 743 | (Mozilla, 744 | tantek@cs.stanford.edu) sorted out legal hassles. 745 | -------------------------------------------------------------------------------- /review-drafts/2018-07.bs: -------------------------------------------------------------------------------- 1 |

  2 | Group: WHATWG
  3 | Date: 2018-07-23
  4 | H1: Fullscreen API
  5 | Shortname: fullscreen
  6 | Text Macro: TWITTER fullscreenapi
  7 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
  8 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
  9 | 
10 | 11 | 19 | 20 |
 21 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 22 |     type: dfn
 23 |         text: triggered by a user generated orientation change
 24 | 
25 | 26 |
 27 | {
 28 |     "CSS": {
 29 |         "aliasOf": "CSS2"
 30 |     },
 31 |     "SVG": {
 32 |         "aliasOf": "SVG11"
 33 |     }
 34 | }
 35 | 
36 | 37 | 38 | 39 |

Terminology

40 | 41 |

This specification depends on the Infra Standard. [[!INFRA]] 42 | 43 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 44 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 45 | 46 |

A browsing context A is called a descendant browsing context 47 | of a browsing context B if and only if B is an 48 | ancestor browsing context of A. 49 | 50 | 51 | 52 |

Model

53 | 54 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 55 | unset. 56 | 57 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 58 | stated otherwise it is unset. 59 | 60 |

All documents have an associated fullscreen element. The 61 | fullscreen element is the topmost element in the document's 62 | top layer whose fullscreen flag is set, if any, and null otherwise. 63 | 64 |

All documents have an associated list of pending fullscreen events, which 65 | is an ordered set of (string, element) pairs. It is initially empty. 66 | 67 |

To fullscreen an element, set element's fullscreen flag 68 | and add it to its node document's top layer. 69 | 70 |

To unfullscreen an element, unset element's 71 | fullscreen flag and iframe fullscreen flag (if any), and remove it from 72 | its node document's top layer. 73 | 74 |

To unfullscreen a document, 75 | unfullscreen all elements, within document's 76 | top layer, whose fullscreen flag is set. 77 | 78 |


79 | 80 |

To fully exit fullscreen a document document, run these steps: 81 | 82 |

    83 |
  1. If document's fullscreen element is null, terminate these steps. 84 | 85 |

  2. Unfullscreen elements whose fullscreen flag is 86 | set, within document's top layer, except for document's 87 | fullscreen element. 88 | 89 |

  3. Exit fullscreen document. 90 |

91 | 92 |

Whenever the removing steps run with a removedNode, run 93 | these steps: 94 | 95 |

    96 |
  1. Let nodes be removedNode's 97 | shadow-including inclusive descendants that have their fullscreen flag set, in 98 | shadow-including tree order. 99 | 100 |

  2. 101 |

    For each node in nodes: 102 | 103 |

      104 |
    1. If node is its node document's fullscreen element, 105 | exit fullscreen that document. 106 | 107 |

    2. Otherwise, unfullscreen node within its 108 | node document. 109 |

    110 |
111 | 112 |

Whenever the unloading document cleanup steps run with a document, 113 | fully exit fullscreen document. 114 | 115 |


116 | 117 |

Fullscreen is supported if there is no previously-established user preference, 118 | security risk, or platform limitation. 119 | 120 |

An algorithm is allowed to request fullscreen if one of the following is true: 121 | 122 |

127 | 128 | 129 |
130 | 131 |

To run the fullscreen steps for a document document, run these 132 | steps: 133 | 134 |

    135 |
  1. Let pairs be document's list of pending fullscreen events. 136 | 137 |

  2. Empty document's list of pending fullscreen events. 138 | 139 |

  3. 140 |

    For each (type, element) in pairs: 141 | 142 |

      143 |
    1. Let target be element if element is connected 144 | and its node document is document, and otherwise let target be 145 | document. 146 | 147 |

    2. Fire an event named type, with its {{Event/bubbles}} and 148 | {{Event/composed}} attributes set to true, at target. 149 |

    150 |
151 | 152 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 153 | 154 | 155 | 156 |

API

157 | 158 |
159 | partial interface Element {
160 |   Promise<void> requestFullscreen();
161 | 
162 |   attribute EventHandler onfullscreenchange;
163 |   attribute EventHandler onfullscreenerror;
164 | };
165 | 
166 | partial interface Document {
167 |   [LenientSetter] readonly attribute boolean fullscreenEnabled;
168 |   [LenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
169 | 
170 |   Promise<void> exitFullscreen();
171 | 
172 |   attribute EventHandler onfullscreenchange;
173 |   attribute EventHandler onfullscreenerror;
174 | };
175 | 
176 | partial interface DocumentOrShadowRoot {
177 |   [LenientSetter] readonly attribute Element? fullscreenElement;
178 | };
179 | 
180 | 182 | 183 |
184 |
promise = element . {{Element/requestFullscreen()}} 185 |

Displays element fullscreen and resolves promise when done. 186 | 187 |

document . {{Document/fullscreenEnabled}} 188 |

Returns true if document has the ability to display elements fullscreen 189 | and fullscreen is supported, or false otherwise. 190 | 191 |

promise = document . {{Document/exitFullscreen()}} 192 |

Stops document's fullscreen element from being displayed fullscreen and 193 | resolves promise when done. 194 | 195 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 196 |

Returns document's fullscreen element. 197 | 198 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 199 |

Returns shadowroot's fullscreen element. 200 |

201 | 202 |

A fullscreen element ready check for an element element returns true 203 | if all of the following are true, and false otherwise: 204 | 205 |

212 | 213 |

The requestFullscreen() method, when invoked, must run 214 | these steps: 215 | 216 |

    217 |
  1. Let pending be the context object. 218 | 219 |

  2. Let pendingDoc be pending's node document. 220 | 221 |

  3. Let promise be a new promise. 222 | 223 |

  4. If pendingDoc is not fully active, then reject promise with a 224 | TypeError exception and return promise. 225 | 226 |

  5. Let error be false. 227 | 228 |

  6. 229 |

    If any of the following conditions are false, then set error to true: 230 | 231 |

    246 | 247 |
  7. Return promise, and run the remaining steps in parallel. 248 | 249 |

  8. If error is false: Resize pendingDoc's 250 | top-level browsing context's active document's viewport's dimensions to match the 251 | dimensions of the screen of the output device. Optionally display a message how the end user can 252 | revert this. 253 | 254 | 255 |

  9. 256 |

    If any of the following conditions are false, then set error to true: 257 | 258 |

    264 | 265 |
  10. 266 |

    If error is true: 267 | 268 |

      269 |
    1. Append (fullscreenerror, pending) to 270 | pendingDoc's list of pending fullscreen events. 271 | 272 |

    2. Reject promise with a TypeError exception and terminate these 273 | steps. 274 |

    275 | 276 |
  11. Let fullscreenElements be an ordered set initially consisting of 277 | pending. 278 | 279 |

  12. While the first element in fullscreenElements is in a 280 | nested browsing context: append its browsing context container to 281 | fullscreenElements. 282 | 283 | 284 |

  13. 285 |

    For each element in fullscreenElements: 286 | 287 |

      288 |
    1. Let doc be element's node document. 289 | 290 |

    2. 291 |

      If element is doc's fullscreen element, continue. 292 | 293 |

      No need to notify observers when nothing has changed. 294 | 295 |

    3. If element is pending and pending is an <{iframe}> 296 | element, then set element's iframe fullscreen flag. 297 | 298 |

    4. Fullscreen element within doc. 299 | 300 |

    5. Append (fullscreenchange, element) to 301 | doc's list of pending fullscreen events. 302 |

    303 | 304 |

    The order in which elements are fullscreened 305 | is not observable, because run the fullscreen steps is invoked in tree order. 306 | 307 |

  14. Resolve promise with undefined. 308 |

309 | 310 |

Implementations with out-of-process browsing contexts are left as an 311 | exercise to the reader. Input welcome on potential improvements. 312 | 313 |

The fullscreenEnabled attribute's getter must 314 | return true if the context object is allowed to use the "fullscreen" feature and fullscreen is supported, and 316 | false otherwise. 317 | 318 |

The fullscreen attribute's getter must return 319 | false if context object's fullscreen element is null, and true otherwise. 320 | 321 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 322 | 323 |

The 324 | fullscreenElement 325 | attribute's getter must run these steps: 326 | 327 |

    328 |
  1. If the context object is a shadow root and its 329 | host is not connected, then return null.

  2. 330 | 331 |
  3. Let candidate be the result of retargeting fullscreen element 332 | against the context object. 333 | 334 |

  4. If candidate and the context object are in the same tree, then 335 | return candidate. 336 | 337 |

  5. Return null. 338 |

339 | 340 |

A document is said to be a simple fullscreen document if there is exactly one 341 | element in its top layer that has its fullscreen flag set. 342 | 343 |

A document with two elements in its top layer can be a 344 | simple fullscreen document. For example, in addition to the fullscreen element there 345 | could be an open <{dialog}> element. 346 | 347 |

To collect documents to unfullscreen given doc, run these steps: 348 | 349 |

    350 |
  1. Let docs be an ordered set consisting of doc. 351 | 352 |

  2. 353 |

    While true: 354 | 355 |

      356 |
    1. Let lastDoc be docs's last document. 357 | 358 |

    2. Assert: lastDoc's fullscreen element is not null. 359 | 360 |

    3. If lastDoc is not a simple fullscreen document, break. 361 | 362 |

    4. Let container be lastDoc's browsing context container, if 363 | any, and otherwise break. 364 | 365 |

    5. If container's iframe fullscreen flag is set, break. 366 | 367 |

    6. Append container's node document to docs. 368 |

    369 | 370 |
  3. Return docs. 371 | 372 |

    This is the set of documents for which the fullscreen element will be 373 | unfullscreened, but the last document in docs might 374 | have more than one element in its top layer with the fullscreen flag set, 375 | in which case that document will still remain in fullscreen. 376 |

377 | 378 |

To exit fullscreen a document doc, run these steps: 379 | 380 |

    381 |
  1. Let promise be a new promise. 382 | 383 |

  2. If doc is not fully active or doc's fullscreen element 384 | is null, then reject promise with a TypeError exception and return 385 | promise. 386 | 387 |

  3. Let resize be false. 388 | 389 |

  4. Let docs be the result of 390 | collecting documents to unfullscreen given 391 | doc. 392 | 393 | 394 |

  5. Let topLevelDoc be doc's top-level browsing context's 395 | active document. 396 | 397 | 398 |

  6. If topLevelDoc is in docs, and it is a 399 | simple fullscreen document, then set doc to topLevelDoc and 400 | resize to true. 401 | 402 |

  7. Return promise, and run the remaining steps in parallel. 403 | 404 |

  8. If resize is true, resize doc's viewport to its "normal" dimensions. 405 | 406 |

  9. If doc's fullscreen element is null, then resolve promise with 407 | undefined and terminate these steps. 408 | 409 |

  10. Let exitDocs be the result of 410 | collecting documents to unfullscreen given 411 | doc. 412 | 413 | 414 |

  11. Let descendantDocs be an ordered set consisting of doc's 415 | descendant browsing contexts' active documents whose fullscreen element is 416 | non-null, if any, in tree order. 417 | 418 | 419 |

  12. 420 |

    For each exitDoc in exitDocs: 421 | 422 |

      423 |
    1. Append (fullscreenchange, exitDoc's 424 | fullscreen element) to exitDoc's list of pending fullscreen events. 425 | 426 |

    2. If resize is true, unfullscreen 427 | exitDoc. 428 | 429 |

    3. Otherwise, unfullscreen exitDoc's 430 | fullscreen element. 431 |

    432 | 433 |
  13. 434 |

    For each descendantDoc in descendantDocs: 435 | 436 |

      437 |
    1. Append (fullscreenchange, descendantDoc's 438 | fullscreen element) to descendantDoc's 439 | list of pending fullscreen events. 440 | 441 |

    2. Unfullscreen descendantDoc. 442 |

    443 | 444 |

    The order in which documents are unfullscreened 445 | is not observable, because run the fullscreen steps is invoked in tree order. 446 | 447 |

  14. Resolve promise with undefined. 448 |

449 | 450 |

The exitFullscreen() method, when invoked, must 451 | return the result of running exit fullscreen on the context object. 452 | 453 |


454 | 455 |

The following are the event handlers (and their corresponding 456 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 457 | event handler IDL attributes: 458 | 459 | 460 | 461 | 462 | 465 | 466 | 469 |
event handler 463 | event handler event type 464 |
onfullscreenchange 467 | fullscreenchange 468 |
onfullscreenerror 470 | fullscreenerror 471 |
472 | 473 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 474 | corresponding event handler content attributes for {{Element}} objects in any namespace. 475 | 476 | 477 | 478 |

UI

479 | 480 |

User agents are encouraged to implement native media fullscreen controls in terms of 481 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 482 | 483 |

If the end user instructs the user agent to end a fullscreen session initiated via 484 | {{Element/requestFullscreen()}}, fully exit fullscreen the 485 | top-level browsing context's active document. 486 | 487 |

The user agent may end any fullscreen session without instruction from the end user 488 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 489 | 490 | 491 | 492 |

Rendering

493 | 494 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 495 | 496 |

Long term CSS will define the top layer concept and its associated 497 | ::backdrop pseudo-element as part of CSS' stacking context model. Patching CSS 498 | as done here is sketchy as hell. 499 | 500 | 501 |

New stacking layer

502 | 503 |

This specification introduces a new stacking layer to the 504 | Elaborate description of Stacking Contexts of CSS 505 | 2.1. It is called the top layer, comes after step 10 in the painting order, and is 506 | therefore rendered closest to the user within a viewport. Each document has one 507 | associated viewport and therefore also one top layer. [[!CSS]] 508 | 509 |

The terminology used in this and following subsection attempts to match CSS 2.1 510 | Appendix E. 511 | 512 |

The top layer is an ordered set of elements, rendered in the order they appear in 513 | the set. The last element in the set is rendered last, and thus appears on top. 514 | 515 |

The z-index property has no effect in the top layer. 516 | 517 |

Each element and ::backdrop pseudo-element in a top layer has the 518 | following characteristics: 519 | 520 |

552 | 553 |

To add an element to a top layer, 554 | remove it from top layer and then append it to 555 | top layer. 556 | 557 |

In other words, element is moved to the end of top layer if it 558 | is already present. 559 | 560 | 561 |

::backdrop pseudo-element

562 | 563 |

Each element in a top layer has a 564 | ::backdrop pseudo-element. This pseudo-element 565 | is a box rendered immediately below the element (and above the element before the element in the 566 | set, if any), within the same top layer. 567 | 568 |

The ::backdrop pseudo-element can be used to create a backdrop 569 | that hides the underlying document for an element in a top layer (such as an element that is 570 | displayed fullscreen). 571 | 572 |

It does not inherit from any element and is not inherited from. No restrictions are made on what 573 | properties apply to this pseudo-element either. 574 | 575 | 577 | 578 | 579 |

:fullscreen pseudo-class

580 | 581 |

The :fullscreen pseudo-class must match any 582 | element element for which one of the following conditions is true: 583 | 584 |

590 | 591 |

This makes it different from the 592 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 593 | 594 |

User-agent level style sheet defaults

595 | 596 | 597 |
598 | @namespace "http://www.w3.org/1999/xhtml";
599 | 
600 | *|*:not(:root):fullscreen {
601 |   position:fixed !important;
602 |   top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
603 |   margin:0 !important;
604 |   box-sizing:border-box !important;
605 |   min-width:0 !important;
606 |   max-width:none !important;
607 |   min-height:0 !important;
608 |   max-height:none !important;
609 |   width:100% !important;
610 |   height:100% !important;
611 |   transform:none !important;
612 | 
613 |   /* intentionally not !important */
614 |   object-fit:contain;
615 | }
616 | 
617 | iframe:fullscreen {
618 |   border:none !important;
619 |   padding:0 !important;
620 | }
621 | 
622 | ::backdrop {
623 |   position:fixed;
624 |   top:0; right:0; bottom:0; left:0;
625 | }
626 | 
627 | *|*:not(:root):fullscreen::backdrop {
628 |   background:black;
629 | }
630 | 
631 | 632 | 633 | 634 |

Feature Policy Integration

635 | 636 |

This specification defines a policy-controlled feature identified by the string 637 | "fullscreen". Its default allowlist is 638 | 'self'. 639 | 640 |

641 |

A document's feature policy determines whether any content in that document is allowed to 642 | go fullscreen. If disabled in any document, no content in the document will be allowed to use 643 | fullscreen. 644 | 645 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 646 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 647 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 648 | allow="fullscreen *">, as described in 649 | [[FEATURE-POLICY#iframe-allowfullscreen-attribute]]. 650 |

651 | 652 | 653 |

Security and Privacy Considerations

654 | 655 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 656 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 657 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 658 | user agent or even operating system environment when fullscreen. See also the definition of 659 | {{Element/requestFullscreen()}}. 660 | 661 |

To enable content in a nested browsing context to go fullscreen, it needs to be 662 | specifically allowed via feature policy, either through the <{iframe/allowfullscreen}> attribute of 663 | the HTML <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the 664 | HTML <{iframe}> element, or through a `Feature-Policy` HTTP header 665 | delivered with the document through which it is nested. 666 | 667 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 668 | 669 | 670 | 671 |

Acknowledgments

672 | 673 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 674 | 675 | 676 |

Thanks to 677 | Andy Earnshaw, 678 | Chris Pearce, 679 | Darin Fisher, 680 | fantasai, 681 | Giuseppe Pascale, 682 | Glenn Maynard, 683 | Ian Clelland, 684 | Ian Hickson, 685 | Ignacio Solla, 686 | João Eiras, 687 | Josh Soref, 688 | Matt Falkenhagen, 689 | Mihai Balan, 690 | Mounir Lamouri, 691 | Øyvind Stenhaug, 692 | Pat Ladd, 693 | Rafał Chłodnicki, 694 | Riff Jiang, 695 | Rune Lillesveen, 696 | Sigbjørn Vik, 697 | Simon Pieters, 698 | Tab Atkins, 699 | Takayoshi Kochi, 700 | Theresa O'Connor, 701 | triple-underscore, 702 | Vincent Scheib, and 703 | Xidorn Quan 704 | for also being awesome. 705 | 706 |

This standard is edited by Philip Jägenstedt 707 | (Google, 708 | philip@foolip.org). It was originally written by 709 | Anne van Kesteren 710 | (Mozilla, 711 | annevk@annevk.nl). 712 | Tantek Çelik 713 | (Mozilla, 714 | tantek@cs.stanford.edu) sorted out legal hassles. 715 | -------------------------------------------------------------------------------- /review-drafts/2019-01.bs: -------------------------------------------------------------------------------- 1 |

  2 | Group: WHATWG
  3 | Date: 2019-01-23
  4 | H1: Fullscreen API
  5 | Shortname: fullscreen
  6 | Text Macro: TWITTER fullscreenapi
  7 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
  8 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
  9 | Markup Shorthands: css no
 10 | 
11 | 12 | 20 | 21 |
 22 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 23 |     type: dfn
 24 |         text: triggered by a user generated orientation change
 25 | 
26 | 27 |
 28 | {
 29 |     "CSS": {
 30 |         "aliasOf": "CSS2"
 31 |     },
 32 |     "SVG": {
 33 |         "aliasOf": "SVG11"
 34 |     }
 35 | }
 36 | 
37 | 38 | 39 | 40 |

Terminology

41 | 42 |

This specification depends on the Infra Standard. [[!INFRA]] 43 | 44 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 45 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 46 | 47 |

A browsing context A is called a descendant browsing context 48 | of a browsing context B if and only if B is an 49 | ancestor browsing context of A. 50 | 51 | 52 | 53 |

Model

54 | 55 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 56 | unset. 57 | 58 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 59 | stated otherwise it is unset. 60 | 61 |

All documents have an associated fullscreen element. The 62 | fullscreen element is the topmost element in the document's 63 | top layer whose fullscreen flag is set, if any, and null otherwise. 64 | 65 |

All documents have an associated list of pending fullscreen events, which 66 | is an ordered set of (string, element) pairs. It is initially empty. 67 | 68 |

To fullscreen an element, set element's fullscreen flag 69 | and add it to its node document's top layer. 70 | 71 |

To unfullscreen an element, unset element's 72 | fullscreen flag and iframe fullscreen flag (if any), and remove it from 73 | its node document's top layer. 74 | 75 |

To unfullscreen a document, 76 | unfullscreen all elements, within document's 77 | top layer, whose fullscreen flag is set. 78 | 79 |


80 | 81 |

To fully exit fullscreen a document document, run these steps: 82 | 83 |

    84 |
  1. If document's fullscreen element is null, terminate these steps. 85 | 86 |

  2. Unfullscreen elements whose fullscreen flag is 87 | set, within document's top layer, except for document's 88 | fullscreen element. 89 | 90 |

  3. Exit fullscreen document. 91 |

92 | 93 |

Whenever the removing steps run with a removedNode, run 94 | these steps: 95 | 96 |

    97 |
  1. Let document be removedNode's node document. 98 | 99 |

  2. Let nodes be removedNode's 100 | shadow-including inclusive descendants that have their fullscreen flag set, in 101 | shadow-including tree order. 102 | 103 |

  3. 104 |

    For each node in nodes: 105 | 106 |

      107 |
    1. If node is document's fullscreen element, 108 | exit fullscreen document. 109 | 110 |

    2. Otherwise, unfullscreen node. 111 | 112 |

    3. 113 |

      If document's top layer contains node, 114 | remove node from document's top layer. 115 | 116 |

      Other specifications can add and remove elements from top layer, so 117 | node might not be document's fullscreen element. For example, 118 | node could be an open <{dialog}> element. 119 |

    120 |
121 | 122 |

Whenever the unloading document cleanup steps run with a document, 123 | fully exit fullscreen document. 124 | 125 |


126 | 127 |

Fullscreen is supported if there is no previously-established user preference, 128 | security risk, or platform limitation. 129 | 130 |

An algorithm is allowed to request fullscreen if one of the following is true: 131 | 132 |

137 | 138 | 139 |
140 | 141 |

To run the fullscreen steps for a document document, run these 142 | steps: 143 | 144 |

    145 |
  1. Let pairs be document's list of pending fullscreen events. 146 | 147 |

  2. Empty document's list of pending fullscreen events. 148 | 149 |

  3. 150 |

    For each (type, element) in pairs: 151 | 152 |

      153 |
    1. Let target be element if element is connected 154 | and its node document is document, and otherwise let target be 155 | document. 156 | 157 |

    2. Fire an event named type, with its {{Event/bubbles}} and 158 | {{Event/composed}} attributes set to true, at target. 159 |

    160 |
161 | 162 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 163 | 164 | 165 | 166 |

API

167 | 168 |
169 | enum FullscreenNavigationUI {
170 |   "auto",
171 |   "show",
172 |   "hide"
173 | };
174 | 
175 | dictionary FullscreenOptions {
176 |   FullscreenNavigationUI navigationUI = "auto";
177 | };
178 | 
179 | partial interface Element {
180 |   Promise<void> requestFullscreen(optional FullscreenOptions options);
181 | 
182 |   attribute EventHandler onfullscreenchange;
183 |   attribute EventHandler onfullscreenerror;
184 | };
185 | 
186 | partial interface Document {
187 |   [LenientSetter] readonly attribute boolean fullscreenEnabled;
188 |   [LenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
189 | 
190 |   Promise<void> exitFullscreen();
191 | 
192 |   attribute EventHandler onfullscreenchange;
193 |   attribute EventHandler onfullscreenerror;
194 | };
195 | 
196 | partial interface mixin DocumentOrShadowRoot {
197 |   [LenientSetter] readonly attribute Element? fullscreenElement;
198 | };
199 | 
200 | 202 | 203 |
204 |
promise = element . requestFullscreen([options]) 205 |
206 | Displays element fullscreen and resolves promise when done. 207 | 208 | When supplied, options's navigationUI member indicates whether showing 209 | navigation UI while in fullscreen is preferred or not. If set to "show", navigation 210 | simplicity is preferred over screen space, and if set to "hide", more screen space 211 | is preferred. User agents are always free to honor user preference over the application's. The 212 | default value "auto" indicates no application preference. 213 | 214 |
document . {{Document/fullscreenEnabled}} 215 |

Returns true if document has the ability to display elements fullscreen 216 | and fullscreen is supported, or false otherwise. 217 | 218 |

promise = document . {{Document/exitFullscreen()}} 219 |

Stops document's fullscreen element from being displayed fullscreen and 220 | resolves promise when done. 221 | 222 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 223 |

Returns document's fullscreen element. 224 | 225 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 226 |

Returns shadowroot's fullscreen element. 227 |

228 | 229 |

A fullscreen element ready check for an element element returns true 230 | if all of the following are true, and false otherwise: 231 | 232 |

239 | 240 |

The requestFullscreen(options) method, 241 | when invoked, must run these steps: 242 | 243 |

    244 |
  1. Let pending be the context object. 245 | 246 |

  2. Let pendingDoc be pending's node document. 247 | 248 |

  3. Let promise be a new promise. 249 | 250 |

  4. If pendingDoc is not fully active, then reject promise with a 251 | TypeError exception and return promise. 252 | 253 |

  5. Let error be false. 254 | 255 |

  6. 256 |

    If any of the following conditions are false, then set error to true: 257 | 258 |

    273 | 274 |
  7. Return promise, and run the remaining steps in parallel. 275 | 276 |

  8. 277 |

    If error is false: Resize pendingDoc's 278 | top-level browsing context's active document's viewport's dimensions, optionally 279 | taking into account options's navigationUI member: 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 |
    valueviewport dimensions
    "hide"full dimensions of the screen of the output device
    "show"dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls
    "auto"user-agent defined, but matching one of the above
    304 | 305 |

    Optionally display a message how the end user can revert this. 306 | 307 |

  9. 308 |

    If any of the following conditions are false, then set error to true: 309 | 310 |

    316 | 317 |
  10. 318 |

    If error is true: 319 | 320 |

      321 |
    1. Append (fullscreenerror, pending) to 322 | pendingDoc's list of pending fullscreen events. 323 | 324 |

    2. Reject promise with a TypeError exception and terminate these 325 | steps. 326 |

    327 | 328 |
  11. Let fullscreenElements be an ordered set initially consisting of 329 | pending. 330 | 331 |

  12. While the first element in fullscreenElements is in a 332 | nested browsing context: append its browsing context container to 333 | fullscreenElements. 334 | 335 | 336 |

  13. 337 |

    For each element in fullscreenElements: 338 | 339 |

      340 |
    1. Let doc be element's node document. 341 | 342 |

    2. 343 |

      If element is doc's fullscreen element, continue. 344 | 345 |

      No need to notify observers when nothing has changed. 346 | 347 |

    3. If element is pending and pending is an <{iframe}> 348 | element, then set element's iframe fullscreen flag. 349 | 350 |

    4. Fullscreen element within doc. 351 | 352 |

    5. Append (fullscreenchange, element) to 353 | doc's list of pending fullscreen events. 354 |

    355 | 356 |

    The order in which elements are fullscreened 357 | is not observable, because run the fullscreen steps is invoked in tree order. 358 | 359 |

  14. Resolve promise with undefined. 360 |

361 | 362 |

Implementations with out-of-process browsing contexts are left as an 363 | exercise to the reader. Input welcome on potential improvements. 364 | 365 |

The fullscreenEnabled attribute's getter must 366 | return true if the context object is allowed to use the "fullscreen" feature and fullscreen is supported, and 368 | false otherwise. 369 | 370 |

The fullscreen attribute's getter must return 371 | false if context object's fullscreen element is null, and true otherwise. 372 | 373 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 374 | 375 |

The 376 | fullscreenElement 377 | attribute's getter must run these steps: 378 | 379 |

    380 |
  1. If the context object is a shadow root and its 381 | host is not connected, then return null.

  2. 382 | 383 |
  3. Let candidate be the result of retargeting fullscreen element 384 | against the context object. 385 | 386 |

  4. If candidate and the context object are in the same tree, then 387 | return candidate. 388 | 389 |

  5. Return null. 390 |

391 | 392 |

A document is said to be a simple fullscreen document if there is exactly one 393 | element in its top layer that has its fullscreen flag set. 394 | 395 |

A document with two elements in its top layer can be a 396 | simple fullscreen document. For example, in addition to the fullscreen element there 397 | could be an open <{dialog}> element. 398 | 399 |

To collect documents to unfullscreen given doc, run these steps: 400 | 401 |

    402 |
  1. Let docs be an ordered set consisting of doc. 403 | 404 |

  2. 405 |

    While true: 406 | 407 |

      408 |
    1. Let lastDoc be docs's last document. 409 | 410 |

    2. Assert: lastDoc's fullscreen element is not null. 411 | 412 |

    3. If lastDoc is not a simple fullscreen document, break. 413 | 414 |

    4. Let container be lastDoc's browsing context container, if 415 | any, and otherwise break. 416 | 417 |

    5. If container's iframe fullscreen flag is set, break. 418 | 419 |

    6. Append container's node document to docs. 420 |

    421 | 422 |
  3. Return docs. 423 | 424 |

    This is the set of documents for which the fullscreen element will be 425 | unfullscreened, but the last document in docs might 426 | have more than one element in its top layer with the fullscreen flag set, 427 | in which case that document will still remain in fullscreen. 428 |

429 | 430 |

To exit fullscreen a document doc, run these steps: 431 | 432 |

    433 |
  1. Let promise be a new promise. 434 | 435 |

  2. If doc is not fully active or doc's fullscreen element 436 | is null, then reject promise with a TypeError exception and return 437 | promise. 438 | 439 |

  3. Let resize be false. 440 | 441 |

  4. Let docs be the result of 442 | collecting documents to unfullscreen given 443 | doc. 444 | 445 | 446 |

  5. Let topLevelDoc be doc's top-level browsing context's 447 | active document. 448 | 449 | 450 |

  6. If topLevelDoc is in docs, and it is a 451 | simple fullscreen document, then set doc to topLevelDoc and 452 | resize to true. 453 | 454 |

  7. If doc's fullscreen element is not connected: 455 |

      456 |
    1. Append (fullscreenchange, doc's 457 | fullscreen element) to doc's 458 | list of pending fullscreen events. 459 |

    460 | 461 |
  8. Return promise, and run the remaining steps in parallel. 462 | 463 |

  9. If resize is true, resize doc's viewport to its "normal" dimensions. 464 | 465 |

  10. If doc's fullscreen element is null, then resolve promise with 466 | undefined and terminate these steps. 467 | 468 |

  11. Let exitDocs be the result of 469 | collecting documents to unfullscreen given 470 | doc. 471 | 472 | 473 |

  12. Let descendantDocs be an ordered set consisting of doc's 474 | descendant browsing contexts' active documents whose fullscreen element is 475 | non-null, if any, in tree order. 476 | 477 | 478 |

  13. 479 |

    For each exitDoc in exitDocs: 480 | 481 |

      482 |
    1. Append (fullscreenchange, exitDoc's 483 | fullscreen element) to exitDoc's list of pending fullscreen events. 484 | 485 |

    2. If resize is true, unfullscreen 486 | exitDoc. 487 | 488 |

    3. Otherwise, unfullscreen exitDoc's 489 | fullscreen element. 490 |

    491 | 492 |
  14. 493 |

    For each descendantDoc in descendantDocs: 494 | 495 |

      496 |
    1. Append (fullscreenchange, descendantDoc's 497 | fullscreen element) to descendantDoc's 498 | list of pending fullscreen events. 499 | 500 |

    2. Unfullscreen descendantDoc. 501 |

    502 | 503 |

    The order in which documents are unfullscreened 504 | is not observable, because run the fullscreen steps is invoked in tree order. 505 | 506 |

  15. Resolve promise with undefined. 507 |

508 | 509 |

The exitFullscreen() method, when invoked, must 510 | return the result of running exit fullscreen on the context object. 511 | 512 |


513 | 514 |

The following are the event handlers (and their corresponding 515 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 516 | event handler IDL attributes: 517 | 518 | 519 | 520 | 521 | 524 | 525 | 528 |
event handler 522 | event handler event type 523 |
onfullscreenchange 526 | fullscreenchange 527 |
onfullscreenerror 529 | fullscreenerror 530 |
531 | 532 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 533 | corresponding event handler content attributes for {{Element}} objects in any namespace. 534 | 535 | 536 | 537 |

UI

538 | 539 |

User agents are encouraged to implement native media fullscreen controls in terms of 540 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 541 | 542 |

If the end user instructs the user agent to end a fullscreen session initiated via 543 | {{Element/requestFullscreen()}}, fully exit fullscreen the 544 | top-level browsing context's active document. 545 | 546 |

The user agent may end any fullscreen session without instruction from the end user 547 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 548 | 549 | 550 | 551 |

Rendering

552 | 553 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 554 | 555 |

Long term CSS will define the top layer concept and its associated 556 | ::backdrop pseudo-element as part of CSS' stacking context model. Patching CSS 557 | as done here is sketchy as hell. 558 | 559 | 560 |

New stacking layer

561 | 562 |

This specification introduces a new stacking layer to the 563 | Elaborate description of Stacking Contexts of CSS 564 | 2.1. It is called the top layer, comes after step 10 in the painting order, and is 565 | therefore rendered closest to the user within a viewport. Each document has one 566 | associated viewport and therefore also one top layer. [[!CSS]] 567 | 568 |

The terminology used in this and following subsection attempts to match CSS 2.1 569 | Appendix E. 570 | 571 |

The top layer is an ordered set of elements, rendered in the order they appear in 572 | the set. The last element in the set is rendered last, and thus appears on top. 573 | 574 |

The z-index property has no effect in the top layer. 575 | 576 |

Each element and ::backdrop pseudo-element in a top layer has the 577 | following characteristics: 578 | 579 |

611 | 612 |

To add an element to a top layer, 613 | remove it from top layer and then append it to 614 | top layer. 615 | 616 |

In other words, element is moved to the end of top layer if it 617 | is already present. 618 | 619 | 620 |

::backdrop pseudo-element

621 | 622 |

Each element in a top layer has a 623 | ::backdrop pseudo-element. This pseudo-element 624 | is a box rendered immediately below the element (and above the element before the element in the 625 | set, if any), within the same top layer. 626 | 627 |

The ::backdrop pseudo-element can be used to create a backdrop 628 | that hides the underlying document for an element in a top layer (such as an element that is 629 | displayed fullscreen). 630 | 631 |

It does not inherit from any element and is not inherited from. No restrictions are made on what 632 | properties apply to this pseudo-element either. 633 | 634 | 636 | 637 | 638 |

:fullscreen pseudo-class

639 | 640 |

The :fullscreen pseudo-class must match any 641 | element element for which one of the following conditions is true: 642 | 643 |

649 | 650 |

This makes it different from the 651 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 652 | 653 |

User-agent level style sheet defaults

654 | 655 | 656 |
657 | @namespace "http://www.w3.org/1999/xhtml";
658 | 
659 | *|*:not(:root):fullscreen {
660 |   position:fixed !important;
661 |   top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
662 |   margin:0 !important;
663 |   box-sizing:border-box !important;
664 |   min-width:0 !important;
665 |   max-width:none !important;
666 |   min-height:0 !important;
667 |   max-height:none !important;
668 |   width:100% !important;
669 |   height:100% !important;
670 |   transform:none !important;
671 | 
672 |   /* intentionally not !important */
673 |   object-fit:contain;
674 | }
675 | 
676 | iframe:fullscreen {
677 |   border:none !important;
678 |   padding:0 !important;
679 | }
680 | 
681 | ::backdrop {
682 |   position:fixed;
683 |   top:0; right:0; bottom:0; left:0;
684 | }
685 | 
686 | *|*:not(:root):fullscreen::backdrop {
687 |   background:black;
688 | }
689 | 
690 | 691 | 692 | 693 |

Feature Policy Integration

694 | 695 |

This specification defines a policy-controlled feature identified by the string 696 | "fullscreen". Its default allowlist is 697 | 'self'. 698 | 699 |

700 |

A document's feature policy determines whether any content in that document is allowed to 701 | go fullscreen. If disabled in any document, no content in the document will be allowed to use 702 | fullscreen. 703 | 704 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 705 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 706 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 707 | allow="fullscreen *">, as described in 708 | [[FEATURE-POLICY#iframe-allowfullscreen-attribute]]. 709 |

710 | 711 | 712 |

Security and Privacy Considerations

713 | 714 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 715 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 716 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 717 | user agent or even operating system environment when fullscreen. See also the definition of 718 | {{Element/requestFullscreen()}}. 719 | 720 |

To enable content in a nested browsing context to go fullscreen, it needs to be 721 | specifically allowed via feature policy, either through the <{iframe/allowfullscreen}> attribute of 722 | the HTML <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the 723 | HTML <{iframe}> element, or through a `Feature-Policy` HTTP header 724 | delivered with the document through which it is nested. 725 | 726 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 727 | 728 | 729 | 730 |

Acknowledgments

731 | 732 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 733 | 734 | 735 |

Thanks to 736 | Andy Earnshaw, 737 | Chris Pearce, 738 | Darin Fisher, 739 | Dave Tapuska, 740 | fantasai, 741 | Giuseppe Pascale, 742 | Glenn Maynard, 743 | Ian Clelland, 744 | Ian Hickson, 745 | Ignacio Solla, 746 | João Eiras, 747 | Josh Soref, 748 | Kagami Sascha Rosylight, 749 | Matt Falkenhagen, 750 | Mihai Balan, 751 | Mounir Lamouri, 752 | Øyvind Stenhaug, 753 | Pat Ladd, 754 | Rafał Chłodnicki, 755 | Riff Jiang, 756 | Rune Lillesveen, 757 | Sigbjørn Vik, 758 | Simon Pieters, 759 | Tab Atkins, 760 | Takayoshi Kochi, 761 | Theresa O'Connor, 762 | triple-underscore, 763 | Vincent Scheib, and 764 | Xidorn Quan 765 | for also being awesome. 766 | 767 |

This standard is edited by Philip Jägenstedt 768 | (Google, 769 | philip@foolip.org). It was originally written by 770 | Anne van Kesteren 771 | (Mozilla, 772 | annevk@annevk.nl). 773 | Tantek Çelik 774 | (Mozilla, 775 | tantek@cs.stanford.edu) sorted out legal hassles. 776 | -------------------------------------------------------------------------------- /review-drafts/2020-01.bs: -------------------------------------------------------------------------------- 1 |

  2 | Group: WHATWG
  3 | Date: 2020-01-29
  4 | H1: Fullscreen API
  5 | Shortname: fullscreen
  6 | Text Macro: TWITTER fullscreenapi
  7 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
  8 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
  9 | Markup Shorthands: css no
 10 | 
11 | 12 | 20 | 21 |
 22 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 23 |     type: dfn
 24 |         text: triggered by a user generated orientation change
 25 | 
26 | 27 |
 28 | {
 29 |     "CSS": {
 30 |         "aliasOf": "CSS2"
 31 |     },
 32 |     "SVG": {
 33 |         "aliasOf": "SVG11"
 34 |     }
 35 | }
 36 | 
37 | 38 | 39 | 40 |

Terminology

41 | 42 |

This specification depends on the Infra Standard. [[!INFRA]] 43 | 44 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 45 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 46 | 47 |

A browsing context A is called a descendant browsing context 48 | of a browsing context B if and only if B is an 49 | ancestor browsing context of A. 50 | 51 | 52 | 53 |

Model

54 | 55 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 56 | unset. 57 | 58 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 59 | stated otherwise it is unset. 60 | 61 |

All documents have an associated fullscreen element. The 62 | fullscreen element is the topmost element in the document's 63 | top layer whose fullscreen flag is set, if any, and null otherwise. 64 | 65 |

All documents have an associated list of pending fullscreen events, which 66 | is an ordered set of (string, element) pairs. It is initially empty. 67 | 68 |

To fullscreen an element, set element's fullscreen flag 69 | and add it to its node document's top layer. 70 | 71 |

To unfullscreen an element, unset element's 72 | fullscreen flag and iframe fullscreen flag (if any), and remove it from 73 | its node document's top layer. 74 | 75 |

To unfullscreen a document, 76 | unfullscreen all elements, within document's 77 | top layer, whose fullscreen flag is set. 78 | 79 |


80 | 81 |

To fully exit fullscreen a document document, run these steps: 82 | 83 |

    84 |
  1. If document's fullscreen element is null, terminate these steps. 85 | 86 |

  2. Unfullscreen elements whose fullscreen flag is 87 | set, within document's top layer, except for document's 88 | fullscreen element. 89 | 90 |

  3. Exit fullscreen document. 91 |

92 | 93 |

Whenever the removing steps run with a removedNode, run 94 | these steps: 95 | 96 |

    97 |
  1. Let document be removedNode's node document. 98 | 99 |

  2. Let nodes be removedNode's 100 | shadow-including inclusive descendants that have their fullscreen flag set, in 101 | shadow-including tree order. 102 | 103 |

  3. 104 |

    For each node in nodes: 105 | 106 |

      107 |
    1. If node is document's fullscreen element, 108 | exit fullscreen document. 109 | 110 |

    2. Otherwise, unfullscreen node. 111 | 112 |

    3. 113 |

      If document's top layer contains node, 114 | remove node from document's top layer. 115 | 116 |

      Other specifications can add and remove elements from top layer, so 117 | node might not be document's fullscreen element. For example, 118 | node could be an open <{dialog}> element. 119 |

    120 |
121 | 122 |

Whenever the unloading document cleanup steps run with a document, 123 | fully exit fullscreen document. 124 | 125 |


126 | 127 |

Fullscreen is supported if there is no previously-established user preference, 128 | security risk, or platform limitation. 129 | 130 |


131 | 132 |

To run the fullscreen steps for a document document, run these 133 | steps: 134 | 135 |

    136 |
  1. Let pairs be document's list of pending fullscreen events. 137 | 138 |

  2. Empty document's list of pending fullscreen events. 139 | 140 |

  3. 141 |

    For each (type, element) in pairs: 142 | 143 |

      144 |
    1. Let target be element if element is connected 145 | and its node document is document, and otherwise let target be 146 | document. 147 | 148 |

    2. Fire an event named type, with its {{Event/bubbles}} and 149 | {{Event/composed}} attributes set to true, at target. 150 |

    151 |
152 | 153 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 154 | 155 | 156 | 157 |

API

158 | 159 |
160 | enum FullscreenNavigationUI {
161 |   "auto",
162 |   "show",
163 |   "hide"
164 | };
165 | 
166 | dictionary FullscreenOptions {
167 |   FullscreenNavigationUI navigationUI = "auto";
168 | };
169 | 
170 | partial interface Element {
171 |   Promise<void> requestFullscreen(optional FullscreenOptions options = {});
172 | 
173 |   attribute EventHandler onfullscreenchange;
174 |   attribute EventHandler onfullscreenerror;
175 | };
176 | 
177 | partial interface Document {
178 |   [LenientSetter] readonly attribute boolean fullscreenEnabled;
179 |   [LenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
180 | 
181 |   Promise<void> exitFullscreen();
182 | 
183 |   attribute EventHandler onfullscreenchange;
184 |   attribute EventHandler onfullscreenerror;
185 | };
186 | 
187 | partial interface mixin DocumentOrShadowRoot {
188 |   [LenientSetter] readonly attribute Element? fullscreenElement;
189 | };
190 | 
191 | 193 | 194 |
195 |
promise = element . requestFullscreen([options]) 196 |
197 | Displays element fullscreen and resolves promise when done. 198 | 199 | When supplied, options's navigationUI member indicates whether showing 200 | navigation UI while in fullscreen is preferred or not. If set to "show", navigation 201 | simplicity is preferred over screen space, and if set to "hide", more screen space 202 | is preferred. User agents are always free to honor user preference over the application's. The 203 | default value "auto" indicates no application preference. 204 | 205 |
document . {{Document/fullscreenEnabled}} 206 |

Returns true if document has the ability to display elements fullscreen 207 | and fullscreen is supported, or false otherwise. 208 | 209 |

promise = document . {{Document/exitFullscreen()}} 210 |

Stops document's fullscreen element from being displayed fullscreen and 211 | resolves promise when done. 212 | 213 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 214 |

Returns document's fullscreen element. 215 | 216 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 217 |

Returns shadowroot's fullscreen element. 218 |

219 | 220 |

A fullscreen element ready check for an element element returns true 221 | if all of the following are true, and false otherwise: 222 | 223 |

230 | 231 |

The requestFullscreen(options) method, 232 | when invoked, must run these steps: 233 | 234 |

    235 |
  1. Let pending be the context object. 236 | 237 |

  2. Let pendingDoc be pending's node document. 238 | 239 |

  3. Let promise be a new promise. 240 | 241 |

  4. If pendingDoc is not fully active, then reject promise with a 242 | TypeError exception and return promise. 243 | 244 |

  5. Let error be false. 245 | 246 |

  6. 247 |

    If any of the following conditions are false, then set error to true: 248 | 249 |

    265 | 266 |
  7. Return promise, and run the remaining steps in parallel. 267 | 268 |

  8. 269 |

    If error is false, then resize pendingDoc's 270 | top-level browsing context's active document's viewport's dimensions, optionally 271 | taking into account options's navigationUI member: 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 |
    valueviewport dimensions
    "hide"full dimensions of the screen of the output device
    "show"dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls
    "auto"user-agent defined, but matching one of the above
    296 | 297 |

    Optionally display a message how the end user can revert this. 298 | 299 |

  9. 300 |

    If any of the following conditions are false, then set error to true: 301 | 302 |

    308 | 309 |
  10. 310 |

    If error is true: 311 | 312 |

      313 |
    1. Append (fullscreenerror, pending) to 314 | pendingDoc's list of pending fullscreen events. 315 | 316 |

    2. Reject promise with a TypeError exception and terminate these 317 | steps. 318 |

    319 | 320 |
  11. Let fullscreenElements be an ordered set initially consisting of 321 | pending. 322 | 323 |

  12. While the last element in fullscreenElements is in a 324 | nested browsing context: append its browsing context container to 325 | fullscreenElements. 326 | 327 | 328 |

  13. 329 |

    For each element in fullscreenElements: 330 | 331 |

      332 |
    1. Let doc be element's node document. 333 | 334 |

    2. 335 |

      If element is doc's fullscreen element, continue. 336 | 337 |

      No need to notify observers when nothing has changed. 338 | 339 |

    3. If element is pending and pending is an <{iframe}> 340 | element, then set element's iframe fullscreen flag. 341 | 342 |

    4. Fullscreen element within doc. 343 | 344 |

    5. Append (fullscreenchange, element) to 345 | doc's list of pending fullscreen events. 346 |

    347 | 348 |

    The order in which elements are fullscreened 349 | is not observable, because run the fullscreen steps is invoked in tree order. 350 | 351 |

  14. Resolve promise with undefined. 352 |

353 | 354 |

Implementations with out-of-process browsing contexts are left as an 355 | exercise to the reader. Input welcome on potential improvements. 356 | 357 |

The fullscreenEnabled attribute's getter must 358 | return true if the context object is allowed to use the "fullscreen" feature and fullscreen is supported, and 360 | false otherwise. 361 | 362 |

The fullscreen attribute's getter must return 363 | false if context object's fullscreen element is null, and true otherwise. 364 | 365 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 366 | 367 |

The 368 | fullscreenElement 369 | attribute's getter must run these steps: 370 | 371 |

    372 |
  1. If the context object is a shadow root and its 373 | host is not connected, then return null.

  2. 374 | 375 |
  3. Let candidate be the result of retargeting fullscreen element 376 | against the context object. 377 | 378 |

  4. If candidate and the context object are in the same tree, then 379 | return candidate. 380 | 381 |

  5. Return null. 382 |

383 | 384 |

A document is said to be a simple fullscreen document if there is exactly one 385 | element in its top layer that has its fullscreen flag set. 386 | 387 |

A document with two elements in its top layer can be a 388 | simple fullscreen document. For example, in addition to the fullscreen element there 389 | could be an open <{dialog}> element. 390 | 391 |

To collect documents to unfullscreen given doc, run these steps: 392 | 393 |

    394 |
  1. Let docs be an ordered set consisting of doc. 395 | 396 |

  2. 397 |

    While true: 398 | 399 |

      400 |
    1. Let lastDoc be docs's last document. 401 | 402 |

    2. Assert: lastDoc's fullscreen element is not null. 403 | 404 |

    3. If lastDoc is not a simple fullscreen document, break. 405 | 406 |

    4. Let container be lastDoc's browsing context container, if 407 | any, and otherwise break. 408 | 409 |

    5. If container's iframe fullscreen flag is set, break. 410 | 411 |

    6. Append container's node document to docs. 412 |

    413 | 414 |
  3. Return docs. 415 | 416 |

    This is the set of documents for which the fullscreen element will be 417 | unfullscreened, but the last document in docs might 418 | have more than one element in its top layer with the fullscreen flag set, 419 | in which case that document will still remain in fullscreen. 420 |

421 | 422 |

To exit fullscreen a document doc, run these steps: 423 | 424 |

    425 |
  1. Let promise be a new promise. 426 | 427 |

  2. If doc is not fully active or doc's fullscreen element 428 | is null, then reject promise with a TypeError exception and return 429 | promise. 430 | 431 |

  3. Let resize be false. 432 | 433 |

  4. Let docs be the result of 434 | collecting documents to unfullscreen given 435 | doc. 436 | 437 | 438 |

  5. Let topLevelDoc be doc's top-level browsing context's 439 | active document. 440 | 441 | 442 |

  6. If topLevelDoc is in docs, and it is a 443 | simple fullscreen document, then set doc to topLevelDoc and 444 | resize to true. 445 | 446 |

  7. If doc's fullscreen element is not connected: 447 |

      448 |
    1. Append (fullscreenchange, doc's 449 | fullscreen element) to doc's 450 | list of pending fullscreen events. 451 |

    452 | 453 |
  8. Return promise, and run the remaining steps in parallel. 454 | 455 |

  9. If resize is true, resize doc's viewport to its "normal" dimensions. 456 | 457 |

  10. If doc's fullscreen element is null, then resolve promise with 458 | undefined and terminate these steps. 459 | 460 |

  11. Let exitDocs be the result of 461 | collecting documents to unfullscreen given 462 | doc. 463 | 464 | 465 |

  12. Let descendantDocs be an ordered set consisting of doc's 466 | descendant browsing contexts' active documents whose fullscreen element is 467 | non-null, if any, in tree order. 468 | 469 | 470 |

  13. 471 |

    For each exitDoc in exitDocs: 472 | 473 |

      474 |
    1. Append (fullscreenchange, exitDoc's 475 | fullscreen element) to exitDoc's list of pending fullscreen events. 476 | 477 |

    2. If resize is true, unfullscreen 478 | exitDoc. 479 | 480 |

    3. Otherwise, unfullscreen exitDoc's 481 | fullscreen element. 482 |

    483 | 484 |
  14. 485 |

    For each descendantDoc in descendantDocs: 486 | 487 |

      488 |
    1. Append (fullscreenchange, descendantDoc's 489 | fullscreen element) to descendantDoc's 490 | list of pending fullscreen events. 491 | 492 |

    2. Unfullscreen descendantDoc. 493 |

    494 | 495 |

    The order in which documents are unfullscreened 496 | is not observable, because run the fullscreen steps is invoked in tree order. 497 | 498 |

  15. Resolve promise with undefined. 499 |

500 | 501 |

The exitFullscreen() method, when invoked, must 502 | return the result of running exit fullscreen on the context object. 503 | 504 |


505 | 506 |

The following are the event handlers (and their corresponding 507 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 508 | event handler IDL attributes: 509 | 510 | 511 | 512 | 513 | 516 | 517 | 520 |
event handler 514 | event handler event type 515 |
onfullscreenchange 518 | fullscreenchange 519 |
onfullscreenerror 521 | fullscreenerror 522 |
523 | 524 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 525 | corresponding event handler content attributes for {{Element}} objects in any namespace. 526 | 527 | 528 | 529 |

UI

530 | 531 |

User agents are encouraged to implement native media fullscreen controls in terms of 532 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 533 | 534 |

If the end user instructs the user agent to end a fullscreen session initiated via 535 | {{Element/requestFullscreen()}}, fully exit fullscreen the 536 | top-level browsing context's active document. 537 | 538 |

The user agent may end any fullscreen session without instruction from the end user 539 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 540 | 541 | 542 | 543 |

Rendering

544 | 545 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 546 | 547 |

Long term CSS will define the top layer concept and its associated 548 | ::backdrop pseudo-element as part of CSS' stacking context model. Patching CSS 549 | as done here is sketchy as hell. 550 | 551 | 552 |

New stacking layer

553 | 554 |

This specification introduces a new stacking layer to the 555 | Elaborate description of Stacking Contexts of CSS 556 | 2.1. It is called the top layer, comes after step 10 in the painting order, and is 557 | therefore rendered closest to the user within a viewport. Each document has one 558 | associated viewport and therefore also one top layer. [[!CSS]] 559 | 560 |

The terminology used in this and following subsection attempts to match CSS 2.1 561 | Appendix E. 562 | 563 |

The top layer is an ordered set of elements, rendered in the order they appear in 564 | the set. The last element in the set is rendered last, and thus appears on top. 565 | 566 |

The z-index property has no effect in the top layer. 567 | 568 |

Each element and ::backdrop pseudo-element in a top layer has the 569 | following characteristics: 570 | 571 |

603 | 604 |

To add an element to a top layer, 605 | remove it from top layer and then append it to 606 | top layer. 607 | 608 |

In other words, element is moved to the end of top layer if it 609 | is already present. 610 | 611 | 612 |

::backdrop pseudo-element

613 | 614 |

Each element in a top layer has a 615 | ::backdrop pseudo-element. This pseudo-element 616 | is a box rendered immediately below the element (and above the element before the element in the 617 | set, if any), within the same top layer. 618 | 619 |

The ::backdrop pseudo-element can be used to create a backdrop 620 | that hides the underlying document for an element in a top layer (such as an element that is 621 | displayed fullscreen). 622 | 623 |

It does not inherit from any element and is not inherited from. No restrictions are made on what 624 | properties apply to this pseudo-element either. 625 | 626 | 628 | 629 | 630 |

:fullscreen pseudo-class

631 | 632 |

The :fullscreen pseudo-class must match any 633 | element element for which one of the following conditions is true: 634 | 635 |

641 | 642 |

This makes it different from the 643 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 644 | 645 |

User-agent level style sheet defaults

646 | 647 | 648 |
649 | @namespace "http://www.w3.org/1999/xhtml";
650 | 
651 | *|*:not(:root):fullscreen {
652 |   position:fixed !important;
653 |   top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
654 |   margin:0 !important;
655 |   box-sizing:border-box !important;
656 |   min-width:0 !important;
657 |   max-width:none !important;
658 |   min-height:0 !important;
659 |   max-height:none !important;
660 |   width:100% !important;
661 |   height:100% !important;
662 |   transform:none !important;
663 | 
664 |   /* intentionally not !important */
665 |   object-fit:contain;
666 | }
667 | 
668 | iframe:fullscreen {
669 |   border:none !important;
670 |   padding:0 !important;
671 | }
672 | 
673 | ::backdrop {
674 |   position:fixed;
675 |   top:0; right:0; bottom:0; left:0;
676 | }
677 | 
678 | *|*:not(:root):fullscreen::backdrop {
679 |   background:black;
680 | }
681 | 
682 | 683 | 684 | 685 |

Feature Policy Integration

686 | 687 |

This specification defines a policy-controlled feature identified by the string 688 | "fullscreen". Its default allowlist is 689 | 'self'. 690 | 691 |

692 |

A document's feature policy determines whether any content in that document is allowed to 693 | go fullscreen. If disabled in any document, no content in the document will be allowed to use 694 | fullscreen. 695 | 696 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 697 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 698 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 699 | allow="fullscreen *">, as described in 700 | [[FEATURE-POLICY#iframe-allowfullscreen-attribute]]. 701 |

702 | 703 | 704 |

Security and Privacy Considerations

705 | 706 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 707 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 708 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 709 | user agent or even operating system environment when fullscreen. See also the definition of 710 | {{Element/requestFullscreen()}}. 711 | 712 |

To enable content in a nested browsing context to go fullscreen, it needs to be 713 | specifically allowed via feature policy, either through the <{iframe/allowfullscreen}> attribute of 714 | the HTML <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the 715 | HTML <{iframe}> element, or through a `Feature-Policy` HTTP header 716 | delivered with the document through which it is nested. 717 | 718 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 719 | 720 | 721 | 722 |

Acknowledgments

723 | 724 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 725 | 726 | 727 |

Thanks to 728 | Andy Earnshaw, 729 | Changwan Hong, 730 | Chris Pearce, 731 | Darin Fisher, 732 | Dave Tapuska, 733 | fantasai, 734 | Giuseppe Pascale, 735 | Glenn Maynard, 736 | Ian Clelland, 737 | Ian Hickson, 738 | Ignacio Solla, 739 | João Eiras, 740 | Josh Soref, 741 | Kagami Sascha Rosylight, 742 | Matt Falkenhagen, 743 | Mihai Balan, 744 | Mounir Lamouri, 745 | Øyvind Stenhaug, 746 | Pat Ladd, 747 | Rafał Chłodnicki, 748 | Riff Jiang, 749 | Rune Lillesveen, 750 | Sigbjørn Vik, 751 | Simon Pieters, 752 | Tab Atkins, 753 | Takayoshi Kochi, 754 | Theresa O'Connor, 755 | triple-underscore, 756 | Vincent Scheib, and 757 | Xidorn Quan 758 | for also being awesome. 759 | 760 |

This standard is edited by Philip Jägenstedt 761 | (Google, 762 | philip@foolip.org). It was originally written by 763 | Anne van Kesteren 764 | (Mozilla, 765 | annevk@annevk.nl). 766 | Tantek Çelik 767 | (Mozilla, 768 | tantek@cs.stanford.edu) sorted out legal hassles. 769 | -------------------------------------------------------------------------------- /review-drafts/2023-07.bs: -------------------------------------------------------------------------------- 1 |

  2 | Group: WHATWG
  3 | Status: RD
  4 | Date: 2023-07-17
  5 | H1: Fullscreen API
  6 | Shortname: fullscreen
  7 | Text Macro: TWITTER fullscreenapi
  8 | Text Macro: LATESTRD 2023-07
  9 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
 10 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
 11 | Markup Shorthands: css no
 12 | 
13 | 14 | 25 | 26 |
 27 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 28 |     type: dfn
 29 |         text: triggered by a user generated orientation change
 30 | 
31 | 32 |
 33 | {
 34 |     "CSS": {
 35 |         "aliasOf": "CSS2"
 36 |     },
 37 |     "SVG": {
 38 |         "aliasOf": "SVG11"
 39 |     }
 40 | }
 41 | 
42 | 43 | 44 | 45 |

Terminology

46 | 47 |

This specification depends on the Infra Standard. [[!INFRA]] 48 | 49 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 50 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 51 | 52 | 53 | 54 |

Model

55 | 56 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 57 | unset. 58 | 59 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 60 | stated otherwise it is unset. 61 | 62 |

All documents have an associated fullscreen element. The 63 | fullscreen element is the topmost element in the document's 64 | top layer whose fullscreen flag is set, if any, and null otherwise. 65 | 66 |

All documents have an associated list of pending fullscreen events, which 67 | is an ordered set of (string, element) tuples. It is initially empty. 68 | 69 |

To fullscreen an element: 70 | 71 |

    72 |
  1. Run hide all popovers given element's node document. 73 | 74 |

  2. Set element's fullscreen flag. 75 | 76 |

  3. Remove from the top layer immediately given element. 77 | 78 |

  4. Add to the top layer given element. 79 |
80 | 81 |

To unfullscreen an element, unset element's 82 | fullscreen flag and iframe fullscreen flag (if any), and 83 | remove from the top layer immediately given element. 84 | 85 |

To unfullscreen a document, 86 | unfullscreen all elements, within document's 87 | top layer, whose fullscreen flag is set. 88 | 89 |


90 | 91 |
92 |

To fully exit fullscreen a document document, run these steps: 93 | 94 |

    95 |
  1. If document's fullscreen element is null, terminate these steps. 96 | 97 |

  2. Unfullscreen elements whose fullscreen flag is 98 | set, within document's top layer, except for document's 99 | fullscreen element. 100 | 101 |

  3. Exit fullscreen document. 102 |

103 |
104 | 105 |
106 |

Whenever the removing steps run with a removedNode, run 107 | these steps: 108 | 109 |

    110 |
  1. Let document be removedNode's node document. 111 | 112 |

  2. Let nodes be removedNode's 113 | shadow-including inclusive descendants that have their fullscreen flag set, in 114 | shadow-including tree order. 115 | 116 |

  3. 117 |

    For each node in nodes: 118 | 119 |

      120 |
    1. If node is document's fullscreen element, 121 | exit fullscreen document. 122 | 123 |

    2. Otherwise, unfullscreen node. 124 | 125 |

    3. 126 |

      If document's top layer contains node, 127 | remove from the top layer immediately given node. 128 | 129 |

      Other specifications can add and remove elements from top layer, so 130 | node might not be document's fullscreen element. For example, 131 | node could be an open <{dialog}> element. 132 |

    133 |
134 |
135 | 136 |

Whenever the unloading document cleanup steps run with a document, 137 | fully exit fullscreen document. 138 | 139 |


140 | 141 |

Fullscreen is supported if there is no previously-established user preference, 142 | security risk, or platform limitation. 143 | 144 |


145 | 146 |
147 |

To run the fullscreen steps for a document document, run these 148 | steps: 149 | 150 |

    151 |
  1. Let pendingEvents be document's 152 | list of pending fullscreen events. 153 | 154 |

  2. Empty document's list of pending fullscreen events. 155 | 156 |

  3. 157 |

    For each (type, element) in pendingEvents: 158 | 159 |

      160 |
    1. Let target be element if element is connected 161 | and its node document is document, and otherwise let target be 162 | document. 163 | 164 |

    2. Fire an event named type, with its {{Event/bubbles}} and 165 | {{Event/composed}} attributes set to true, at target. 166 |

    167 |
168 | 169 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 170 |

171 | 172 | 173 | 174 |

API

175 | 176 |
177 | enum FullscreenNavigationUI {
178 |   "auto",
179 |   "show",
180 |   "hide"
181 | };
182 | 
183 | dictionary FullscreenOptions {
184 |   FullscreenNavigationUI navigationUI = "auto";
185 | };
186 | 
187 | partial interface Element {
188 |   Promise<undefined> requestFullscreen(optional FullscreenOptions options = {});
189 | 
190 |   attribute EventHandler onfullscreenchange;
191 |   attribute EventHandler onfullscreenerror;
192 | };
193 | 
194 | partial interface Document {
195 |   [LegacyLenientSetter] readonly attribute boolean fullscreenEnabled;
196 |   [LegacyLenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
197 | 
198 |   Promise<undefined> exitFullscreen();
199 | 
200 |   attribute EventHandler onfullscreenchange;
201 |   attribute EventHandler onfullscreenerror;
202 | };
203 | 
204 | partial interface mixin DocumentOrShadowRoot {
205 |   [LegacyLenientSetter] readonly attribute Element? fullscreenElement;
206 | };
207 | 
208 | 210 | 211 |
212 |
promise = element . requestFullscreen([options]) 213 |
214 | Displays element fullscreen and resolves promise when done. 215 | 216 | When supplied, options's {{FullscreenOptions/navigationUI}} member indicates whether 217 | showing navigation UI while in fullscreen is preferred or not. If set to 218 | "{{FullscreenNavigationUI/show}}", navigation simplicity is preferred over screen space, and if 219 | set to "{{FullscreenNavigationUI/hide}}", more screen space is preferred. User agents are always 220 | free to honor user preference over the application's. The default value 221 | "{{FullscreenNavigationUI/auto}}" indicates no application preference. 222 | 223 |
document . {{Document/fullscreenEnabled}} 224 |

Returns true if document has the ability to display elements fullscreen 225 | and fullscreen is supported, or false otherwise. 226 | 227 |

promise = document . {{Document/exitFullscreen()}} 228 |

Stops document's fullscreen element from being displayed fullscreen and 229 | resolves promise when done. 230 | 231 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 232 |

Returns document's fullscreen element. 233 | 234 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 235 |

Returns shadowroot's fullscreen element. 236 |

237 | 238 |

A fullscreen element ready check for an element element returns true 239 | if all of the following are true, and false otherwise: 240 | 241 |

252 | 253 |
254 |

The requestFullscreen(options) method steps 255 | are: 256 | 257 |

    258 |
  1. Let pendingDoc be this's node document. 259 | 260 |

  2. Let promise be a new promise. 261 | 262 |

  3. If pendingDoc is not fully active, then reject promise with a 263 | {{TypeError}} exception and return promise. 264 | 265 |

  4. Let error be false. 266 | 267 |

  5. 268 |

    If any of the following conditions are false, then set error to true: 269 | 270 |

    286 | 287 |
  6. If error is false, then consume user activation given 288 | pendingDoc's relevant global object. 289 | 290 |

  7. Return promise, and run the remaining steps in parallel. 291 | 292 |

  8. 293 |

    If error is false, then resize pendingDoc's node navigable's 294 | top-level traversable's active document's viewport's 295 | dimensions, optionally taking into account 296 | options["{{FullscreenOptions/navigationUI}}"]: 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 |
    valueviewport dimensions
    "hide"full dimensions of the screen of the output device
    "show"dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls
    "auto"user-agent defined, but matching one of the above
    321 | 322 |

    Optionally display a message how the end user can revert this. 323 | 324 |

  9. 325 |

    If any of the following conditions are false, then set error to true: 326 | 327 |

    333 | 334 |
  10. 335 |

    If error is true: 336 | 337 |

      338 |
    1. Append ({{fullscreenerror}}, this) to 339 | pendingDoc's list of pending fullscreen events. 340 | 341 |

    2. Reject promise with a {{TypeError}} exception and terminate these 342 | steps. 343 |

    344 | 345 |
  11. Let fullscreenElements be an ordered set initially consisting of 346 | this. 347 | 348 |

  12. 349 |

    While true: 350 | 351 |

      352 |
    1. Let last be the last item of fullscreenElements. 353 | 354 |

    2. Let container be last's node navigable's 355 | container. 356 | 357 |

    3. If container is null, then break. 358 | 359 |

    4. Append container to fullscreenElements. 360 |

    361 |
  13. 362 | 363 | 364 |
  14. 365 |

    For each element in fullscreenElements: 366 | 367 |

      368 |
    1. Let doc be element's node document. 369 | 370 |

    2. 371 |

      If element is doc's fullscreen element, continue. 372 | 373 |

      No need to notify observers when nothing has changed. 374 | 375 |

    3. If element is this and this is an <{iframe}> 376 | element, then set element's iframe fullscreen flag. 377 | 378 |

    4. Fullscreen element within doc. 379 | 380 |

    5. Append ({{fullscreenchange}}, element) to 381 | doc's list of pending fullscreen events. 382 |

    383 | 384 |

    The order in which elements are fullscreened 385 | is not observable, because run the fullscreen steps is invoked in tree order. 386 | 387 |

  15. Resolve promise with undefined. 388 |

389 | 390 |

Implementations with out-of-process navigables are left as an exercise 391 | to the reader. Input welcome on potential improvements. 392 |

393 | 394 |

The fullscreenEnabled getter steps are to return 395 | true if this is allowed to use the "fullscreen" feature and fullscreen is supported, and 397 | false otherwise. 398 | 399 |

The fullscreen getter steps are to return false if 400 | this's fullscreen element is null, and true otherwise. 401 | 402 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 403 | 404 |

405 |

The 406 | fullscreenElement 407 | getter steps are: 408 | 409 |

    410 |
  1. If this is a shadow root and its host is not 411 | connected, then return null. 412 | 413 |

  2. Let candidate be the result of retargeting fullscreen element 414 | against this. 415 | 416 |

  3. If candidate and this are in the same tree, then return 417 | candidate. 418 | 419 |

  4. Return null. 420 |

421 |
422 | 423 |

A document is said to be a simple fullscreen document if there is exactly one 424 | element in its top layer that has its fullscreen flag set. 425 | 426 |

A document with two elements in its top layer can be a 427 | simple fullscreen document. For example, in addition to the fullscreen element there 428 | could be an open <{dialog}> element. 429 | 430 |

431 |

To collect documents to unfullscreen given doc, run these steps: 432 | 433 |

    434 |
  1. Let docs be an ordered set consisting of doc. 435 | 436 |

  2. 437 |

    While true: 438 | 439 |

      440 |
    1. Let lastDoc be docs's last document. 441 | 442 |

    2. Assert: lastDoc's fullscreen element is not null. 443 | 444 |

    3. If lastDoc is not a simple fullscreen document, break. 445 | 446 |

    4. Let container be lastDoc's node navigable's 447 | container. 448 | 449 |

    5. If container is null, then break. 450 | 451 |

    6. If container's iframe fullscreen flag is set, break. 452 | 453 |

    7. Append container's node document to docs. 454 |

    455 | 456 |
  3. Return docs. 457 | 458 |

    This is the set of documents for which the fullscreen element will be 459 | unfullscreened, but the last document in docs might 460 | have more than one element in its top layer with the fullscreen flag set, 461 | in which case that document will still remain in fullscreen. 462 |

463 |
464 | 465 |
466 |

To exit fullscreen a document doc, run these steps: 467 | 468 |

    469 |
  1. Let promise be a new promise. 470 | 471 |

  2. If doc is not fully active or doc's fullscreen element 472 | is null, then reject promise with a {{TypeError}} exception and return 473 | promise. 474 | 475 |

  3. Let resize be false. 476 | 477 |

  4. Let docs be the result of 478 | collecting documents to unfullscreen given 479 | doc. 480 | 481 | 482 |

  5. Let topLevelDoc be doc's node navigable's 483 | top-level traversable's active document. 484 | 485 | 486 |

  6. If topLevelDoc is in docs, and it is a 487 | simple fullscreen document, then set doc to topLevelDoc and 488 | resize to true. 489 | 490 |

  7. If doc's fullscreen element is not connected: 491 |

      492 |
    1. Append ({{fullscreenchange}}, doc's 493 | fullscreen element) to doc's 494 | list of pending fullscreen events. 495 |

    496 | 497 |
  8. Return promise, and run the remaining steps in parallel. 498 | 499 |

  9. Run the [=fully unlock the screen orientation steps=] with doc. 500 | 501 |

  10. If resize is true, resize doc's viewport to its "normal" dimensions. 502 | 503 |

  11. If doc's fullscreen element is null, then resolve promise with 504 | undefined and terminate these steps. 505 | 506 |

  12. Let exitDocs be the result of 507 | collecting documents to unfullscreen given 508 | doc. 509 | 510 | 511 |

  13. Let descendantDocs be an ordered set consisting of doc's 512 | descendant navigables' active documents whose 513 | fullscreen element is non-null, if any, in tree order. 514 | 515 | 516 |

  14. 517 |

    For each exitDoc in exitDocs: 518 | 519 |

      520 |
    1. Append ({{fullscreenchange}}, exitDoc's 521 | fullscreen element) to exitDoc's list of pending fullscreen events. 522 | 523 |

    2. If resize is true, unfullscreen 524 | exitDoc. 525 | 526 |

    3. Otherwise, unfullscreen exitDoc's 527 | fullscreen element. 528 |

    529 | 530 |
  15. 531 |

    For each descendantDoc in descendantDocs: 532 | 533 |

      534 |
    1. Append ({{fullscreenchange}}, descendantDoc's 535 | fullscreen element) to descendantDoc's 536 | list of pending fullscreen events. 537 | 538 |

    2. Unfullscreen descendantDoc. 539 |

    540 | 541 |

    The order in which documents are unfullscreened 542 | is not observable, because run the fullscreen steps is invoked in tree order. 543 | 544 |

  16. Resolve promise with undefined. 545 |

546 |
547 | 548 |

The exitFullscreen() method steps are to return the 549 | result of running exit fullscreen on this. 550 | 551 |


552 | 553 |

The following are the event handlers (and their corresponding 554 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 555 | event handler IDL attributes: 556 | 557 | 558 | 559 | 560 | 563 | 564 | 567 |
event handler 561 | event handler event type 562 |
onfullscreenchange 565 | fullscreenchange 566 |
onfullscreenerror 568 | fullscreenerror 569 |
570 | 571 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 572 | corresponding event handler content attributes for {{Element}} objects in any namespace. 573 | 574 | 575 | 576 |

UI

577 | 578 |

User agents are encouraged to implement native media fullscreen controls in terms of 579 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 580 | 581 |

If the end user instructs the user agent to end a fullscreen session initiated via 582 | {{Element/requestFullscreen()}}, fully exit fullscreen given the 583 | top-level traversable's active document. 584 | 585 |

The user agent may end any fullscreen session without instruction from the end user 586 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 587 | 588 | 589 | 590 |

Rendering

591 | 592 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 593 | 594 | 595 |

:fullscreen pseudo-class

596 | 597 |

The :fullscreen pseudo-class must match any 598 | element element for which one of the following conditions is true: 599 | 600 |

606 | 607 |

This makes it different from the 608 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 609 | 610 |

User-agent level style sheet defaults

611 | 612 | 613 |
614 | @namespace "http://www.w3.org/1999/xhtml";
615 | 
616 | *|*:not(:root):fullscreen {
617 |   position:fixed !important;
618 |   inset:0 !important;
619 |   margin:0 !important;
620 |   box-sizing:border-box !important;
621 |   min-width:0 !important;
622 |   max-width:none !important;
623 |   min-height:0 !important;
624 |   max-height:none !important;
625 |   width:100% !important;
626 |   height:100% !important;
627 |   transform:none !important;
628 | 
629 |   /* intentionally not !important */
630 |   object-fit:contain;
631 | }
632 | 
633 | iframe:fullscreen {
634 |   border:none !important;
635 |   padding:0 !important;
636 | }
637 | 
638 | *|*:not(:root):fullscreen::backdrop {
639 |   background:black;
640 | }
641 | 
642 | 643 | 644 | 645 |

Permissions Policy 646 | Integration

647 | 648 |

This specification defines a policy-controlled feature identified by the string 649 | "fullscreen". Its default allowlist is 650 | 'self'. 651 | 652 |

653 |

A document's permissions policy determines whether any content in that 654 | document is allowed to go fullscreen. If disabled in any document, no content in the document will 655 | be allowed to use fullscreen. 656 | 657 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 658 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 659 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 660 | allow="fullscreen *">, as described in 661 | [[permissions-policy#iframe-allowfullscreen-attribute]]. 662 |

663 | 664 | 665 | 666 |

Security and Privacy Considerations

667 | 668 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 669 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 670 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 671 | user agent or even operating system environment when fullscreen. See also the definition of 672 | {{Element/requestFullscreen()}}. 673 | 674 |

To enable content in a child navigable to go fullscreen, it needs to be specifically 675 | allowed via permissions policy, either through the <{iframe/allowfullscreen}> attribute of the HTML 676 | <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the HTML 677 | <{iframe}> element, or through a `Permissions-Policy` HTTP header 678 | delivered with the document through which it is nested. 679 | 680 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 681 | 682 | 683 | 684 |

685 | 686 | This specification previously hosted the definitions of ::backdrop 687 | and the concept of the document's top layer. 688 | 689 | 690 | 691 |

Acknowledgments

692 | 693 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 694 | 695 | 696 |

Thanks to 697 | Andy Earnshaw, 698 | Changwan Hong, 699 | Chris Pearce, 700 | Darin Fisher, 701 | Dave Tapuska, 702 | fantasai, 703 | Giuseppe Pascale, 704 | Glenn Maynard, 705 | Ian Clelland, 706 | Ian Hickson, 707 | Ignacio Solla, 708 | João Eiras, 709 | Josh Soref, 710 | Kagami Sascha Rosylight, 711 | Matt Falkenhagen, 712 | Mihai Balan, 713 | Mounir Lamouri, 714 | Øyvind Stenhaug, 715 | Pat Ladd, 716 | Rafał Chłodnicki, 717 | Riff Jiang, 718 | Rune Lillesveen, 719 | Sigbjørn Vik, 720 | Simon Pieters, 721 | Tab Atkins-Bittner, 722 | Takayoshi Kochi, 723 | Theresa O'Connor, 724 | triple-underscore, 725 | Vincent Scheib, and 726 | Xidorn Quan 727 | for also being awesome. 728 | 729 |

This standard is edited by Philip Jägenstedt 730 | (Google, 731 | philip@foolip.org). It was originally written by 732 | Anne van Kesteren 733 | (Apple, annevk@annevk.nl). 734 | Tantek Çelik 735 | (Mozilla, 736 | tantek@cs.stanford.edu) sorted out legal hassles. 737 | -------------------------------------------------------------------------------- /review-drafts/2024-07.bs: -------------------------------------------------------------------------------- 1 |

  2 | Group: WHATWG
  3 | Status: RD
  4 | Date: 2024-07-15
  5 | H1: Fullscreen API
  6 | Shortname: fullscreen
  7 | Text Macro: TWITTER fullscreenapi
  8 | Text Macro: LATESTRD 2024-07
  9 | Abstract: The Fullscreen API standard defines an API for elements to display themselves fullscreen.
 10 | Translation: ja https://triple-underscore.github.io/fullscreen-ja.html
 11 | Markup Shorthands: css no
 12 | 
13 | 14 | 25 | 26 |
 27 | urlPrefix: https://w3c.github.io/screen-orientation/#dfn-
 28 |     type: dfn
 29 |         text: triggered by a user generated orientation change
 30 | 
31 | 32 |
 33 | {
 34 |     "CSS": {
 35 |         "aliasOf": "CSS2"
 36 |     },
 37 |     "SVG": {
 38 |         "aliasOf": "SVG11"
 39 |     }
 40 | }
 41 | 
42 | 43 | 44 | 45 |

Terminology

46 | 47 |

This specification depends on the Infra Standard. [[!INFRA]] 48 | 49 |

Most terminology used in this specification is from CSS, DOM, HTML, and Web IDL. [[!CSS]] 50 | [[!DOM]] [[!HTML]] [[!WEBIDL]] 51 | 52 | 53 | 54 |

Model

55 | 56 |

All elements have an associated fullscreen flag. Unless stated otherwise it is 57 | unset. 58 | 59 |

All <{iframe}> elements have an associated iframe fullscreen flag. Unless 60 | stated otherwise it is unset. 61 | 62 |

All documents have an associated fullscreen element. The 63 | fullscreen element is the topmost element in the document's 64 | top layer whose fullscreen flag is set, if any, and null otherwise. 65 | 66 |

All documents have an associated list of pending fullscreen events, which 67 | is an ordered set of (string, element) tuples. It is initially empty. 68 | 69 |

To fullscreen an element: 70 | 71 |

    72 |
  1. Let hideUntil be the result of running topmost popover ancestor given 73 | element, null, and false. 74 | 75 |

  2. If hideUntil is null, then set hideUntil to element's 76 | node document. 77 | 78 |

  3. Run hide all popovers until given hideUntil, false, and true. 79 | 80 |

  4. Set element's fullscreen flag. 81 | 82 |

  5. Remove from the top layer immediately given element. 83 | 84 |

  6. Add to the top layer given element. 85 |
86 | 87 |

To unfullscreen an element, unset element's 88 | fullscreen flag and iframe fullscreen flag (if any), and 89 | remove from the top layer immediately given element. 90 | 91 |

To unfullscreen a document, 92 | unfullscreen all elements, within document's 93 | top layer, whose fullscreen flag is set. 94 | 95 |


96 | 97 |
98 |

To fully exit fullscreen a document document, run these steps: 99 | 100 |

    101 |
  1. If document's fullscreen element is null, terminate these steps. 102 | 103 |

  2. Unfullscreen elements whose fullscreen flag is 104 | set, within document's top layer, except for document's 105 | fullscreen element. 106 | 107 |

  3. Exit fullscreen document. 108 |

109 |
110 | 111 |
112 |

Whenever the removing steps run with a removedNode, run 113 | these steps: 114 | 115 |

    116 |
  1. Let document be removedNode's node document. 117 | 118 |

  2. Let nodes be removedNode's 119 | shadow-including inclusive descendants that have their fullscreen flag set, in 120 | shadow-including tree order. 121 | 122 |

  3. 123 |

    For each node in nodes: 124 | 125 |

      126 |
    1. If node is document's fullscreen element, 127 | exit fullscreen document. 128 | 129 |

    2. Otherwise, unfullscreen node. 130 | 131 |

    3. 132 |

      If document's top layer contains node, 133 | remove from the top layer immediately given node. 134 | 135 |

      Other specifications can add and remove elements from top layer, so 136 | node might not be document's fullscreen element. For example, 137 | node could be an open <{dialog}> element. 138 |

    139 |
140 |
141 | 142 |

Whenever the unloading document cleanup steps run with a document, 143 | fully exit fullscreen document. 144 | 145 |


146 | 147 |

Fullscreen is supported if there is no previously-established user preference, 148 | security risk, or platform limitation. 149 | 150 |


151 | 152 |
153 |

To run the fullscreen steps for a document document, run these 154 | steps: 155 | 156 |

    157 |
  1. Let pendingEvents be document's 158 | list of pending fullscreen events. 159 | 160 |

  2. Empty document's list of pending fullscreen events. 161 | 162 |

  3. 163 |

    For each (type, element) in pendingEvents: 164 | 165 |

      166 |
    1. Let target be element if element is connected 167 | and its node document is document, and otherwise let target be 168 | document. 169 | 170 |

    2. Fire an event named type, with its {{Event/bubbles}} and 171 | {{Event/composed}} attributes set to true, at target. 172 |

    173 |
174 | 175 |

These steps integrate with the event loop defined in HTML. [[!HTML]] 176 |

177 | 178 | 179 | 180 |

API

181 | 182 |
183 | enum FullscreenNavigationUI {
184 |   "auto",
185 |   "show",
186 |   "hide"
187 | };
188 | 
189 | dictionary FullscreenOptions {
190 |   FullscreenNavigationUI navigationUI = "auto";
191 | };
192 | 
193 | partial interface Element {
194 |   Promise<undefined> requestFullscreen(optional FullscreenOptions options = {});
195 | 
196 |   attribute EventHandler onfullscreenchange;
197 |   attribute EventHandler onfullscreenerror;
198 | };
199 | 
200 | partial interface Document {
201 |   [LegacyLenientSetter] readonly attribute boolean fullscreenEnabled;
202 |   [LegacyLenientSetter, Unscopable] readonly attribute boolean fullscreen; // historical
203 | 
204 |   Promise<undefined> exitFullscreen();
205 | 
206 |   attribute EventHandler onfullscreenchange;
207 |   attribute EventHandler onfullscreenerror;
208 | };
209 | 
210 | partial interface mixin DocumentOrShadowRoot {
211 |   [LegacyLenientSetter] readonly attribute Element? fullscreenElement;
212 | };
213 | 
214 | 216 | 217 |
218 |
promise = element . requestFullscreen([options]) 219 |
220 | Displays element fullscreen and resolves promise when done. 221 | 222 | When supplied, options's {{FullscreenOptions/navigationUI}} member indicates whether 223 | showing navigation UI while in fullscreen is preferred or not. If set to 224 | "{{FullscreenNavigationUI/show}}", navigation simplicity is preferred over screen space, and if 225 | set to "{{FullscreenNavigationUI/hide}}", more screen space is preferred. User agents are always 226 | free to honor user preference over the application's. The default value 227 | "{{FullscreenNavigationUI/auto}}" indicates no application preference. 228 | 229 |
document . {{Document/fullscreenEnabled}} 230 |

Returns true if document has the ability to display elements fullscreen 231 | and fullscreen is supported, or false otherwise. 232 | 233 |

promise = document . {{Document/exitFullscreen()}} 234 |

Stops document's fullscreen element from being displayed fullscreen and 235 | resolves promise when done. 236 | 237 |

document . {{DocumentOrShadowRoot/fullscreenElement}} 238 |

Returns document's fullscreen element. 239 | 240 |

shadowroot . {{DocumentOrShadowRoot/fullscreenElement}} 241 |

Returns shadowroot's fullscreen element. 242 |

243 | 244 |

A fullscreen element ready check for an element element returns true 245 | if all of the following are true, and false otherwise: 246 | 247 |

258 | 259 |
260 |

The requestFullscreen(options) method steps 261 | are: 262 | 263 |

    264 |
  1. Let pendingDoc be this's node document. 265 | 266 |

  2. Let promise be a new promise. 267 | 268 |

  3. If pendingDoc is not fully active, then reject promise with a 269 | {{TypeError}} exception and return promise. 270 | 271 |

  4. Let error be false. 272 | 273 |

  5. 274 |

    If any of the following conditions are false, then set error to true: 275 | 276 |

    292 | 293 |
  6. If error is false, then consume user activation given 294 | pendingDoc's relevant global object. 295 | 296 |

  7. Return promise, and run the remaining steps in parallel. 297 | 298 |

  8. 299 |

    If error is false, then resize pendingDoc's node navigable's 300 | top-level traversable's active document's viewport's 301 | dimensions, optionally taking into account 302 | options["{{FullscreenOptions/navigationUI}}"]: 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 |
    valueviewport dimensions
    "hide"full dimensions of the screen of the output device
    "show"dimensions of the screen of the output device clamped to allow the user agent to show page navigation controls
    "auto"user-agent defined, but matching one of the above
    327 | 328 |

    Optionally display a message how the end user can revert this. 329 | 330 |

  9. 331 |

    If any of the following conditions are false, then set error to true: 332 | 333 |

    339 | 340 |
  10. 341 |

    If error is true: 342 | 343 |

      344 |
    1. Append ({{fullscreenerror}}, this) to 345 | pendingDoc's list of pending fullscreen events. 346 | 347 |

    2. Reject promise with a {{TypeError}} exception and terminate these 348 | steps. 349 |

    350 | 351 |
  11. Let fullscreenElements be an ordered set initially consisting of 352 | this. 353 | 354 |

  12. 355 |

    While true: 356 | 357 |

      358 |
    1. Let last be the last item of fullscreenElements. 359 | 360 |

    2. Let container be last's node navigable's 361 | container. 362 | 363 |

    3. If container is null, then break. 364 | 365 |

    4. Append container to fullscreenElements. 366 |

    367 |
  13. 368 | 369 | 370 |
  14. 371 |

    For each element in fullscreenElements: 372 | 373 |

      374 |
    1. Let doc be element's node document. 375 | 376 |

    2. 377 |

      If element is doc's fullscreen element, continue. 378 | 379 |

      No need to notify observers when nothing has changed. 380 | 381 |

    3. If element is this and this is an <{iframe}> 382 | element, then set element's iframe fullscreen flag. 383 | 384 |

    4. Fullscreen element within doc. 385 | 386 |

    5. Append ({{fullscreenchange}}, element) to 387 | doc's list of pending fullscreen events. 388 |

    389 | 390 |

    The order in which elements are fullscreened 391 | is not observable, because run the fullscreen steps is invoked in tree order. 392 | 393 |

  15. Resolve promise with undefined. 394 |

395 | 396 |

Implementations with out-of-process navigables are left as an exercise 397 | to the reader. Input welcome on potential improvements. 398 |

399 | 400 |

The fullscreenEnabled getter steps are to return 401 | true if this is allowed to use the "fullscreen" feature and fullscreen is supported, and 403 | false otherwise. 404 | 405 |

The fullscreen getter steps are to return false if 406 | this's fullscreen element is null, and true otherwise. 407 | 408 |

Use the {{DocumentOrShadowRoot/fullscreenElement}} attribute instead. 409 | 410 |

411 |

The 412 | fullscreenElement 413 | getter steps are: 414 | 415 |

    416 |
  1. If this is a shadow root and its host is not 417 | connected, then return null. 418 | 419 |

  2. Let candidate be the result of retargeting fullscreen element 420 | against this. 421 | 422 |

  3. If candidate and this are in the same tree, then return 423 | candidate. 424 | 425 |

  4. Return null. 426 |

427 |
428 | 429 |

A document is said to be a simple fullscreen document if there is exactly one 430 | element in its top layer that has its fullscreen flag set. 431 | 432 |

A document with two elements in its top layer can be a 433 | simple fullscreen document. For example, in addition to the fullscreen element there 434 | could be an open <{dialog}> element. 435 | 436 |

437 |

To collect documents to unfullscreen given doc, run these steps: 438 | 439 |

    440 |
  1. Let docs be an ordered set consisting of doc. 441 | 442 |

  2. 443 |

    While true: 444 | 445 |

      446 |
    1. Let lastDoc be docs's last document. 447 | 448 |

    2. Assert: lastDoc's fullscreen element is not null. 449 | 450 |

    3. If lastDoc is not a simple fullscreen document, break. 451 | 452 |

    4. Let container be lastDoc's node navigable's 453 | container. 454 | 455 |

    5. If container is null, then break. 456 | 457 |

    6. If container's iframe fullscreen flag is set, break. 458 | 459 |

    7. Append container's node document to docs. 460 |

    461 | 462 |
  3. Return docs. 463 | 464 |

    This is the set of documents for which the fullscreen element will be 465 | unfullscreened, but the last document in docs might 466 | have more than one element in its top layer with the fullscreen flag set, 467 | in which case that document will still remain in fullscreen. 468 |

469 |
470 | 471 |
472 |

To exit fullscreen a document doc, run these steps: 473 | 474 |

    475 |
  1. Let promise be a new promise. 476 | 477 |

  2. If doc is not fully active or doc's fullscreen element 478 | is null, then reject promise with a {{TypeError}} exception and return 479 | promise. 480 | 481 |

  3. Let resize be false. 482 | 483 |

  4. Let docs be the result of 484 | collecting documents to unfullscreen given 485 | doc. 486 | 487 | 488 |

  5. Let topLevelDoc be doc's node navigable's 489 | top-level traversable's active document. 490 | 491 | 492 |

  6. If topLevelDoc is in docs, and it is a 493 | simple fullscreen document, then set doc to topLevelDoc and 494 | resize to true. 495 | 496 |

  7. If doc's fullscreen element is not connected: 497 |

      498 |
    1. Append ({{fullscreenchange}}, doc's 499 | fullscreen element) to doc's 500 | list of pending fullscreen events. 501 |

    502 | 503 |
  8. Return promise, and run the remaining steps in parallel. 504 | 505 |

  9. Run the [=fully unlock the screen orientation steps=] with doc. 506 | 507 |

  10. If resize is true, resize doc's viewport to its "normal" dimensions. 508 | 509 |

  11. If doc's fullscreen element is null, then resolve promise with 510 | undefined and terminate these steps. 511 | 512 |

  12. Let exitDocs be the result of 513 | collecting documents to unfullscreen given 514 | doc. 515 | 516 | 517 |

  13. Let descendantDocs be an ordered set consisting of doc's 518 | descendant navigables' active documents whose 519 | fullscreen element is non-null, if any, in tree order. 520 | 521 | 522 |

  14. 523 |

    For each exitDoc in exitDocs: 524 | 525 |

      526 |
    1. Append ({{fullscreenchange}}, exitDoc's 527 | fullscreen element) to exitDoc's list of pending fullscreen events. 528 | 529 |

    2. If resize is true, unfullscreen 530 | exitDoc. 531 | 532 |

    3. Otherwise, unfullscreen exitDoc's 533 | fullscreen element. 534 |

    535 | 536 |
  15. 537 |

    For each descendantDoc in descendantDocs: 538 | 539 |

      540 |
    1. Append ({{fullscreenchange}}, descendantDoc's 541 | fullscreen element) to descendantDoc's 542 | list of pending fullscreen events. 543 | 544 |

    2. Unfullscreen descendantDoc. 545 |

    546 | 547 |

    The order in which documents are unfullscreened 548 | is not observable, because run the fullscreen steps is invoked in tree order. 549 | 550 |

  16. Resolve promise with undefined. 551 |

552 |
553 | 554 |

The exitFullscreen() method steps are to return the 555 | result of running exit fullscreen on this. 556 | 557 |


558 | 559 |

The following are the event handlers (and their corresponding 560 | event handler event types) that must be supported by {{Element}} and {{Document}} objects as 561 | event handler IDL attributes: 562 | 563 | 564 | 565 | 566 | 569 | 570 | 573 |
event handler 567 | event handler event type 568 |
onfullscreenchange 571 | fullscreenchange 572 |
onfullscreenerror 574 | fullscreenerror 575 |
576 | 577 |

These are not supported by {{ShadowRoot}} or {{Window}} objects, and there are no 578 | corresponding event handler content attributes for {{Element}} objects in any namespace. 579 | 580 | 581 | 582 |

UI

583 | 584 |

User agents are encouraged to implement native media fullscreen controls in terms of 585 | {{Element/requestFullscreen()}} and {{Document/exitFullscreen()}}. 586 | 587 |

If the end user instructs the user agent to end a fullscreen session initiated via 588 | {{Element/requestFullscreen()}}, fully exit fullscreen given the 589 | top-level traversable's active document. 590 | 591 |

The user agent may end any fullscreen session without instruction from the end user 592 | or call to {{Document/exitFullscreen()}} whenever the user agent deems it necessary. 593 | 594 | 595 | 596 |

Rendering

597 | 598 |

This section is to be interpreted equivalently to the Rendering section of HTML. [[!HTML]] 599 | 600 | 601 |

:fullscreen pseudo-class

602 | 603 |

The :fullscreen pseudo-class must match any 604 | element element for which one of the following conditions is true: 605 | 606 |

612 | 613 |

This makes it different from the 614 | {{DocumentOrShadowRoot/fullscreenElement}} API, which returns the topmost fullscreen element. 615 | 616 |

User-agent level style sheet defaults

617 | 618 | 619 |
620 | @namespace "http://www.w3.org/1999/xhtml";
621 | 
622 | *|*:not(:root):fullscreen {
623 |   position:fixed !important;
624 |   inset:0 !important;
625 |   margin:0 !important;
626 |   box-sizing:border-box !important;
627 |   min-width:0 !important;
628 |   max-width:none !important;
629 |   min-height:0 !important;
630 |   max-height:none !important;
631 |   width:100% !important;
632 |   height:100% !important;
633 |   transform:none !important;
634 | 
635 |   /* intentionally not !important */
636 |   object-fit:contain;
637 | }
638 | 
639 | iframe:fullscreen {
640 |   border:none !important;
641 |   padding:0 !important;
642 | }
643 | 
644 | *|*:not(:root):fullscreen::backdrop {
645 |   background:black;
646 | }
647 | 
648 | 649 | 650 | 651 |

Permissions Policy 652 | Integration

653 | 654 |

This specification defines a policy-controlled feature identified by the string 655 | "fullscreen". Its default allowlist is 656 | 'self'. 657 | 658 |

659 |

A document's permissions policy determines whether any content in that 660 | document is allowed to go fullscreen. If disabled in any document, no content in the document will 661 | be allowed to use fullscreen. 662 | 663 |

The <{iframe/allowfullscreen}> attribute of the HTML <{iframe}> element affects the container 664 | policy for any document nested in that iframe. Unless overridden by the <{iframe/allow}> 665 | attribute, setting <{iframe/allowfullscreen}> on an iframe is equivalent to <iframe 666 | allow="fullscreen *">, as described in 667 | [[permissions-policy#iframe-allowfullscreen-attribute]]. 668 |

669 | 670 | 671 | 672 |

Security and Privacy Considerations

673 | 674 |

User agents should ensure, e.g. by means of an overlay, that the end user is aware something is 675 | displayed fullscreen. User agents should provide a means of exiting fullscreen that always works and 676 | advertise this to the user. This is to prevent a site from spoofing the end user by recreating the 677 | user agent or even operating system environment when fullscreen. See also the definition of 678 | {{Element/requestFullscreen()}}. 679 | 680 |

To enable content in a child navigable to go fullscreen, it needs to be specifically 681 | allowed via permissions policy, either through the <{iframe/allowfullscreen}> attribute of the HTML 682 | <{iframe}> element, or an appropriate declaration in the <{iframe/allow}> attribute of the HTML 683 | <{iframe}> element, or through a `Permissions-Policy` HTTP header 684 | delivered with the document through which it is nested. 685 | 686 |

This prevents e.g. content from third parties to go fullscreen without explicit permission. 687 | 688 | 689 | 690 |

691 | 692 | This specification previously hosted the definitions of ::backdrop 693 | and the concept of the document's top layer. 694 | 695 | 696 | 697 |

Acknowledgments

698 | 699 |

Many thanks to Robert O'Callahan for designing the initial model and being awesome. 700 | 701 | 702 |

Thanks to 703 | Andy Earnshaw, 704 | Changwan Hong, 705 | Chris Pearce, 706 | Darin Fisher, 707 | Dave Tapuska, 708 | fantasai, 709 | Giuseppe Pascale, 710 | Glenn Maynard, 711 | Ian Clelland, 712 | Ian Hickson, 713 | Ignacio Solla, 714 | João Eiras, 715 | Josh Soref, 716 | Kagami Sascha Rosylight, 717 | Matt Falkenhagen, 718 | Mihai Balan, 719 | Mounir Lamouri, 720 | Øyvind Stenhaug, 721 | Pat Ladd, 722 | Rafał Chłodnicki, 723 | Riff Jiang, 724 | Rune Lillesveen, 725 | Sigbjørn Vik, 726 | Simon Pieters, 727 | Tab Atkins-Bittner, 728 | Takayoshi Kochi, 729 | Theresa O'Connor, 730 | triple-underscore, 731 | Vincent Scheib, and 732 | Xidorn Quan 733 | for also being awesome. 734 | 735 |

This standard is edited by Philip Jägenstedt 736 | (Google, 737 | philip@foolip.org). It was originally written by 738 | Anne van Kesteren 739 | (Apple, annevk@annevk.nl). 740 | Tantek Çelik 741 | (Mozilla, 742 | tantek@cs.stanford.edu) sorted out legal hassles. 743 | --------------------------------------------------------------------------------