| 
WARNING:
The push did not contain any new commits, but force pushed to delete the commits and changes below.
 
Deleted commits:
6a6c68cf
 by Edgar Chen   at 2023-07-31T17:56:02+00:00 
 Bug 1821884 - Ensure consistent state for fullscreen/pointerlock warnings; r=Gijs
Fullscreen/PointerLock warnings are initialized with hidden="true", but
change to hidden="" after being shown and hidden again. I think this
started happening when we began using HTML elements instead of XUL as
they handle hidden attribute differently.
Differential Revision: https://phabricator.services.mozilla.com/D177790
5e8c1b08
 by Edgar Chen   at 2023-07-31T17:56:07+00:00 
 Bug 1821884 - Reshow initial fullscreen notification; r=Gijs
Depends on D177790
Differential Revision: https://phabricator.services.mozilla.com/D178339 
4 changed files:
Changes:
browser/base/content/browser-fullScreenAndPointerLock.js
 
| ... | ... | @@ -62,9 +62,14 @@ var PointerlockFsWarning = { |  
| 62 | 62 |        this._element = document.getElementById(elementId);
 |  
| 63 | 63 |        // Setup event listeners
 |  
| 64 | 64 |        this._element.addEventListener("transitionend", this);
 |  
|  | 65 | +      this._element.addEventListener("transitioncancel", this);
 |  
| 65 | 66 |        window.addEventListener("mousemove", this, true);
 |  
|  | 67 | +      window.addEventListener("activate", this);
 |  
|  | 68 | +      window.addEventListener("deactivate", this);
 |  
| 66 | 69 |        // The timeout to hide the warning box after a while.
 |  
| 67 | 70 |        this._timeoutHide = new this.Timeout(() => {
 |  
|  | 71 | +        window.removeEventListener("activate", this);
 |  
|  | 72 | +        window.removeEventListener("deactivate", this);
 |  
| 68 | 73 |          this._state = "hidden";
 |  
| 69 | 74 |        }, timeout);
 |  
| 70 | 75 |        // The timeout to show the warning box when the pointer is at the top
 |  
| ... | ... | @@ -116,11 +121,10 @@ var PointerlockFsWarning = { |  
| 116 | 121 |        return;
 |  
| 117 | 122 |      }
 |  
| 118 | 123 |  
 |  
| 119 |  | -    // Explicitly set the last state to hidden to avoid the warning
 |  
| 120 |  | -    // box being hidden immediately because of mousemove.
 |  
| 121 |  | -    this._state = "onscreen";
 |  
| 122 |  | -    this._lastState = "hidden";
 |  
| 123 |  | -    this._timeoutHide.start();
 |  
|  | 124 | +    if (Services.focus.activeWindow == window) {
 |  
|  | 125 | +      this._state = "onscreen";
 |  
|  | 126 | +      this._timeoutHide.start();
 |  
|  | 127 | +    }
 |  
| 124 | 128 |    },
 |  
| 125 | 129 |  
 |  
