diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27b53d3ec..7a5ebc971 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -298,7 +298,6 @@ jobs: secrets: inherit with: use-sccache: ${{ inputs.use-sccache }} - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} generate-pgo: true profile-data-path-archive: zen-windows-profile-data-and-jarlog.zip @@ -314,7 +313,6 @@ jobs: secrets: inherit needs: [windows-step-1, build-data] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} profile-data-path-archive: zen.win64-pgo-stage-1.zip release-branch: ${{ inputs.update_branch }} @@ -329,7 +327,6 @@ jobs: if: ${{ !failure() && !cancelled() }} needs: [build-data, windows-step-2, start-self-host, buildid] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} generate-pgo: false disable-pgo: ${{ inputs.disable-pgo }} @@ -345,7 +342,6 @@ jobs: secrets: inherit needs: [build-data, start-self-host, buildid] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} release-branch: ${{ inputs.update_branch }} MOZ_BUILD_DATE: ${{needs.buildid.outputs.buildids}} @@ -362,7 +358,6 @@ jobs: secrets: inherit with: use-sccache: ${{ inputs.use-sccache }} - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} generate-pgo: true release-branch: ${{ inputs.update_branch }} @@ -377,7 +372,6 @@ jobs: secrets: inherit needs: [mac-step-1, build-data] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} release-branch: ${{ inputs.update_branch }} @@ -391,7 +385,6 @@ jobs: if: ${{ !failure() && !cancelled() }} needs: [build-data, mac-step-2, start-self-host, buildid] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} generate-pgo: false disable-pgo: ${{ inputs.disable-pgo }} @@ -407,7 +400,6 @@ jobs: secrets: inherit needs: [build-data, mac-step-3] with: - force-candidate: ${{ !inputs.create_release }} build-version: ${{ needs.build-data.outputs.version }} release-branch: ${{ inputs.update_branch }} diff --git a/.github/workflows/linux-release-build.yml b/.github/workflows/linux-release-build.yml index 7415eee48..4841eea82 100644 --- a/.github/workflows/linux-release-build.yml +++ b/.github/workflows/linux-release-build.yml @@ -25,14 +25,6 @@ on: required: false type: boolean default: false - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false - -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: build-linux: diff --git a/.github/workflows/macos-profile-build.yml b/.github/workflows/macos-profile-build.yml index 9dbbcaff4..43aa552b2 100644 --- a/.github/workflows/macos-profile-build.yml +++ b/.github/workflows/macos-profile-build.yml @@ -14,14 +14,6 @@ on: description: "The branch to build" required: true type: string - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false - -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: macos-profile-build: diff --git a/.github/workflows/macos-release-build.yml b/.github/workflows/macos-release-build.yml index 6e45fd2fc..72d7f2ee9 100644 --- a/.github/workflows/macos-release-build.yml +++ b/.github/workflows/macos-release-build.yml @@ -32,14 +32,6 @@ on: required: true type: boolean default: false - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false - -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: mac-build: diff --git a/.github/workflows/macos-universal-release-build.yml b/.github/workflows/macos-universal-release-build.yml index ecadde63f..101d39738 100644 --- a/.github/workflows/macos-universal-release-build.yml +++ b/.github/workflows/macos-universal-release-build.yml @@ -11,14 +11,6 @@ on: description: "The branch to build" required: true type: string - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false - -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: mac-build: diff --git a/.github/workflows/windows-profile-build.yml b/.github/workflows/windows-profile-build.yml index 888a237b8..694672647 100644 --- a/.github/workflows/windows-profile-build.yml +++ b/.github/workflows/windows-profile-build.yml @@ -18,14 +18,6 @@ on: description: "The branch to build" required: true type: string - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false - -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: windows-profile-build: diff --git a/.github/workflows/windows-release-build.yml b/.github/workflows/windows-release-build.yml index 9741ca354..970636be3 100644 --- a/.github/workflows/windows-release-build.yml +++ b/.github/workflows/windows-release-build.yml @@ -35,13 +35,6 @@ on: required: true type: boolean default: false - force-candidate: - description: "Force building against the Firefox release candidate" - required: false - type: boolean - default: false -env: - SURFER_FORCE_CANDIDATE: ${{ inputs.force-candidate && '1' || '' }} jobs: windows-build: diff --git a/README.md b/README.md index f391024f4..45db3aa51 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Zen is a firefox-based browser with the aim of pushing your productivity to a ne ### Firefox Versions -- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `154.0.1`! +- [`Release`](https://zen-browser.app/download) - Is currently built using Firefox version `155.0`! - [`Twilight`](https://zen-browser.app/download?twilight) - Is currently built using Firefox version `RC 155.0`! ### Contributing diff --git a/build/firefox-cache/l10n-last-commit-hash b/build/firefox-cache/l10n-last-commit-hash index e668d9111..24e25043a 100644 --- a/build/firefox-cache/l10n-last-commit-hash +++ b/build/firefox-cache/l10n-last-commit-hash @@ -1 +1 @@ -6b4abe0093721c1be89eb41b3fb060dd6336923d \ No newline at end of file +20e5abbb642ab21d943bc1261864d9c531ba421a \ No newline at end of file diff --git a/prefs/zen/sync.yaml b/prefs/zen/sync.yaml index 9ed0efc35..8424b23f8 100644 --- a/prefs/zen/sync.yaml +++ b/prefs/zen/sync.yaml @@ -3,13 +3,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. - name: services.sync.engine.spaces - value: true + value: "@cond" condition: "@IS_TWILIGHT@" -- name: services.sync.engine.spaces - value: false - locked: true - condition: "!@IS_TWILIGHT@" - - name: zen.spaces-sync.debug value: false diff --git a/src/browser/themes/shared/zen-icons/icons.css b/src/browser/themes/shared/zen-icons/icons.css index 5a083ca7d..8a7c01c8e 100644 --- a/src/browser/themes/shared/zen-icons/icons.css +++ b/src/browser/themes/shared/zen-icons/icons.css @@ -435,10 +435,6 @@ list-style-image: url("arrow-left.svg") !important; } -#appmenu-moreTools-button { - list-style-image: url("customize.svg") !important; -} - #zen-copy-current-url-button, #share-tab-button, #zen-site-data-header-share { diff --git a/src/browser/themes/shared/zen-icons/jar.inc.mn b/src/browser/themes/shared/zen-icons/jar.inc.mn index 91c0cc49d..145e97214 100644 --- a/src/browser/themes/shared/zen-icons/jar.inc.mn +++ b/src/browser/themes/shared/zen-icons/jar.inc.mn @@ -14,8 +14,8 @@ * skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg) * skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg) * skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg) -* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg) +* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg) * skin/classic/browser/zen-icons/bookmark-hollow.svg (../shared/zen-icons/nucleo/bookmark-hollow.svg) * skin/classic/browser/zen-icons/bookmark-star-on-tray.svg (../shared/zen-icons/nucleo/bookmark-star-on-tray.svg) @@ -104,26 +104,27 @@ * skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg) * skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg) * skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg) -* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) +* skin/classic/browser/zen-icons/private-window-small.svg (../shared/zen-icons/nucleo/private-window-small.svg) * skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg) +* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) * skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg) * skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg) * skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg) * skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg) -* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg) +* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg) * skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg) * skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg) -* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg) +* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg) * skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg) * skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg) * skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg) * skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg) -* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg) +* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg) * skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg) * skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg) @@ -164,8 +165,8 @@ * skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg) * skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg) * skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg) -* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg) +* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg) * skin/classic/browser/zen-icons/bookmark-hollow.svg (../shared/zen-icons/nucleo/bookmark-hollow.svg) * skin/classic/browser/zen-icons/bookmark-star-on-tray.svg (../shared/zen-icons/nucleo/bookmark-star-on-tray.svg) @@ -254,26 +255,27 @@ * skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg) * skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg) * skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg) -* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) +* skin/classic/browser/zen-icons/private-window-small.svg (../shared/zen-icons/nucleo/private-window-small.svg) * skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg) +* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) * skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg) * skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg) * skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg) * skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg) -* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg) +* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg) * skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg) * skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg) -* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg) +* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg) * skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg) * skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg) * skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg) * skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg) -* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg) +* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg) * skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg) * skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg) @@ -314,8 +316,8 @@ * skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg) * skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg) * skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg) -* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg) +* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg) * skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg) * skin/classic/browser/zen-icons/bookmark-hollow.svg (../shared/zen-icons/nucleo/bookmark-hollow.svg) * skin/classic/browser/zen-icons/bookmark-star-on-tray.svg (../shared/zen-icons/nucleo/bookmark-star-on-tray.svg) @@ -404,26 +406,27 @@ * skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg) * skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg) * skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg) -* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) +* skin/classic/browser/zen-icons/private-window-small.svg (../shared/zen-icons/nucleo/private-window-small.svg) * skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg) +* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg) * skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg) * skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg) * skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg) * skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg) -* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg) +* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg) * skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg) * skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg) * skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg) -* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg) +* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg) * skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg) * skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg) * skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg) * skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg) * skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg) -* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg) +* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg) * skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg) * skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg) * skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg) @@ -459,8 +462,8 @@ * skin/classic/browser/zen-icons/selectable/basket.svg (../shared/zen-icons/common/selectable/basket.svg) * skin/classic/browser/zen-icons/selectable/bed.svg (../shared/zen-icons/common/selectable/bed.svg) * skin/classic/browser/zen-icons/selectable/bell.svg (../shared/zen-icons/common/selectable/bell.svg) -* skin/classic/browser/zen-icons/selectable/bookmark.svg (../shared/zen-icons/common/selectable/bookmark.svg) * skin/classic/browser/zen-icons/selectable/book.svg (../shared/zen-icons/common/selectable/book.svg) +* skin/classic/browser/zen-icons/selectable/bookmark.svg (../shared/zen-icons/common/selectable/bookmark.svg) * skin/classic/browser/zen-icons/selectable/briefcase.svg (../shared/zen-icons/common/selectable/briefcase.svg) * skin/classic/browser/zen-icons/selectable/brush.svg (../shared/zen-icons/common/selectable/brush.svg) * skin/classic/browser/zen-icons/selectable/bug.svg (../shared/zen-icons/common/selectable/bug.svg) @@ -522,8 +525,8 @@ * skin/classic/browser/zen-icons/selectable/shapes.svg (../shared/zen-icons/common/selectable/shapes.svg) * skin/classic/browser/zen-icons/selectable/shirt.svg (../shared/zen-icons/common/selectable/shirt.svg) * skin/classic/browser/zen-icons/selectable/skull.svg (../shared/zen-icons/common/selectable/skull.svg) -* skin/classic/browser/zen-icons/selectable/squares.svg (../shared/zen-icons/common/selectable/squares.svg) * skin/classic/browser/zen-icons/selectable/square.svg (../shared/zen-icons/common/selectable/square.svg) +* skin/classic/browser/zen-icons/selectable/squares.svg (../shared/zen-icons/common/selectable/squares.svg) * skin/classic/browser/zen-icons/selectable/star-1.svg (../shared/zen-icons/common/selectable/star-1.svg) * skin/classic/browser/zen-icons/selectable/star.svg (../shared/zen-icons/common/selectable/star.svg) * skin/classic/browser/zen-icons/selectable/stats-chart.svg (../shared/zen-icons/common/selectable/stats-chart.svg) diff --git a/src/browser/themes/shared/zen-icons/nucleo/private-window-small.svg b/src/browser/themes/shared/zen-icons/nucleo/private-window-small.svg new file mode 100644 index 000000000..f8cc1bb19 --- /dev/null +++ b/src/browser/themes/shared/zen-icons/nucleo/private-window-small.svg @@ -0,0 +1,5 @@ +#filter dumbComments emptyLines substitution +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + diff --git a/src/external-patches/firefox/issue_14710.patch b/src/external-patches/firefox/issue_14710.patch index 54e288ed8..da0f7160e 100644 --- a/src/external-patches/firefox/issue_14710.patch +++ b/src/external-patches/firefox/issue_14710.patch @@ -1,7 +1,24 @@ diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs --- a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs +++ b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs -@@ -119,10 +119,19 @@ +@@ -39,10 +39,16 @@ + const TOGGLE_POSITION_PREF = + "media.videocontrols.picture-in-picture.video-toggle.position"; + const TOGGLE_POSITION_RIGHT = "right"; + const TOGGLE_POSITION_LEFT = "left"; + const RESIZE_MARGIN_PX = 16; ++// Close reasons that should suppress auto-toggle when the originating tab is backgrounded ++const DELIBERATE_CLOSE_REASONS = [ ++ "CloseButton", ++ "ClosePlayerShortcut", ++ "Shortcut", ++]; + + XPCOMUtils.defineLazyPreferenceGetter( + lazy, + "PIP_ENABLED", + "media.videocontrols.picture-in-picture.enabled", +@@ -119,10 +125,19 @@ } case "PictureInPicture:VideoTabHidden": { if (!lazy.PIP_ENABLED || !lazy.PIP_WHEN_SWITCHING_TABS) { @@ -21,12 +38,13 @@ diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/tool break; } let actor = browsingContext.currentWindowGlobal.getActor( -@@ -261,10 +270,12 @@ +@@ -261,10 +276,13 @@ maxConcurrentPlayerCount: 0, // Maps auto pip browser to PictureInPictureParent actor weakAutoPipBrowserToParent: new WeakMap(), ++ // Browsers with deliberately closed PiP windows; suppresses auto-toggle. + weakAutoPipBrowserClosedDeliberately: new WeakSet(), + /** @@ -34,7 +52,28 @@ diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/tool * * @param {PictureInPictureParent} pipActorRef * Reference to the calling PictureInPictureParent actor -@@ -899,10 +910,17 @@ +@@ -441,10 +459,20 @@ + }, + + onPipSwappedBrowsers(event) { + let otherTab = event.detail; + if (otherTab) { ++ if ( ++ this.weakAutoPipBrowserClosedDeliberately.has( ++ event.target.linkedBrowser ++ ) ++ ) { ++ this.weakAutoPipBrowserClosedDeliberately.add(otherTab.linkedBrowser); ++ this.weakAutoPipBrowserClosedDeliberately.delete( ++ event.target.linkedBrowser ++ ); ++ } + for (let win of Services.wm.getEnumerator(WINDOW_TYPE)) { + if (this.weakWinToBrowser.get(win) === event.target.linkedBrowser) { + this.weakWinToBrowser.set(win, otherTab.linkedBrowser); + this.removePiPBrowserFromWeakMap(event.target.linkedBrowser); + this.removeOriginatingWinFromWeakMap(event.target.linkedBrowser); +@@ -899,10 +927,20 @@ const { reason, actorRef } = closeData; const win = this.getWeakPipPlayer(actorRef); if (!win) { @@ -43,8 +82,11 @@ diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/tool + + const browser = this.weakWinToBrowser.get(win); + -+ if (reason === "CloseButton") { -+ PictureInPicture.weakAutoPipBrowserClosedDeliberately.add(browser); ++ if (browser && DELIBERATE_CLOSE_REASONS.includes(reason)) { ++ const tabbrowser = browser.getTabBrowser(); ++ if (tabbrowser && tabbrowser.selectedBrowser != browser) { ++ PictureInPicture.weakAutoPipBrowserClosedDeliberately.add(browser); ++ } + } + this.removePiPBrowserFromWeakMap(this.weakWinToBrowser.get(win)); @@ -52,4 +94,69 @@ diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/tool Glean.pictureinpicture["closedMethod" + reason].record(); await this.closePipWindow(win); +diff --git a/toolkit/components/pictureinpicture/tests/browser_autotoggle.js b/toolkit/components/pictureinpicture/tests/browser_autotoggle.js +--- a/toolkit/components/pictureinpicture/tests/browser_autotoggle.js ++++ b/toolkit/components/pictureinpicture/tests/browser_autotoggle.js +@@ -297,5 +297,61 @@ + await new Promise(resolve => setTimeout(resolve, 2000)); + assertNoPiPWindowsOpen(); + } + ); + }); ++ ++/** ++ * Tests that closing a PiP window deliberately (via Shift+ESC) while the tab is backgrounded ++ * suppresses auto-toggle, but auto-toggle works normally on the next background. ++ */ ++add_task(async function autopip_suppress_on_deliberate_close() { ++ await SpecialPowers.pushPrefEnv({ ++ set: [[ALWAYS_SHOW_PREF, true]], ++ }); ++ ++ // Open a new window and save a handle for the first tab ++ let win1 = await BrowserTestUtils.openNewBrowserWindow(); ++ let firstTab = win1.gBrowser.selectedTab; ++ ++ // Open a new tab containing a video ++ let pipTab = await BrowserTestUtils.openNewForegroundTab( ++ win1.gBrowser, ++ TEST_PAGE ++ ); ++ let browser = pipTab.linkedBrowser; ++ ++ // Ensure the video is playing ++ let videoID = "with-controls"; ++ await ensureVideosReady(browser); ++ await SpecialPowers.spawn(browser, [videoID], async videoID => { ++ await content.document.getElementById(videoID).play(); ++ }); ++ ++ // Switch from the video tab to the first tab and check if the PiP window opened ++ let domWindowOpened = BrowserTestUtils.domWindowOpenedAndLoaded(null); ++ await BrowserTestUtils.switchTab(win1.gBrowser, firstTab); ++ let pipWin = await domWindowOpened; ++ ok(pipWin, "PiP window automatically opened."); ++ ++ // Close the PiP window deliberately while the tab is backgrounded and check that it doesn't reopen ++ domWindowOpened = BrowserTestUtils.domWindowOpenedAndLoaded(null); ++ // A short delay is needed to make the test more robust ++ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout ++ await new Promise(resolve => setTimeout(resolve, 2000)); ++ EventUtils.synthesizeKey("KEY_Escape", { shiftKey: true }, pipWin); ++ let reopened = await Promise.race([ ++ domWindowOpened.then(() => true), ++ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout ++ new Promise(resolve => setTimeout(() => resolve(false), 2000)), ++ ]); ++ ok(!reopened, "PiP window should not reopen after deliberate close"); ++ ++ // Switch to the video tab and back to the first tab, which should automatically open the PiP window ++ domWindowOpened = BrowserTestUtils.domWindowOpenedAndLoaded(null); ++ await BrowserTestUtils.switchTab(win1.gBrowser, pipTab); ++ await BrowserTestUtils.switchTab(win1.gBrowser, firstTab); ++ pipWin = await domWindowOpened; ++ ok(pipWin, "PiP window automatically opened."); ++ ++ await BrowserTestUtils.closeWindow(win1); ++}); diff --git a/src/zen/common/styles/zen-omnibox.css b/src/zen/common/styles/zen-omnibox.css index b392654a5..77ec73bf3 100644 --- a/src/zen/common/styles/zen-omnibox.css +++ b/src/zen/common/styles/zen-omnibox.css @@ -295,7 +295,7 @@ &, .urlbar-background { - border-radius: calc(12px * var(--zen-squircle-value)) !important; + border-radius: 12px !important; } &[breakout-extend][animate-searchmode="true"]::before { @@ -639,7 +639,7 @@ #urlbar-label-box, #urlbar-search-mode-indicator { - --urlbar-basic-component-size: 18px; + --urlbar-basic-component-size: auto; background-color: color-mix(in srgb, var(--zen-primary-color) 50%, light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.2)) 50%) !important; color: white; padding: 4px 8px; diff --git a/src/zen/common/styles/zen-panel-ui.css b/src/zen/common/styles/zen-panel-ui.css index 0f2807649..e3c92bd85 100644 --- a/src/zen/common/styles/zen-panel-ui.css +++ b/src/zen/common/styles/zen-panel-ui.css @@ -26,6 +26,7 @@ panel[type="arrow"]:not(#feature-callout) { * way to properly animate the popup without having the mica * backdrop staying still while the popup animates */ animation: none !important; + border-radius: 0; } } diff --git a/src/zen/common/styles/zen-theme.css b/src/zen/common/styles/zen-theme.css index 4be226527..745cf922d 100644 --- a/src/zen/common/styles/zen-theme.css +++ b/src/zen/common/styles/zen-theme.css @@ -3,10 +3,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* Here, we contain all the theme related variables, for example theme - * colors, border radius, etc. - * We have `--zen-border-radius` and `--zen-primary-color` as variables. - */ :host(:is(.anonymous-content-host, notification-message)), :root { @@ -168,7 +164,11 @@ --zen-toolbar-height-with-bookmarks: calc(var(--zen-toolbar-height) + 30px); } - --toolbarbutton-background-color-hover: var(--zen-toolbar-element-bg-hover) !important; + --toolbarbutton-background-color-hover: color-mix( + in srgb, + var(--zen-branding-bg-reverse) 7%, + transparent + ) !important; --zen-toolbar-button-size: 16px; @media (-moz-platform: macos) { --zen-toolbar-button-size: 17px; @@ -183,8 +183,8 @@ --toolbarbutton-background-color-active: color-mix( in srgb, - var(--zen-branding-bg-reverse) 7%, - transparent 93% + var(--zen-branding-bg-reverse) 10%, + transparent ) !important; --toolbar-color: var(--toolbox-textcolor) !important; @@ -223,10 +223,6 @@ --zen-squircle-value: 2.1; } - @media (-moz-platform: linux) { - --zen-squircle-value: 1.2; - } - --tab-icon-overlay-stroke: light-dark(white, black) !important; --tab-close-button-padding: 4px !important; diff --git a/src/zen/folders/ZenFolders.mjs b/src/zen/folders/ZenFolders.mjs index 653beb6e9..40078fc9f 100644 --- a/src/zen/folders/ZenFolders.mjs +++ b/src/zen/folders/ZenFolders.mjs @@ -44,6 +44,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature { #popup = null; #popupTimer = null; #mouseTimer = null; + #collapsedRelayoutQueue = new Set(); #lastHighlightedGroup = null; #lastFolderContextMenu = null; @@ -339,13 +340,29 @@ class nsZenFolders extends nsZenDOMOperatedFeature { group.setAttribute("had-zen-pinned-changed", true); } - if (group.collapsed && !this._sessionRestoring && !group.isLiveFolder) { + if (this._sessionRestoring) { + // The margins hiding collapsed content are computed at collapse time; + // content materializing quietly under a collapsed folder must refresh + // them. + const owner = group.isZenFolder ? group : group.group; + const collapsedRoot = owner?.rootMostCollapsedFolder; + if (collapsedRoot) { + this.#queueCollapsedRelayout(collapsedRoot); + } + } else if (group.collapsed && !group.isLiveFolder) { group.collapsed = group.hasAttribute("has-active"); } } on_FolderGrouped(event) { if (this._sessionRestoring) { + const parentFolder = event.target; + if (!groupIsCollapsiblePins(parentFolder)) { + const collapsedRoot = parentFolder?.rootMostCollapsedFolder; + if (collapsedRoot) { + this.#queueCollapsedRelayout(collapsedRoot); + } + } return; } const folder = event.detail; @@ -473,6 +490,47 @@ class nsZenFolders extends nsZenDOMOperatedFeature { await this.animateCollapse(group); } + #queueCollapsedRelayout(group) { + if (this.#collapsedRelayoutQueue.size === 0) { + requestAnimationFrame(() => this.#flushCollapsedRelayout()); + } + this.#collapsedRelayoutQueue.add(group); + } + + #flushCollapsedRelayout() { + if (this.#animationCount) { + // A collapse/expand animation is mid-flight and writes margins when it + // settles, retry once it is done. + requestAnimationFrame(() => this.#flushCollapsedRelayout()); + return; + } + const groups = [...this.#collapsedRelayoutQueue]; + this.#collapsedRelayoutQueue.clear(); + for (const group of groups) { + if ( + !group.isConnected || + !group.isZenFolder || + !group.collapsed || + group.hasAttribute("has-active") + ) { + continue; + } + const container = group.groupContainer; + const groupStart = group.groupStartElement; + const wasHidden = container.hasAttribute("hidden"); + container.removeAttribute("hidden"); + groupStart.style.marginTop = "0px"; + let height = container.getBoundingClientRect().height; + if (container.separatorElement) { + height -= container.separatorElement.getBoundingClientRect().height; + } + groupStart.style.marginTop = `${-(height + 4)}px`; + if (wasHidden) { + container.setAttribute("hidden", true); + } + } + } + async on_TabGroupExpand(event) { const group = event.target; if (!group.isZenFolder) { diff --git a/src/zen/spaces/ZenGradientGenerator.mjs b/src/zen/spaces/ZenGradientGenerator.mjs index a68dc3bc1..cc423bc39 100644 --- a/src/zen/spaces/ZenGradientGenerator.mjs +++ b/src/zen/spaces/ZenGradientGenerator.mjs @@ -1476,14 +1476,19 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature { * @returns {string} The primary color in hex format. */ getAccentColorForUI(accentColor, isDarkMode) { - const [h, s, l] = this.rgbToHsl(...accentColor); + let [r, g, b] = accentColor; if (isDarkMode) { - return `rgb(${accentColor[0]}, ${accentColor[1]}, ${accentColor[2]})`; + return `rgb(${r}, ${g}, ${b})`; } + // gh-15142: Special case for grayscale colors + if (r == g && g == b) { + return `rgb(${r}, ${g}, ${b})`; + } + const [h, s, l] = this.rgbToHsl(...accentColor); const saturation = Math.min(1, s + 0.3); const targetLightness = this.isDarkMode ? 0.62 : 0.42; const lightness = l * 0.4 + targetLightness * 0.6; - const [r, g, b] = this.hslToRgb(h / 360, saturation, lightness); + [r, g, b] = this.hslToRgb(h / 360, saturation, lightness); return `rgb(${r}, ${g}, ${b})`; } @@ -1504,7 +1509,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature { baseColor = this.blendColors( accentColor, baseColor.slice(0, 3), - this.canBeTransparent ? 15 : 5 + this.canBeTransparent ? 25 : 5 ).concat(opacity); } return baseColor; diff --git a/src/zen/spaces/ZenSpaceManager.mjs b/src/zen/spaces/ZenSpaceManager.mjs index 801222b1f..191328e53 100644 --- a/src/zen/spaces/ZenSpaceManager.mjs +++ b/src/zen/spaces/ZenSpaceManager.mjs @@ -2550,7 +2550,7 @@ class nsZenWorkspaces { "Default"; name = this.isPrivateWindow ? "Incognito" : label; if (this.isPrivateWindow) { - icon = gZenEmojiPicker.getSVGURL("eye.svg"); + icon = "chrome://browser/skin/zen-icons/private-window-small.svg"; } } let workspace = { diff --git a/src/zen/tests/mochitests/backforward/browser_history_menu.js b/src/zen/tests/mochitests/backforward/browser_history_menu.js index 8623d5405..a0cff08b1 100644 --- a/src/zen/tests/mochitests/backforward/browser_history_menu.js +++ b/src/zen/tests/mochitests/backforward/browser_history_menu.js @@ -44,7 +44,7 @@ async function openHistoryMenu(useContextMenu) { async function testBackForwardMenu(useContextMenu) { let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.com" ); @@ -90,7 +90,7 @@ async function testBackForwardMenu(useContextMenu) { ); let node = popupEvent.target.lastElementChild; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url is(node.getAttribute("uri"), "http://example.com/", "'1' item uri"); is(node.getAttribute("index"), "0", "'1' item index"); is( @@ -100,7 +100,7 @@ async function testBackForwardMenu(useContextMenu) { ); node = node.previousElementSibling; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url is(node.getAttribute("uri"), "http://example.com/2.html", "'2' item uri"); is(node.getAttribute("index"), "1", "'2' item index"); is( @@ -111,7 +111,7 @@ async function testBackForwardMenu(useContextMenu) { if (iter >= 3) { node = node.previousElementSibling; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url is(node.getAttribute("uri"), "http://example.com/3.html", "'3' item uri"); is(node.getAttribute("index"), "2", "'3' item index"); is( @@ -133,7 +133,7 @@ async function testBackForwardMenu(useContextMenu) { } else { let newTabPromise = BrowserTestUtils.waitForNewTab( gBrowser, - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url url => url == "http://example.com/" ); diff --git a/src/zen/tests/mochitests/caps/browser_principalSerialization_json.js b/src/zen/tests/mochitests/caps/browser_principalSerialization_json.js index f79f269fd..bdc34988b 100644 --- a/src/zen/tests/mochitests/caps/browser_principalSerialization_json.js +++ b/src/zen/tests/mochitests/caps/browser_principalSerialization_json.js @@ -88,32 +88,32 @@ add_task(async function test_contentPrincipal() { */ let tests = [ { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://example.com/", OA: {} }, expected: `{"${contentId}":{"${content}":"http://example.com/"}}`, }, { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://mozilla1.com/", OA: {} }, expected: `{"${contentId}":{"${content}":"http://mozilla1.com/"}}`, }, { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://mozilla2.com/", OA: { userContextId: 0 } }, expected: `{"${contentId}":{"${content}":"http://mozilla2.com/"}}`, }, { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://mozilla3.com/", OA: { userContextId: 2 } }, expected: `{"${contentId}":{"${content}":"http://mozilla3.com/","${suffix}":"^userContextId=2"}}`, }, { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://mozilla4.com/", OA: { privateBrowsingId: 1 } }, expected: `{"${contentId}":{"${content}":"http://mozilla4.com/","${suffix}":"^privateBrowsingId=1"}}`, }, { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url input: { uri: "http://mozilla5.com/", OA: { privateBrowsingId: 0 } }, expected: `{"${contentId}":{"${content}":"http://mozilla5.com/"}}`, }, diff --git a/src/zen/tests/mochitests/readermode/browser_bug1780350_readerModeSaveScroll.js b/src/zen/tests/mochitests/readermode/browser_bug1780350_readerModeSaveScroll.js index 76add5511..dedeee53d 100644 --- a/src/zen/tests/mochitests/readermode/browser_bug1780350_readerModeSaveScroll.js +++ b/src/zen/tests/mochitests/readermode/browser_bug1780350_readerModeSaveScroll.js @@ -1,4 +1,4 @@ -/* eslint-disable @microsoft/sdl/no-insecure-url */ +/* eslint-disable sdl/no-insecure-url */ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; diff --git a/src/zen/tests/mochitests/sessionstore/browser.toml b/src/zen/tests/mochitests/sessionstore/browser.toml index f6ab3d6e8..d49574a0e 100644 --- a/src/zen/tests/mochitests/sessionstore/browser.toml +++ b/src/zen/tests/mochitests/sessionstore/browser.toml @@ -355,6 +355,7 @@ skip-if = [ ["browser_sizemodeBeforeMinimized.js"] skip-if = [ + "os == 'linux' && os_version == '22.04' && arch == 'x86_64' && opt && nova", # Bug 2057856 "os == 'win' && os_version == '11.26200' && asan", # Bug 2019745 ] @@ -436,6 +437,7 @@ disabled="Disabled by import_external_tests.py" skip-if = [ "os == 'mac' && os_version == '15.30' && arch == 'aarch64'", # Bug 2023967 ] + ["browser_tab_label_during_restore.js"] disabled="Disabled by import_external_tests.py" https_first_disabled = true diff --git a/src/zen/tests/mochitests/sessionstore/browser_bfcache_telemetry.js b/src/zen/tests/mochitests/sessionstore/browser_bfcache_telemetry.js index c1e987750..9e5d2bd36 100644 --- a/src/zen/tests/mochitests/sessionstore/browser_bfcache_telemetry.js +++ b/src/zen/tests/mochitests/sessionstore/browser_bfcache_telemetry.js @@ -1,44 +1,26 @@ const URL1 = "data:text/html;charset=utf-8,
Hello1
"; const URL2 = "data:text/html;charset=utf-8,Hello2
"; -async function getBFCacheComboTelemetry(probeInParent) { - let bfcacheCombo; - await TestUtils.waitForCondition(() => { - let histograms; - if (probeInParent) { - histograms = Services.telemetry.getSnapshotForHistograms( - "main", - false /* clear */ - ).parent; - } else { - histograms = Services.telemetry.getSnapshotForHistograms( - "main", - false /* clear */ - ).content; - } - bfcacheCombo = histograms.BFCACHE_COMBO; - return bfcacheCombo; - }); - return bfcacheCombo; +async function getBFCacheComboValue(label) { + await Services.fog.testFlushAllChildren(); + return Glean.bfcache.combo[label].testGetValue(); } -async function test_bfcache_telemetry(probeInParent) { - Services.telemetry.getHistogramById("BFCACHE_COMBO").clear(); +add_task(async () => { + await Services.fog.testFlushAllChildren(); + Services.fog.testResetFOG(); let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL1); BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, URL2); await BrowserTestUtils.browserLoaded(tab.linkedBrowser); - let bfcacheCombo = await getBFCacheComboTelemetry(probeInParent); + await TestUtils.waitForCondition( + async () => (await getBFCacheComboValue("BFCache_Success")) !== null, + "Waiting for bfcache.combo 'BFCache_Success' to be recorded" + ); - is(bfcacheCombo.values[0], 1, "1 bfcache success"); + is(await getBFCacheComboValue("BFCache_Success"), 1, "1 bfcache success"); gBrowser.removeTab(tab); -} - -add_task(async () => { - await test_bfcache_telemetry( - Services.prefs.getBoolPref("fission.bfcacheInParent") - ); }); diff --git a/src/zen/tests/mochitests/sessionstore/browser_oldformat.toml b/src/zen/tests/mochitests/sessionstore/browser_oldformat.toml index 54842390e..348a0c004 100644 --- a/src/zen/tests/mochitests/sessionstore/browser_oldformat.toml +++ b/src/zen/tests/mochitests/sessionstore/browser_oldformat.toml @@ -153,6 +153,7 @@ skip-if = [ ["browser_477657.js"] skip-if = [ + "os == 'linux' && os_version == '22.04' && arch == 'x86_64' && opt && nova", # Bug 2057857 "os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'", # Bug 1610668 ] @@ -182,6 +183,9 @@ skip-if = [ ] ["browser_524745.js"] +skip-if = [ + "os == 'linux' && os_version == '22.04' && arch == 'x86_64' && debug && nova", # Bug 2057858 +] ["browser_528776.js"] diff --git a/src/zen/tests/mochitests/sessionstore/browser_restored_window_features.js b/src/zen/tests/mochitests/sessionstore/browser_restored_window_features.js index 20a1d7196..64aca7910 100644 --- a/src/zen/tests/mochitests/sessionstore/browser_restored_window_features.js +++ b/src/zen/tests/mochitests/sessionstore/browser_restored_window_features.js @@ -8,7 +8,6 @@ const BARPROP_NAMES = [ "menubar", "personalbar", "scrollbars", - "statusbar", "toolbar", ]; @@ -45,7 +44,6 @@ add_task(async function testRestoredWindowFeatures() { menubar: true, personalbar: true, scrollbars: true, - statusbar: true, toolbar: true, }; const TESTS = [ diff --git a/src/zen/tests/mochitests/sessionstore/browser_should_restore_tab.js b/src/zen/tests/mochitests/sessionstore/browser_should_restore_tab.js index 07c699c31..318c846a6 100644 --- a/src/zen/tests/mochitests/sessionstore/browser_should_restore_tab.js +++ b/src/zen/tests/mochitests/sessionstore/browser_should_restore_tab.js @@ -18,8 +18,14 @@ async function check_tab_close_notification(openedTab, expectNotification) { } Services.obs.addObserver(topicObserver, NOTIFY_CLOSED_OBJECTS_CHANGED); + // (Bug 2058570) Intermittently, the tab state wasn't fully up to date before closing the tab. + // This caused test_navigated_about_home to think there was no meaningful history beyond about:home. + // Try flushing the tab state and then waiting for a notification if one is expected. + let flushedPromise = TabStateFlusher.flush(openedTab.linkedBrowser); + BrowserTestUtils.removeTab(openedTab); await tabClosed; + await flushedPromise; // SessionStore does a setTimeout(notify, 0) to notifyObservers when it handles TabClose // We need to wait long enough to be confident the observer would have been notified // if it was going to be. diff --git a/src/zen/tests/mochitests/sessionstore/marionette/test_restore_aiwindow.py b/src/zen/tests/mochitests/sessionstore/marionette/test_restore_aiwindow.py index 530bfdecb..b899a392d 100644 --- a/src/zen/tests/mochitests/sessionstore/marionette/test_restore_aiwindow.py +++ b/src/zen/tests/mochitests/sessionstore/marionette/test_restore_aiwindow.py @@ -385,3 +385,64 @@ class TestSmartWindowDefaultManualRestore( tab_count, msg="Tab count should be preserved after restore", ) + + +class TestSmartWindowDefaultManualRestoreOverwritesNewTab( + SmartWindowDefaultMixin, SessionStoreTestCase +): + """With Smart Window as default (startup.page=1), the startup window opens + showing the Smart new tab. Restoring a previously Smart session via + "Restore previous session" reuses that startup window (the types match), + and the restored tabs must *overwrite* the Smart new tab rather than being + appended alongside it.""" + + def test_smart_session_restored_overwrites_smart_new_tab(self): + self.marionette.execute_script( + """ + Services.prefs.setBoolPref("browser.sessionstore.persist_closed_tabs_between_sessions", true); + """ + ) + + self.wait_for_windows( + self.all_windows, "Not all requested windows have been opened" + ) + + # Make the saved session a Smart Window with the 3 content tabs from + # setUp (Tab 1/2/3), which are real pages, not the Smart new tab. + self.toggle_ai_window(True) + self.assertTrue( + self.is_ai_window(), msg="Window should be Smart before the restart" + ) + tab_count = self.get_tab_count() + self.assertEqual(tab_count, 3, msg="Saved session should have 3 tabs") + + self.marionette.quit() + self.marionette.start_session() + self.marionette.set_context("chrome") + + # The new startup window opens Smart (Smart Window is the default) and + # shows a single Smart new tab. + self.assertTrue( + self.is_ai_window(), + msg="Startup window should open Smart when Smart Window is the default", + ) + + self.restore_last_session() + + self.assertEqual( + len(self.marionette.chrome_window_handles), + 1, + msg="Smart session should restore into the existing startup window", + ) + self.assertTrue( + self.is_ai_window(), + msg="Restored window should stay Smart", + ) + + # Asserts if Smart new tab was overwritten, not appended to. + self.assertEqual( + self.get_tab_count(), + tab_count, + msg="Restored tabs should overwrite the Smart new tab, not be " + "appended alongside it", + ) diff --git a/src/zen/tests/mochitests/shell/unit/test_isOneClickSetDefaultEnabled.js b/src/zen/tests/mochitests/shell/unit/test_isOneClickSetDefaultEnabled.js new file mode 100644 index 000000000..639d62ce8 --- /dev/null +++ b/src/zen/tests/mochitests/shell/unit/test_isOneClickSetDefaultEnabled.js @@ -0,0 +1,174 @@ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +ChromeUtils.defineESModuleGetters(this, { + ShellService: "moz-src:///browser/components/shell/ShellService.sys.mjs", + sinon: "resource://testing-common/Sinon.sys.mjs", +}); + +const USER_CHOICE_PREF = "browser.shell.setDefaultBrowserUserChoice"; +const REG_RENAME_PREF = "browser.shell.setDefaultBrowserUserChoice.regRename"; + +function mockNativeShellService(overrides) { + const mock = { + QueryInterface: ChromeUtils.generateQI([Ci.nsIWindowsShellService]), + checkAllProgIDsExist: () => true, + checkBrowserUserChoiceHashes: () => true, + isDefaultBrowser: () => false, + isUserChoiceProtectionDriverRunning: () => false, + canRenameUserChoiceAssociationKey: sinon.stub().returns(false), + ...overrides, + }; + sinon.stub(ShellService, "shellService").value(mock); + return mock; +} + +registerCleanupFunction(() => { + sinon.restore(); + Services.prefs.clearUserPref(USER_CHOICE_PREF); + Services.prefs.clearUserPref(REG_RENAME_PREF); +}); + +add_task(function test_pref_disabled() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, false); + const native = mockNativeShellService({ + checkAllProgIDsExist: () => { + Assert.ok( + false, + "Should not check capability when the user choice pref is off" + ); + return true; + }, + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + false, + "Should be false when the user choice pref is disabled, regardless of capability" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.notCalled, + "Should not probe the registry when the user choice pref is off" + ); + + sinon.restore(); +}); + +add_task(function test_user_choice_impossible() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + const native = mockNativeShellService({ + checkBrowserUserChoiceHashes: () => false, + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + false, + "Should be false when the existing UserChoice hashes can't be reproduced" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.notCalled, + "Should not probe the registry when a UserChoice write can't succeed anyway" + ); + + sinon.restore(); +}); + +add_task(function test_ucpd_not_running() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + const native = mockNativeShellService({ + isUserChoiceProtectionDriverRunning: () => false, + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + true, + "Should be true when UCPD isn't running to lock the UserChoice keys" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.notCalled, + "Should not probe the registry when UCPD isn't running" + ); + + sinon.restore(); +}); + +add_task(function test_already_default_skips_probe() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + const native = mockNativeShellService({ + isUserChoiceProtectionDriverRunning: () => true, + isDefaultBrowser: () => true, + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + true, + "Should be true without probing when Firefox is already the default" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.notCalled, + "Should not probe the registry when Firefox is already the default" + ); + + sinon.restore(); +}); + +add_task(function test_ucpd_running_rename_blocked() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + const native = mockNativeShellService({ + isUserChoiceProtectionDriverRunning: () => true, + canRenameUserChoiceAssociationKey: sinon.stub().returns(false), + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + false, + "Should be false when UCPD is running and blocks the registry rename" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.calledOnceWith("http"), + "Should probe the http association" + ); + + sinon.restore(); +}); + +add_task(function test_ucpd_running_rename_permitted() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + mockNativeShellService({ + isUserChoiceProtectionDriverRunning: () => true, + canRenameUserChoiceAssociationKey: sinon.stub().returns(true), + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + true, + "Should be true when UCPD is running but permits the registry rename" + ); + + sinon.restore(); +}); + +add_task(function test_reg_rename_disabled() { + Services.prefs.setBoolPref(USER_CHOICE_PREF, true); + Services.prefs.setBoolPref(REG_RENAME_PREF, false); + const native = mockNativeShellService({ + isUserChoiceProtectionDriverRunning: () => true, + canRenameUserChoiceAssociationKey: sinon.stub().returns(true), + }); + + Assert.strictEqual( + ShellService.isOneClickSetDefaultEnabled(), + false, + "Should be false when the rename pref is false, as renaming is the only " + + "way to reach a locked UserChoice key" + ); + Assert.ok( + native.canRenameUserChoiceAssociationKey.notCalled, + "Should not probe the registry when a successful rename wouldn't be used" + ); + + sinon.restore(); + Services.prefs.clearUserPref(REG_RENAME_PREF); +}); diff --git a/src/zen/tests/mochitests/shell/unit/test_taskbarPinningPolicy.js b/src/zen/tests/mochitests/shell/unit/test_taskbarPinningPolicy.js new file mode 100644 index 000000000..a24d06f28 --- /dev/null +++ b/src/zen/tests/mochitests/shell/unit/test_taskbarPinningPolicy.js @@ -0,0 +1,166 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { MockRegistry } = ChromeUtils.importESModule( + "resource://testing-common/MockRegistry.sys.mjs" +); + +const EXPLORER_POLICY_KEY = String.raw`Software\Policies\Microsoft\Windows\Explorer`; +const POLICY_LOG_PREFIX = "Pinning disabled by policy"; + +const HIVES = { + HKCU: Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, + HKLM: Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE, +}; +const POLICIES = ["NoPinningToTaskbar", "TaskbarNoPinnedList"]; + +const shellService = Cc["@mozilla.org/browser/shell-service;1"].getService( + Ci.nsIWindowsShellService +); + +let gRegistry; +let gLogFile; + +add_setup(async function () { + // The pinning policy diagnostic only reaches MOZ_LOG, never the console + // service, so route the module to a file and read it back. + // logging.config.sync flushes each line, so the message is on disk by the + // time canPinToTaskbar() returns. + const logBase = PathUtils.join( + do_get_profile().path, + "taskbar_policy_test.log" + ); + gLogFile = `${logBase}-main.${Services.appinfo.processID}.moz_log`; + + Services.prefs.setBoolPref("logging.config.sync", true); + Services.prefs.setCharPref("logging.config.LOG_FILE", logBase); + Services.prefs.setIntPref("logging.shell_windows::taskbar", 3); + + gRegistry = new MockRegistry(); + + registerCleanupFunction(async () => { + gRegistry.shutdown(); + Services.prefs.clearUserPref("logging.shell_windows::taskbar"); + Services.prefs.clearUserPref("logging.config.LOG_FILE"); + Services.prefs.clearUserPref("logging.config.sync"); + await IOUtils.remove(gLogFile, { ignoreAbsent: true }); + }); +}); + +async function readLog() { + if (!(await IOUtils.exists(gLogFile))) { + return ""; + } + return IOUtils.readUTF8(gLogFile); +} + +function clearPolicies() { + for (const root of Object.values(HIVES)) { + for (const policy of POLICIES) { + gRegistry.setValue(root, EXPLORER_POLICY_KEY, policy, null); + } + } +} + +function setPolicy(hive, policy, value) { + clearPolicies(); + gRegistry.setValue( + HIVES[hive], + EXPLORER_POLICY_KEY, + policy, + value, + Ci.nsIWindowsRegKey.TYPE_INT + ); +} + +// Calls canPinToTaskbar and returns what it threw (if anything) along with the +// log output it produced. The log file accumulates across tasks, so only the +// appended portion is returned. +async function callCanPinToTaskbar() { + const offset = (await readLog()).length; + + let error = null; + try { + shellService.canPinToTaskbar(); + } catch (e) { + error = e; + } + + let log = (await readLog()).slice(offset); + + return { error, log }; +} + +// Set of hive/group policy combinations known to block pinning. +const BLOCKING_POLICIES = [ + ["HKCU", "NoPinningToTaskbar"], + ["HKCU", "TaskbarNoPinnedList"], + ["HKLM", "TaskbarNoPinnedList"], +]; + +add_task(async function test_policiesBlockPinning() { + for (const [hive, policy] of BLOCKING_POLICIES) { + info(`Testing ${policy} in ${hive}`); + setPolicy(hive, policy, 1); + + const { error, log } = await callCanPinToTaskbar(); + + Assert.equal( + error?.result, + Cr.NS_ERROR_NOT_AVAILABLE, + `canPinToTaskbar threw NS_ERROR_NOT_AVAILABLE for ${policy} in ${hive}` + ); + Assert.stringContains( + log, + `${POLICY_LOG_PREFIX} ${policy} in hive ${hive}.`, + `The blocking policy ${policy} in ${hive} was logged` + ); + } +}); + +// Policies that apply in other hives, but not the ones paired here. +const INVALID_HIVE_FOR_POLICY = [["HKLM", "NoPinningToTaskbar"]]; + +add_task(async function test_invalidPoliciesDoNotBlockPinning() { + for (const [hive, policy] of INVALID_HIVE_FOR_POLICY) { + info(`Testing ${policy} in ${hive}`); + setPolicy(hive, policy, 1); + + // Whether pinning is actually available depends on the host machine, so only + // the absence of the policy diagnostic is asserted here. + const { log } = await callCanPinToTaskbar(); + + Assert.ok( + !log.includes(POLICY_LOG_PREFIX), + `The policy ${policy} in ${hive} is invalid and should not block pinning` + ); + } +}); + +add_task(async function test_policySetToZeroDoesNotBlockPinning() { + setPolicy("HKCU", "NoPinningToTaskbar", 0); + + // Whether pinning is actually available depends on the host machine, so only + // the absence of the policy diagnostic is asserted here. + const { log } = await callCanPinToTaskbar(); + + Assert.ok( + !log.includes(POLICY_LOG_PREFIX), + "A policy present but set to zero does not block pinning" + ); +}); + +add_task(async function test_noPoliciesSet() { + clearPolicies(); + + // Whether pinning is actually available depends on the host machine, so only + // the absence of the policy diagnostic is asserted here. + const { log } = await callCanPinToTaskbar(); + + Assert.ok( + !log.includes(POLICY_LOG_PREFIX), + "No policy is reported when none are set" + ); +}); diff --git a/src/zen/tests/mochitests/shell/unit/xpcshell.toml b/src/zen/tests/mochitests/shell/unit/xpcshell.toml index 106c8565a..d5f25a0c4 100644 --- a/src/zen/tests/mochitests/shell/unit/xpcshell.toml +++ b/src/zen/tests/mochitests/shell/unit/xpcshell.toml @@ -30,6 +30,11 @@ support-files = [ ] tags = ["portal"] +["test_isOneClickSetDefaultEnabled.js"] +run-if = [ + "os == 'win'", +] + ["test_linuxDesktopEntry.js"] run-if = [ "os == 'linux'", @@ -45,6 +50,11 @@ run-if = [ "os == 'win'" ] +["test_taskbarPinningPolicy.js"] +run-if = [ + "os == 'win'", +] + ["test_writeShortcutIcon.js"] run-if = [ "os == 'win'", diff --git a/src/zen/tests/mochitests/sync/head_helpers.js b/src/zen/tests/mochitests/sync/head_helpers.js index d9383db21..17a726501 100644 --- a/src/zen/tests/mochitests/sync/head_helpers.js +++ b/src/zen/tests/mochitests/sync/head_helpers.js @@ -97,7 +97,10 @@ function loadWebExtensionTestFunctions() { const path = webExtensionsTestPath("/head_sync.js"); let file = do_get_file(path); let uri = Services.io.newFileURI(file); - Services.scriptloader.loadSubScript(uri.spec, gGlobalScope); + Services.scriptloader.loadSubScriptWithOptions(uri.spec, { + target: gGlobalScope, + allowUnsafeURL: true, + }); } /** diff --git a/src/zen/tests/mochitests/sync/test_resource.js b/src/zen/tests/mochitests/sync/test_resource.js index 5dee57b39..2e983a655 100644 --- a/src/zen/tests/mochitests/sync/test_resource.js +++ b/src/zen/tests/mochitests/sync/test_resource.js @@ -47,10 +47,10 @@ function server_404(metadata, response) { response.bodyOutputStream.write(body, body.length); } -var pacFetched = false; +var pacFetched; function server_pac(metadata, response) { _("Invoked PAC handler."); - pacFetched = true; + pacFetched.resolve(); let body = 'function FindProxyForURL(url, host) { return "DIRECT"; }'; response.setStatusLine(metadata.httpVersion, 200, "OK"); response.setHeader( @@ -189,12 +189,13 @@ add_task(async function test_proxy_auth_redirect() { PACSystemSettings.PACURI = server.baseURI + "/pac2"; installFakePAC(); + pacFetched = Promise.withResolvers(); let res = new Resource(server.baseURI + "/open"); let result = await res.get(); - Assert.ok(pacFetched); + await pacFetched.promise; Assert.ok(fetched); Assert.equal("This path exists", result.data); - pacFetched = fetched = false; + fetched = false; uninstallFakePAC(); await promiseStopServer(server); }); diff --git a/src/zen/tests/mochitests/tabMediaIndicator/browser.toml b/src/zen/tests/mochitests/tabMediaIndicator/browser.toml index a725df4df..6754a3dd9 100644 --- a/src/zen/tests/mochitests/tabMediaIndicator/browser.toml +++ b/src/zen/tests/mochitests/tabMediaIndicator/browser.toml @@ -45,6 +45,8 @@ https_first_disabled = true ["browser_sound_indicator_silent_video.js"] +["browser_sound_indicator_tab_move.js"] + ["browser_webAudio_hideSoundPlayingIcon.js"] ["browser_webAudio_silentData.js"] diff --git a/src/zen/tests/mochitests/tabMediaIndicator/browser_mediaplayback_audibility_change.js b/src/zen/tests/mochitests/tabMediaIndicator/browser_mediaplayback_audibility_change.js index 6c0c9de2b..4c50c2afe 100644 --- a/src/zen/tests/mochitests/tabMediaIndicator/browser_mediaplayback_audibility_change.js +++ b/src/zen/tests/mochitests/tabMediaIndicator/browser_mediaplayback_audibility_change.js @@ -179,31 +179,6 @@ add_task(async function testSoundIndicatorWhenChangingMediaVolume() { /** * Following are helper functions */ -function initMediaPlaybackDocument( - tab, - fileName, - { preload, createVideo, muted = false, volume = 1.0 } = {} -) { - return SpecialPowers.spawn( - tab.linkedBrowser, - [fileName, preload, createVideo, muted, volume], - // eslint-disable-next-line no-shadow - async (fileName, preload, createVideo, muted, volume) => { - if (createVideo) { - content.media = content.document.createElement("video"); - } else { - content.media = content.document.createElement("audio"); - } - if (preload) { - content.media.preload = preload; - } - content.media.muted = muted; - content.media.volume = volume; - content.media.src = fileName; - } - ); -} - function initMediaStreamPlaybackDocument(tab) { return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { content.media = content.document.createElement("audio"); @@ -212,26 +187,6 @@ function initMediaStreamPlaybackDocument(tab) { }); } -function playMedia(tab, { resolveOnTimeupdate } = {}) { - return SpecialPowers.spawn( - tab.linkedBrowser, - [resolveOnTimeupdate], - // eslint-disable-next-line no-shadow - async resolveOnTimeupdate => { - await content.media.play(); - if (resolveOnTimeupdate) { - await new Promise(r => (content.media.ontimeupdate = r)); - } - } - ); -} - -function pauseMedia(tab) { - return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { - content.media.pause(); - }); -} - function assignNewSourceForAudio(tab, fileName) { // eslint-disable-next-line no-shadow return SpecialPowers.spawn(tab.linkedBrowser, [fileName], async fileName => { diff --git a/src/zen/tests/mochitests/tabMediaIndicator/browser_sound_indicator_tab_move.js b/src/zen/tests/mochitests/tabMediaIndicator/browser_sound_indicator_tab_move.js new file mode 100644 index 000000000..6731d69e4 --- /dev/null +++ b/src/zen/tests/mochitests/tabMediaIndicator/browser_sound_indicator_tab_move.js @@ -0,0 +1,76 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Moving a tab to another window hands its browsing context to a different + * browser, which also changes the media controller the tab has to listen to. + * For each way a tab can reach another window, these tests check that the sound + * indicator still appears when audio starts and still clears when audio stops. + */ + +const MOVE_MODES = [ + { name: "moving it to a new window", moveTab: moveTabToNewWindow }, + { name: "adopting it into another window", moveTab: adoptTabIntoOtherWindow }, +]; + +for (const { name, moveTab } of MOVE_MODES) { + add_task(async function testSoundIndicatorAppearsAfterMovingTab() { + info("create a tab loading media document"); + const tab = await createBlankForegroundTab(); + await initMediaPlaybackDocument(tab, "audio.ogg"); + + info(`move the silent tab by ${name}`); + const { win, movedTab } = await moveTab(tab); + + info("sound indicator should appear when audible audio starts playing"); + await playMedia(movedTab); + await waitForTabSoundIndicatorAppears(movedTab); + + info("stop media and close window"); + await pauseMedia(movedTab); + await BrowserTestUtils.closeWindow(win); + }); + + add_task(async function testSoundIndicatorDisappearsAfterMovingTab() { + info("create a tab loading media document"); + const tab = await createBlankForegroundTab(); + await initMediaPlaybackDocument(tab, "audio.ogg"); + + info("sound indicator should appear when audible audio starts playing"); + await playMedia(tab); + await waitForTabSoundIndicatorAppears(tab); + + info(`move the audible tab by ${name}`); + const { win, movedTab } = await moveTab(tab); + ok(movedTab.soundPlaying, "Tab sound indicator is kept after moving"); + + info("sound indicator should disappear when audio stops playing"); + await pauseMedia(movedTab); + await waitForTabSoundIndicatorDisappears(movedTab); + + info("close window"); + await BrowserTestUtils.closeWindow(win); + }); +} + +// Following are helper functions. + +async function moveTabToNewWindow(tab) { + const win = gBrowser.replaceTabWithWindow(tab); + await TestUtils.topicObserved( + "browser-delayed-startup-finished", + subject => subject == win + ); + return { win, movedTab: win.gBrowser.selectedTab }; +} + +async function adoptTabIntoOtherWindow(tab) { + const win = await BrowserTestUtils.openNewBrowserWindow(); + const movedTab = win.gBrowser.adoptTab(tab, { selectTab: true }); + if (!movedTab) { + throw new Error("adoptTab refused to swap the tab into the other window"); + } + return { win, movedTab }; +} diff --git a/src/zen/tests/mochitests/tabMediaIndicator/head.js b/src/zen/tests/mochitests/tabMediaIndicator/head.js index 8d58339a2..ce58e50ee 100644 --- a/src/zen/tests/mochitests/tabMediaIndicator/head.js +++ b/src/zen/tests/mochitests/tabMediaIndicator/head.js @@ -12,8 +12,8 @@ const gEMPTY_PAGE_URL = GetTestWebBasedURL("file_empty.html"); * if set, then return a url with different origin */ function GetTestWebBasedURL(fileName, cors = false) { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const origin = cors ? "http://example.org" : "http://example.com"; return ( getRootDirectory(gTestPath).replace("chrome://mochitests/content", origin) + @@ -163,3 +163,52 @@ function disableNonTestMouse(disable) { let utils = window.windowUtils; utils.disableNonTestMouseEvents(disable); } + +/** + * Create a media element in the given tab and point it at fileName. The element + * is stored on the content window as `content.media` for playMedia/pauseMedia. + */ +function initMediaPlaybackDocument( + tab, + fileName, + { preload, createVideo, muted = false, volume = 1.0 } = {} +) { + return SpecialPowers.spawn( + tab.linkedBrowser, + [fileName, preload, createVideo, muted, volume], + // eslint-disable-next-line no-shadow + async (fileName, preload, createVideo, muted, volume) => { + if (createVideo) { + content.media = content.document.createElement("video"); + } else { + content.media = content.document.createElement("audio"); + } + if (preload) { + content.media.preload = preload; + } + content.media.muted = muted; + content.media.volume = volume; + content.media.src = fileName; + } + ); +} + +function playMedia(tab, { resolveOnTimeupdate } = {}) { + return SpecialPowers.spawn( + tab.linkedBrowser, + [resolveOnTimeupdate], + // eslint-disable-next-line no-shadow + async resolveOnTimeupdate => { + await content.media.play(); + if (resolveOnTimeupdate) { + await new Promise(r => (content.media.ontimeupdate = r)); + } + } + ); +} + +function pauseMedia(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], async _ => { + content.media.pause(); + }); +} diff --git a/src/zen/tests/mochitests/zoom/browser_background_link_zoom_reset.js b/src/zen/tests/mochitests/zoom/browser_background_link_zoom_reset.js index ac224cc4a..a0692bcf3 100644 --- a/src/zen/tests/mochitests/zoom/browser_background_link_zoom_reset.js +++ b/src/zen/tests/mochitests/zoom/browser_background_link_zoom_reset.js @@ -39,7 +39,7 @@ function test() { (async function () { gTestTab = BrowserTestUtils.addTab(gBrowser); await FullZoomHelper.selectTabAndWaitForLocationChange(gTestTab); - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url await FullZoomHelper.load(gTestTab, "http://example.org" + TEST_PAGE); })().then(testInitialZoom, FullZoomHelper.failAndContinue(finish)); } diff --git a/src/zen/tests/mochitests/zoom/browser_background_zoom.js b/src/zen/tests/mochitests/zoom/browser_background_zoom.js index d757d8e7b..10754e294 100644 --- a/src/zen/tests/mochitests/zoom/browser_background_zoom.js +++ b/src/zen/tests/mochitests/zoom/browser_background_zoom.js @@ -1,8 +1,8 @@ var gTestPage = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/zoom/zoom_test.html"; var gTestImage = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/general/moz.png"; var gTab1, gTab2, gTab3; var gLevel; diff --git a/src/zen/tests/mochitests/zoom/browser_default_zoom_multitab.js b/src/zen/tests/mochitests/zoom/browser_default_zoom_multitab.js index d20402088..7dea43973 100644 --- a/src/zen/tests/mochitests/zoom/browser_default_zoom_multitab.js +++ b/src/zen/tests/mochitests/zoom/browser_default_zoom_multitab.js @@ -4,9 +4,9 @@ "use strict"; add_task(async function test_multidomain_global_zoom() { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const TEST_PAGE_URL_1 = "http://example.com/"; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const TEST_PAGE_URL_2 = "http://example.org/"; // Prepare the test tabs @@ -95,9 +95,9 @@ add_task(async function test_multidomain_global_zoom() { }); add_task(async function test_site_specific_global_zoom() { - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const TEST_PAGE_URL_1 = "http://example.net/"; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const TEST_PAGE_URL_2 = "http://example.net/"; // Prepare the test tabs diff --git a/src/zen/tests/mochitests/zoom/browser_image_zoom_tabswitch.js b/src/zen/tests/mochitests/zoom/browser_image_zoom_tabswitch.js index b2357d813..84862abe3 100644 --- a/src/zen/tests/mochitests/zoom/browser_image_zoom_tabswitch.js +++ b/src/zen/tests/mochitests/zoom/browser_image_zoom_tabswitch.js @@ -6,7 +6,7 @@ function test() { let tab1, tab2; const TEST_IMAGE = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/general/moz.png"; waitForExplicitFinish(); diff --git a/src/zen/tests/mochitests/zoom/browser_mousewheel_zoom.js b/src/zen/tests/mochitests/zoom/browser_mousewheel_zoom.js index a814f1dba..8ccbf3457 100644 --- a/src/zen/tests/mochitests/zoom/browser_mousewheel_zoom.js +++ b/src/zen/tests/mochitests/zoom/browser_mousewheel_zoom.js @@ -4,7 +4,7 @@ "use strict"; const TEST_PAGE = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/zoom/zoom_test.html"; var gTab1, gTab2, gLevel1; diff --git a/src/zen/tests/mochitests/zoom/browser_sitespecific_background_pref.js b/src/zen/tests/mochitests/zoom/browser_sitespecific_background_pref.js index 5756c4d8d..81440fde5 100644 --- a/src/zen/tests/mochitests/zoom/browser_sitespecific_background_pref.js +++ b/src/zen/tests/mochitests/zoom/browser_sitespecific_background_pref.js @@ -3,7 +3,7 @@ function test() { (async function () { let testPage = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/zoom/zoom_test.html"; let tab1 = BrowserTestUtils.addTab(gBrowser); await FullZoomHelper.selectTabAndWaitForLocationChange(tab1); diff --git a/src/zen/tests/mochitests/zoom/browser_sitespecific_video_zoom.js b/src/zen/tests/mochitests/zoom/browser_sitespecific_video_zoom.js index 94fd0dee5..6f3ebc873 100644 --- a/src/zen/tests/mochitests/zoom/browser_sitespecific_video_zoom.js +++ b/src/zen/tests/mochitests/zoom/browser_sitespecific_video_zoom.js @@ -4,10 +4,10 @@ "use strict"; const TEST_PAGE = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/zoom/zoom_test.html"; const TEST_VIDEO = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/general/video.webm"; var gTab1, gTab2, gLevel1; diff --git a/src/zen/tests/mochitests/zoom/browser_subframe_textzoom.js b/src/zen/tests/mochitests/zoom/browser_subframe_textzoom.js index e5d40cf58..c456feaea 100644 --- a/src/zen/tests/mochitests/zoom/browser_subframe_textzoom.js +++ b/src/zen/tests/mochitests/zoom/browser_subframe_textzoom.js @@ -11,7 +11,7 @@ function test() { waitForExplicitFinish(); const TEST_PAGE_URL = 'data:text/html,'; - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url const TEST_IFRAME_URL = "http://test2.example.org/"; (async function () { diff --git a/src/zen/tests/mochitests/zoom/browser_tabswitch_zoom_flicker.js b/src/zen/tests/mochitests/zoom/browser_tabswitch_zoom_flicker.js index df1c3816a..6d5d12981 100644 --- a/src/zen/tests/mochitests/zoom/browser_tabswitch_zoom_flicker.js +++ b/src/zen/tests/mochitests/zoom/browser_tabswitch_zoom_flicker.js @@ -10,7 +10,7 @@ function test() { Services.prefs.setBoolPref("browser.zoom.siteSpecific", true); let uri = - // eslint-disable-next-line @microsoft/sdl/no-insecure-url + // eslint-disable-next-line sdl/no-insecure-url "http://example.org/browser/browser/base/content/test/zoom/zoom_test.html"; (async function () { diff --git a/src/zen/welcome/ZenWelcome.mjs b/src/zen/welcome/ZenWelcome.mjs index bed6b00a0..7baac6aba 100644 --- a/src/zen/welcome/ZenWelcome.mjs +++ b/src/zen/welcome/ZenWelcome.mjs @@ -189,7 +189,7 @@ document.getElementById("zen-welcome-start").remove(); const pages = document.getElementById("zen-welcome-pages"); pages.style.display = "flex"; - animate(pages, { opacity: [0, 1] }, { ...kFade, duration: 0.2 }); + animate(pages, { opacity: [0, 1] }, { ...kFade, duration: 0.45 }); this.backButton.addEventListener("click", () => this.back()); } @@ -501,7 +501,7 @@ // 20 is the shadow width * 2 anchor.style.height = panelRect.height - - (AppConstants.platform == "macosx" ? -72 : 20) + + (AppConstants.platform == "macosx" ? -90 : 20) + "px"; anchor.style.width = panelRect.width - 20 + "px"; }, @@ -687,7 +687,7 @@ chars, { opacity: [0, 1], y: [50, 0] }, { - delay: getMotion().stagger(0.035, { startDelay: 0.2 }), + delay: getMotion().stagger(0.035, { startDelay: 0.8 }), type: "spring", bounce: 0.3, visualDuration: 0.45, @@ -700,7 +700,11 @@ await animate( "#zen-welcome-title .zen-welcome-char, #zen-welcome-start-button", { opacity: [1, 0], y: [0, -14] }, - { ...kSpring, delay: getMotion().stagger(0.012) } + { + duration: 0.3, + ease: "easeIn", + delay: getMotion().stagger(0.012), + } ); new nsZenWelcomePages(getWelcomePages()); }, diff --git a/src/zen/welcome/zen-welcome.css b/src/zen/welcome/zen-welcome.css index 13247db21..6b697eb24 100644 --- a/src/zen/welcome/zen-welcome.css +++ b/src/zen/welcome/zen-welcome.css @@ -74,7 +74,7 @@ font-weight: 600; cursor: pointer; will-change: transform; - transition: scale 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); + transition: scale 0.15s ease-out; &:hover { scale: 1.03; @@ -110,7 +110,7 @@ fill: white !important; will-change: transform; - transition: scale 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); + transition: scale 0.15s ease-out; &:hover { scale: 1.03; @@ -294,6 +294,7 @@ overflow-y: auto; padding-top: 6rem; padding-bottom: 6rem; + scrollbar-width: none; mask-image: linear-gradient( transparent, diff --git a/surfer.json b/surfer.json index 340cc61c7..f144a9df1 100644 --- a/surfer.json +++ b/surfer.json @@ -5,7 +5,7 @@ "binaryName": "zen", "version": { "product": "firefox", - "version": "154.0.1", + "version": "155.0", "candidate": "155.0", "candidateBuild": 1 },