| 126 | 130 |    /**
 |  
| ... | ... | @@ -148,7 +152,10 @@ var PointerlockFsWarning = { |  
| 148 | 152 |      this._element.hidden = true;
 |  
| 149 | 153 |      // Remove all event listeners
 |  
| 150 | 154 |      this._element.removeEventListener("transitionend", this);
 |  
|  | 155 | +    this._element.removeEventListener("transitioncancel", this);
 |  
| 151 | 156 |      window.removeEventListener("mousemove", this, true);
 |  
|  | 157 | +    window.removeEventListener("activate", this);
 |  
|  | 158 | +    window.removeEventListener("deactivate", this);
 |  
| 152 | 159 |      // Clear fields
 |  
| 153 | 160 |      this._element = null;
 |  
| 154 | 161 |      this._timeoutHide = null;
 |  
| ... | ... | @@ -186,7 +193,7 @@ var PointerlockFsWarning = { |  
| 186 | 193 |      }
 |  
| 187 | 194 |      if (newState != "hidden") {
 |  
| 188 | 195 |        if (currentState != "hidden") {
 |  
| 189 |  | -        this._element.setAttribute(newState, true);
 |  
|  | 196 | +        this._element.setAttribute(newState, "");
 |  
| 190 | 197 |        } else {
 |  
| 191 | 198 |          // When the previous state is hidden, the display was none,
 |  
| 192 | 199 |          // thus no box was constructed. We need to wait for the new
 |  
| ... | ... | @@ -197,7 +204,7 @@ var PointerlockFsWarning = { |  
| 197 | 204 |          requestAnimationFrame(() => {
 |  
| 198 | 205 |            requestAnimationFrame(() => {
 |  
| 199 | 206 |              if (this._element) {
 |  
| 200 |  | -              this._element.setAttribute(newState, true);
 |  
|  | 207 | +              this._element.setAttribute(newState, "");
 |  
| 201 | 208 |              }
 |  
| 202 | 209 |            });
 |  
| 203 | 210 |          });
 |  
| ... | ... | @@ -217,7 +224,7 @@ var PointerlockFsWarning = { |  
| 217 | 224 |            } else if (this._timeoutShow.delay >= 0) {
 |  
| 218 | 225 |              this._timeoutShow.start();
 |  
| 219 | 226 |            }
 |  
| 220 |  | -        } else {
 |  
|  | 227 | +        } else if (state != "onscreen") {
 |  
| 221 | 228 |            let elemRect = this._element.getBoundingClientRect();
 |  
| 222 | 229 |            if (state == "hiding" && this._lastState != "hidden") {
 |  
| 223 | 230 |              // If we are on the hiding transition, and the pointer
 |  
| ... | ... | @@ -239,12 +246,23 @@ var PointerlockFsWarning = { |  
| 239 | 246 |          }
 |  
| 240 | 247 |          break;
 |  
| 241 | 248 |        }
 |  
| 242 |  | -      case "transitionend": {
 |  
|  | 249 | +      case "transitionend":
 |  
|  | 250 | +      case "transitioncancel": {
 |  
| 243 | 251 |          if (this._state == "hiding") {
 |  
| 244 | 252 |            this._element.hidden = true;
 |  
| 245 | 253 |          }
 |  
| 246 | 254 |          break;
 |  
| 247 | 255 |        }
 |  
|  | 256 | +      case "activate": {
 |  
|  | 257 | +        this._state = "onscreen";
 |  
|  | 258 | +        this._timeoutHide.start();
 |  
|  | 259 | +        break;
 |  
|  | 260 | +      }
 |  
|  | 261 | +      case "deactivate": {
 |  
|  | 262 | +        this._state = "hidden";
 |  
|  | 263 | +        this._timeoutHide.cancel();
 |  
|  | 264 | +        break;
 |  
|  | 265 | +      }
 |  
| 248 | 266 |      }
 |  
| 249 | 267 |    },
 |  
| 250 | 268 |  };
 |  browser/base/content/fullscreen-and-pointerlock.inc.xhtml
 
 
| ... | ... | @@ -3,7 +3,7 @@ |  
| 3 | 3 |  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 |  
| 4 | 4 |  
 |  
| 5 | 5 |  <html:div id="fullscreen-and-pointerlock-wrapper">
 |  
| 6 |  | -  <html:div id="fullscreen-warning" class="pointerlockfswarning" hidden="true">
 |  
|  | 6 | +  <html:div id="fullscreen-warning" class="pointerlockfswarning" hidden="">
 |  
| 7 | 7 |      <html:div class="pointerlockfswarning-domain-text">
 |  
| 8 | 8 |        <html:span class="pointerlockfswarning-domain" data-l10n-name="domain"/>
 |  
| 9 | 9 |      </html:div>
 |  
| ... | ... | @@ -20,7 +20,7 @@ |  
| 20 | 20 |      </html:button>
 |  
| 21 | 21 |    </html:div>
 |  
| 22 | 22 |  
 |  
| 23 |  | -  <html:div id="pointerlock-warning" class="pointerlockfswarning" hidden="true">
 |  
|  | 23 | +  <html:div id="pointerlock-warning" class="pointerlockfswarning" hidden="">
 |  
| 24 | 24 |      <html:div class="pointerlockfswarning-domain-text">
 |  
| 25 | 25 |        <html:span class="pointerlockfswarning-domain" data-l10n-name="domain"/>
 |  
| 26 | 26 |      </html:div>
 |  browser/base/content/test/fullscreen/browser_fullscreen_warning.js
 
 
| ... | ... | @@ -3,14 +3,35 @@ |  
| 3 | 3 |  
 |  
| 4 | 4 |  "use strict";
 |  
| 5 | 5 |  
 |  
| 6 |  | -add_task(async function test_fullscreen_display_none() {
 |  
|  | 6 | +function checkWarningState(aWarningElement, aExpectedState, aMsg) {
 |  
|  | 7 | +  ["hidden", "ontop", "onscreen"].forEach(state => {
 |  
|  | 8 | +    is(
 |  
|  | 9 | +      aWarningElement.hasAttribute(state),
 |  
|  | 10 | +      state == aExpectedState,
 |  
|  | 11 | +      `${aMsg} - check ${state} attribute.`
 |  
|  | 12 | +    );
 |  
|  | 13 | +  });
 |  
|  | 14 | +}
 |  
|  | 15 | +
 |  
|  | 16 | +async function waitForWarningState(aWarningElement, aExpectedState) {
 |  
|  | 17 | +  await BrowserTestUtils.waitForAttribute(aExpectedState, aWarningElement, "");
 |  
|  | 18 | +  checkWarningState(
 |  
|  | 19 | +    aWarningElement,
 |  
|  | 20 | +    aExpectedState,
 |  
|  | 21 | +    `Wait for ${aExpectedState} state`
 |  
|  | 22 | +  );
 |  
|  | 23 | +}
 |  
|  | 24 | +
 |  
|  | 25 | +add_setup(async function init() {
 |  
| 7 | 26 |    await SpecialPowers.pushPrefEnv({
 |  
| 8 | 27 |      set: [
 |  
| 9 | 28 |        ["full-screen-api.enabled", true],
 |  
| 10 | 29 |        ["full-screen-api.allow-trusted-requests-only", false],
 |  
| 11 | 30 |      ],
 |  
| 12 | 31 |    });
 |  
|  | 32 | +});
 |  
| 13 | 33 |  
 |  
|  | 34 | +add_task(async function test_fullscreen_display_none() {
 |  
| 14 | 35 |    await BrowserTestUtils.withNewTab(
 |  
| 15 | 36 |      {
 |  
| 16 | 37 |        gBrowser,
 |  
| ... | ... | @@ -30,11 +51,13 @@ add_task(async function test_fullscreen_display_none() { |  
| 30 | 51 |      },
 |  
| 31 | 52 |      async function (browser) {
 |  
| 32 | 53 |        let warning = document.getElementById("fullscreen-warning");
 |  
| 33 |  | -      let warningShownPromise = BrowserTestUtils.waitForAttribute(
 |  
| 34 |  | -        "onscreen",
 |  
|  | 54 | +      checkWarningState(
 |  
| 35 | 55 |          warning,
 |  
| 36 |  | -        "true"
 |  
|  | 56 | +        "hidden",
 |  
|  | 57 | +        "Should not show full screen warning initially"
 |  
| 37 | 58 |        );
 |  
|  | 59 | +
 |  
|  | 60 | +      let warningShownPromise = waitForWarningState(warning, "onscreen");
 |  
| 38 | 61 |        // Enter fullscreen
 |  
| 39 | 62 |        await SpecialPowers.spawn(browser, [], async () => {
 |  
| 40 | 63 |          let frame = content.document.querySelector("iframe");
 |  
| ... | ... | @@ -54,39 +77,33 @@ add_task(async function test_fullscreen_display_none() { |  
| 54 | 77 |        );
 |  
| 55 | 78 |        document.getElementById("fullscreen-exit-button").click();
 |  
| 56 | 79 |        await exitFullscreenPromise;
 |  
|  | 80 | +
 |  
|  | 81 | +      checkWarningState(
 |  
|  | 82 | +        warning,
 |  
|  | 83 | +        "hidden",
 |  
|  | 84 | +        "Should hide fullscreen warning after exiting fullscreen"
 |  
|  | 85 | +      );
 |  
| 57 | 86 |      }
 |  
| 58 | 87 |    );
 |  
| 59 | 88 |  });
 |  
| 60 | 89 |  
 |  
| 61 | 90 |  add_task(async function test_fullscreen_pointerlock_conflict() {
 |  
| 62 |  | -  await SpecialPowers.pushPrefEnv({
 |  
| 63 |  | -    set: [
 |  
| 64 |  | -      ["full-screen-api.enabled", true],
 |  
| 65 |  | -      ["full-screen-api.allow-trusted-requests-only", false],
 |  
| 66 |  | -    ],
 |  
| 67 |  | -  });
 |  
| 68 |  | -
 |  
| 69 | 91 |    await BrowserTestUtils.withNewTab("https://example.com", async browser => {
 |  
| 70 | 92 |      let fsWarning = document.getElementById("fullscreen-warning");
 |  
| 71 | 93 |      let plWarning = document.getElementById("pointerlock-warning");
 |  
| 72 | 94 |  
 |  
| 73 |  | -    is(
 |  
| 74 |  | -      fsWarning.getAttribute("onscreen"),
 |  
| 75 |  | -      null,
 |  
| 76 |  | -      "Should not show full screen warning initially."
 |  
| 77 |  | -    );
 |  
| 78 |  | -    is(
 |  
| 79 |  | -      plWarning.getAttribute("onscreen"),
 |  
| 80 |  | -      null,
 |  
| 81 |  | -      "Should not show pointer lock warning initially."
 |  
| 82 |  | -    );
 |  
| 83 |  | -
 |  
| 84 |  | -    let fsWarningShownPromise = BrowserTestUtils.waitForAttribute(
 |  
| 85 |  | -      "onscreen",
 |  
|  | 95 | +    checkWarningState(
 |  
| 86 | 96 |        fsWarning,
 |  
| 87 |  | -      "true"
 |  
|  | 97 | +      "hidden",
 |  
|  | 98 | +      "Should not show full screen warning initially"
 |  
|  | 99 | +    );
 |  
|  | 100 | +    checkWarningState(
 |  
|  | 101 | +      plWarning,
 |  
|  | 102 | +      "hidden",
 |  
|  | 103 | +      "Should not show pointer lock warning initially"
 |  
| 88 | 104 |      );
 |  
| 89 | 105 |  
 |  
|  | 106 | +    let fsWarningShownPromise = waitForWarningState(fsWarning, "onscreen");
 |  
| 90 | 107 |      info("Entering full screen and pointer lock.");
 |  
| 91 | 108 |      await SpecialPowers.spawn(browser, [], async () => {
 |  
| 92 | 109 |        await content.document.body.requestFullscreen();
 |  
| ... | ... | @@ -94,15 +111,10 @@ add_task(async function test_fullscreen_pointerlock_conflict() { |  
| 94 | 111 |      });
 |  
| 95 | 112 |  
 |  
| 96 | 113 |      await fsWarningShownPromise;
 |  
| 97 |  | -    is(
 |  
| 98 |  | -      fsWarning.getAttribute("onscreen"),
 |  
| 99 |  | -      "true",
 |  
| 100 |  | -      "Should show full screen warning."
 |  
| 101 |  | -    );
 |  
| 102 |  | -    is(
 |  
| 103 |  | -      plWarning.getAttribute("onscreen"),
 |  
| 104 |  | -      null,
 |  
| 105 |  | -      "Should not show pointer lock warning."
 |  
|  | 114 | +    checkWarningState(
 |  
|  | 115 | +      plWarning,
 |  
|  | 116 | +      "hidden",
 |  
|  | 117 | +      "Should not show pointer lock warning"
 |  
| 106 | 118 |      );
 |  
| 107 | 119 |  
 |  
| 108 | 120 |      info("Exiting pointerlock");
 |  
| ... | ... | @@ -110,18 +122,19 @@ add_task(async function test_fullscreen_pointerlock_conflict() { |  
| 110 | 122 |        await content.document.exitPointerLock();
 |  
| 111 | 123 |      });
 |  
| 112 | 124 |  
 |  
| 113 |  | -    is(
 |  
| 114 |  | -      fsWarning.getAttribute("onscreen"),
 |  
| 115 |  | -      "true",
 |  
| 116 |  | -      "Should still show full screen warning."
 |  
|  | 125 | +    checkWarningState(
 |  
|  | 126 | +      fsWarning,
 |  
|  | 127 | +      "onscreen",
 |  
|  | 128 | +      "Should still show full screen warning"
 |  
| 117 | 129 |      );
 |  
| 118 |  | -    is(
 |  
| 119 |  | -      plWarning.getAttribute("onscreen"),
 |  
| 120 |  | -      null,
 |  
| 121 |  | -      "Should not show pointer lock warning."
 |  
|  | 130 | +    checkWarningState(
 |  
|  | 131 | +      plWarning,
 |  
|  | 132 | +      "hidden",
 |  
|  | 133 | +      "Should not show pointer lock warning"
 |  
| 122 | 134 |      );
 |  
| 123 | 135 |  
 |  
| 124 | 136 |      // Cleanup
 |  
|  | 137 | +    info("Exiting fullscreen");
 |  
| 125 | 138 |      await document.exitFullscreen();
 |  
| 126 | 139 |    });
 |  
| 127 | 140 |  }); |  dom/tests/browser/browser_pointerlock_warning.js
 
 
| ... | ... | @@ -15,6 +15,25 @@ const FRAME_TEST_URL = |  
| 15 | 15 |    encodeURI(BODY_URL) +
 |  
| 16 | 16 |    '"></iframe></body>';
 |  
| 17 | 17 |  
 |  
|  | 18 | +function checkWarningState(aWarningElement, aExpectedState, aMsg) {
 |  
|  | 19 | +  ["hidden", "ontop", "onscreen"].forEach(state => {
 |  
|  | 20 | +    is(
 |  
|  | 21 | +      aWarningElement.hasAttribute(state),
 |  
|  | 22 | +      state == aExpectedState,
 |  
|  | 23 | +      `${aMsg} - check ${state} attribute.`
 |  
|  | 24 | +    );
 |  
|  | 25 | +  });
 |  
|  | 26 | +}
 |  
|  | 27 | +
 |  
|  | 28 | +async function waitForWarningState(aWarningElement, aExpectedState) {
 |  
|  | 29 | +  await BrowserTestUtils.waitForAttribute(aExpectedState, aWarningElement, "");
 |  
|  | 30 | +  checkWarningState(
 |  
|  | 31 | +    aWarningElement,
 |  
|  | 32 | +    aExpectedState,
 |  
|  | 33 | +    `Wait for ${aExpectedState} state`
 |  
|  | 34 | +  );
 |  
|  | 35 | +}
 |  
|  | 36 | +
 |  
| 18 | 37 |  // Make sure the pointerlock warning is shown and exited with the escape key
 |  
| 19 | 38 |  add_task(async function show_pointerlock_warning_escape() {
 |  
| 20 | 39 |    let urls = [TEST_URL, FRAME_TEST_URL];
 |  
| ... | ... | @@ -24,11 +43,7 @@ add_task(async function show_pointerlock_warning_escape() { |  
| 24 | 43 |      let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
 |  
| 25 | 44 |  
 |  
| 26 | 45 |      let warning = document.getElementById("pointerlock-warning");
 |  
| 27 |  | -    let warningShownPromise = BrowserTestUtils.waitForAttribute(
 |  
| 28 |  | -      "onscreen",
 |  
| 29 |  | -      warning,
 |  
| 30 |  | -      "true"
 |  
| 31 |  | -    );
 |  
|  | 46 | +    let warningShownPromise = waitForWarningState(warning, "onscreen");
 |  
| 32 | 47 |  
 |  
| 33 | 48 |      let expectedWarningText;
 |  
| 34 | 49 |  
 |  
| ... | ... | @@ -49,11 +64,7 @@ add_task(async function show_pointerlock_warning_escape() { |  
| 49 | 64 |  
 |  
| 50 | 65 |      ok(true, "Pointerlock warning shown");
 |  
| 51 | 66 |  
 |  
| 52 |  | -    let warningHiddenPromise = BrowserTestUtils.waitForAttribute(
 |  
| 53 |  | -      "hidden",
 |  
| 54 |  | -      warning,
 |  
| 55 |  | -      ""
 |  
| 56 |  | -    );
 |  
|  | 67 | +    let warningHiddenPromise = waitForWarningState(warning, "hidden");
 |  
| 57 | 68 |  
 |  
| 58 | 69 |      await BrowserTestUtils.waitForCondition(
 |  
| 59 | 70 |        () => warning.innerText == expectedWarningText,
 |  
 |