summaryrefslogtreecommitdiffstats
path: root/browser/base/content
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content')
-rw-r--r--browser/base/content/aboutDialog-appUpdater.js2
-rw-r--r--browser/base/content/aboutDialog.xhtml2
-rw-r--r--browser/base/content/appmenu-viewcache.inc.xhtml168
-rw-r--r--browser/base/content/browser-a11yUtils.js8
-rw-r--r--browser/base/content/browser-addons.js143
-rw-r--r--browser/base/content/browser-allTabsMenu.inc.xhtml4
-rw-r--r--browser/base/content/browser-allTabsMenu.js21
-rw-r--r--browser/base/content/browser-box.inc.xhtml3
-rw-r--r--browser/base/content/browser-captivePortal.js2
-rw-r--r--browser/base/content/browser-commands.js591
-rw-r--r--browser/base/content/browser-context.inc2
-rw-r--r--browser/base/content/browser-ctrlTab.js4
-rw-r--r--browser/base/content/browser-data-submission-info-bar.js2
-rw-r--r--browser/base/content/browser-fullScreenAndPointerLock.js43
-rw-r--r--browser/base/content/browser-gestureSupport.js10
-rw-r--r--browser/base/content/browser-init.js1107
-rw-r--r--browser/base/content/browser-menubar.inc16
-rw-r--r--browser/base/content/browser-pageActions.js4
-rw-r--r--browser/base/content/browser-places.js29
-rw-r--r--browser/base/content/browser-sets.inc46
-rw-r--r--browser/base/content/browser-sidebar.js674
-rw-r--r--browser/base/content/browser-siteIdentity.js15
-rw-r--r--browser/base/content/browser-sitePermissionPanel.js7
-rw-r--r--browser/base/content/browser-siteProtections.js39
-rw-r--r--browser/base/content/browser-sync.js336
-rw-r--r--browser/base/content/browser-tabsintitlebar.js2
-rw-r--r--browser/base/content/browser-thumbnails.js4
-rw-r--r--browser/base/content/browser-toolbarKeyNav.js2
-rw-r--r--browser/base/content/browser.css13
-rw-r--r--browser/base/content/browser.js2145
-rw-r--r--browser/base/content/browser.js.globals29
-rw-r--r--browser/base/content/browser.xhtml10
-rw-r--r--browser/base/content/contentTheme.js21
-rw-r--r--browser/base/content/macWindow.inc.xhtml1
-rw-r--r--browser/base/content/main-popupset.inc.xhtml57
-rw-r--r--browser/base/content/navigator-toolbox.inc.xhtml18
-rw-r--r--browser/base/content/nsContextMenu.js95
-rw-r--r--browser/base/content/pageinfo/pageInfo.js40
-rw-r--r--browser/base/content/pageinfo/pageInfo.xhtml4
-rw-r--r--browser/base/content/pageinfo/permissions.js2
-rw-r--r--browser/base/content/pageinfo/security.js2
-rw-r--r--browser/base/content/popup-notifications.inc2
-rw-r--r--browser/base/content/sanitizeDialog.js23
-rw-r--r--browser/base/content/spotlight.html1
-rw-r--r--browser/base/content/tabbrowser-tab.js26
-rw-r--r--browser/base/content/tabbrowser-tabs.js57
-rw-r--r--browser/base/content/tabbrowser.css101
-rw-r--r--browser/base/content/tabbrowser.js397
-rw-r--r--browser/base/content/test/about/browser.toml1
-rw-r--r--browser/base/content/test/about/browser_aboutCertError.js4
-rw-r--r--browser/base/content/test/about/browser_aboutNetError_csp_iframe.js4
-rw-r--r--browser/base/content/test/about/browser_aboutNetError_xfo_iframe.js4
-rw-r--r--browser/base/content/test/alerts/browser.toml4
-rw-r--r--browser/base/content/test/alerts/browser_notification_close.js25
-rw-r--r--browser/base/content/test/alerts/browser_notification_open_settings.js2
-rw-r--r--browser/base/content/test/alerts/browser_notification_replace.js66
-rw-r--r--browser/base/content/test/alerts/head.js2
-rw-r--r--browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js2
-rw-r--r--browser/base/content/test/contextMenu/browser.toml6
-rw-r--r--browser/base/content/test/contextMenu/browser_contextmenu.js71
-rw-r--r--browser/base/content/test/contextMenu/browser_contextmenu_badiframe.js2
-rw-r--r--browser/base/content/test/contextMenu/browser_contextmenu_cross_boundary_selection.js73
-rw-r--r--browser/base/content/test/contextMenu/browser_contextmenu_save_blocked.js2
-rw-r--r--browser/base/content/test/contextMenu/browser_strip_on_share_link.js12
-rw-r--r--browser/base/content/test/contextMenu/browser_strip_on_share_nested_link.js162
-rw-r--r--browser/base/content/test/contextMenu/contextmenu_common.js4
-rw-r--r--browser/base/content/test/contextMenu/subtst_contextmenu.html4
-rw-r--r--browser/base/content/test/contextMenu/subtst_contextmenu_webext.html2
-rw-r--r--browser/base/content/test/favicons/browser_favicon_change_not_in_document.js8
-rw-r--r--browser/base/content/test/favicons/browser_favicon_load.js2
-rw-r--r--browser/base/content/test/favicons/browser_favicon_nostore.js13
-rw-r--r--browser/base/content/test/favicons/browser_favicon_referer.js4
-rw-r--r--browser/base/content/test/favicons/browser_missing_favicon.js2
-rw-r--r--browser/base/content/test/forms/browser.toml2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup.js4
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_colors.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_dir.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_focus.js38
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_large.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_minFontSize.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_text_transform.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_user_input.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_width.js2
-rw-r--r--browser/base/content/test/forms/browser_selectpopup_xhtml.js2
-rw-r--r--browser/base/content/test/fullscreen/browser_fullscreen_context_menu.js4
-rw-r--r--browser/base/content/test/fullscreen/browser_fullscreen_window_focus.js2
-rw-r--r--browser/base/content/test/fullscreen/head.js2
-rw-r--r--browser/base/content/test/general/browser.toml15
-rw-r--r--browser/base/content/test/general/browser_accesskeys.js4
-rw-r--r--browser/base/content/test/general/browser_alltabslistener.js15
-rw-r--r--browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js4
-rw-r--r--browser/base/content/test/general/browser_bug356571.js2
-rw-r--r--browser/base/content/test/general/browser_bug417483.js2
-rw-r--r--browser/base/content/test/general/browser_bug537013.js2
-rw-r--r--browser/base/content/test/general/browser_bug565575.js2
-rw-r--r--browser/base/content/test/general/browser_bug567306.js2
-rw-r--r--browser/base/content/test/general/browser_bug609700.js6
-rw-r--r--browser/base/content/test/general/browser_bug623893.js2
-rw-r--r--browser/base/content/test/general/browser_bug676619.js12
-rw-r--r--browser/base/content/test/general/browser_bug734076.js6
-rw-r--r--browser/base/content/test/general/browser_bug763468_perwindowpb.js2
-rw-r--r--browser/base/content/test/general/browser_bug767836_perwindowpb.js2
-rw-r--r--browser/base/content/test/general/browser_bug817947.js2
-rw-r--r--browser/base/content/test/general/browser_clipboard.js6
-rw-r--r--browser/base/content/test/general/browser_clipboard_pastefile.js4
-rw-r--r--browser/base/content/test/general/browser_documentnavigation.js4
-rw-r--r--browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js6
-rw-r--r--browser/base/content/test/general/browser_double_close_tab.js2
-rw-r--r--browser/base/content/test/general/browser_focusonkeydown.js2
-rw-r--r--browser/base/content/test/general/browser_fullscreen-window-open.js8
-rw-r--r--browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js2
-rw-r--r--browser/base/content/test/general/browser_newWindowDrop.js2
-rw-r--r--browser/base/content/test/general/browser_plainTextLinks.js2
-rw-r--r--browser/base/content/test/general/browser_private_no_prompt.js4
-rw-r--r--browser/base/content/test/general/browser_remoteTroubleshoot.js4
-rw-r--r--browser/base/content/test/general/browser_save_link-perwindowpb.js10
-rw-r--r--browser/base/content/test/general/browser_save_link_when_window_navigates.js8
-rw-r--r--browser/base/content/test/general/browser_save_private_link_perwindowpb.js6
-rw-r--r--browser/base/content/test/general/browser_save_video.js4
-rw-r--r--browser/base/content/test/general/browser_tabfocus.js4
-rw-r--r--browser/base/content/test/general/browser_tabs_owner.js6
-rw-r--r--browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js6
-rw-r--r--browser/base/content/test/general/browser_zbug569342.js2
-rw-r--r--browser/base/content/test/general/download_page.html12
-rw-r--r--browser/base/content/test/general/head.js4
-rw-r--r--browser/base/content/test/general/navigating_window_with_download.html2
-rw-r--r--browser/base/content/test/general/video.oggbin285310 -> 0 bytes
-rw-r--r--browser/base/content/test/general/video.webmbin0 -> 222879 bytes
-rw-r--r--browser/base/content/test/general/web_video.html2
-rw-r--r--browser/base/content/test/general/web_video1.ogvbin28942 -> 0 bytes
-rw-r--r--browser/base/content/test/general/web_video1.ogv^headers^3
-rw-r--r--browser/base/content/test/general/web_video1.webmbin0 -> 17555 bytes
-rw-r--r--browser/base/content/test/general/web_video1.webm^headers^3
-rw-r--r--browser/base/content/test/historySwipeAnimation/browser_historySwipeAnimation.js2
-rw-r--r--browser/base/content/test/keyboard/browser_toolbarButtonKeyPress.js93
-rw-r--r--browser/base/content/test/metaTags/browser_bad_meta_tags.js11
-rw-r--r--browser/base/content/test/metaTags/browser_meta_tags.js8
-rw-r--r--browser/base/content/test/outOfProcess/browser_basic_outofprocess.js9
-rw-r--r--browser/base/content/test/pageActions/head.js2
-rw-r--r--browser/base/content/test/pageinfo/browser.toml2
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js2
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_iframe_media.js2
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_image_info.js2
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_images.js4
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_permissions.js12
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_rtl.js25
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_security.js21
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_separate_private.js4
-rw-r--r--browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js2
-rw-r--r--browser/base/content/test/pageinfo/image.html2
-rw-r--r--browser/base/content/test/performance/StartupContentSubframe.sys.mjs2
-rw-r--r--browser/base/content/test/performance/browser_preferences_usage.js19
-rw-r--r--browser/base/content/test/performance/browser_startup_content.js10
-rw-r--r--browser/base/content/test/performance/browser_startup_mainthreadio.js1
-rw-r--r--browser/base/content/test/performance/browser_tabdetach.js4
-rw-r--r--browser/base/content/test/performance/browser_tabopen.js2
-rw-r--r--browser/base/content/test/performance/browser_tabopen_squeeze.js2
-rw-r--r--browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js4
-rw-r--r--browser/base/content/test/performance/browser_tabswitch.js14
-rw-r--r--browser/base/content/test/performance/browser_windowclose.js2
-rw-r--r--browser/base/content/test/performance/browser_windowopen.js2
-rw-r--r--browser/base/content/test/performance/head.js21
-rw-r--r--browser/base/content/test/permissions/browser_autoplay_blocked.js2
-rw-r--r--browser/base/content/test/permissions/browser_canvas_fingerprinting_resistance.js8
-rw-r--r--browser/base/content/test/permissions/browser_site_scoped_permissions.js89
-rw-r--r--browser/base/content/test/permissions/browser_temporary_permissions_navigation.js2
-rw-r--r--browser/base/content/test/plugins/head.js4
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification.js22
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_2.js20
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_3.js12
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_4.js10
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_5.js14
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js2
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js6
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_no_anchors.js6
-rw-r--r--browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js414
-rw-r--r--browser/base/content/test/popups/browser_popup_close_main_window.js6
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI.js2
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI_cookies_subview.js2
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI_fetch.js2
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI_info_message.js4
-rw-r--r--browser/base/content/test/referrer/head.js2
-rw-r--r--browser/base/content/test/sanitize/browser_cookiePermission_aboutURL.js4
-rw-r--r--browser/base/content/test/sanitize/browser_sanitize-timespans.js2
-rw-r--r--browser/base/content/test/sanitize/browser_sanitize-timespans_v2.js2
-rw-r--r--browser/base/content/test/sanitize/browser_sanitizeDialog_v2.js4
-rw-r--r--browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js65
-rw-r--r--browser/base/content/test/sanitize/head.js4
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_adopt.js8
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_app_locale_changed.js6
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_keys.js16
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_move.js28
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_persist.js4
-rw-r--r--browser/base/content/test/sidebar/browser_sidebar_switcher.js43
-rw-r--r--browser/base/content/test/siteIdentity/browser_identityBlock_focus.js2
-rw-r--r--browser/base/content/test/siteIdentity/browser_identityPopup_clearSiteData.js2
-rw-r--r--browser/base/content/test/siteIdentity/browser_navigation_failures.js4
-rw-r--r--browser/base/content/test/siteIdentity/browser_secure_transport_insecure_scheme.js8
-rw-r--r--browser/base/content/test/siteIdentity/head.js12
-rw-r--r--browser/base/content/test/static/browser_all_files_referenced.js36
-rw-r--r--browser/base/content/test/static/browser_parsable_css.js20
-rw-r--r--browser/base/content/test/static/browser_parsable_script.js9
-rw-r--r--browser/base/content/test/static/browser_sentence_case_strings.js2
-rw-r--r--browser/base/content/test/static/head.js2
-rw-r--r--browser/base/content/test/sync/browser_contextmenu_sendpage.js57
-rw-r--r--browser/base/content/test/sync/browser_contextmenu_sendtab.js2
-rw-r--r--browser/base/content/test/sync/browser_fxa_web_channel.js16
-rw-r--r--browser/base/content/test/sync/browser_sync.js14
-rw-r--r--browser/base/content/test/tabPrompts/browser.toml2
-rw-r--r--browser/base/content/test/tabPrompts/browser_abort_when_in_modal_state.js8
-rw-r--r--browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js4
-rw-r--r--browser/base/content/test/tabPrompts/browser_contentOrigins.js6
-rw-r--r--browser/base/content/test/tabPrompts/browser_promptDelays.js113
-rw-r--r--browser/base/content/test/tabPrompts/browser_promptFocus.js3
-rw-r--r--browser/base/content/test/tabPrompts/browser_windowPrompt.js16
-rw-r--r--browser/base/content/test/tabcrashed/browser_aboutRestartRequired.toml10
-rw-r--r--browser/base/content/test/tabcrashed/browser_aboutRestartRequired_noForkServer.toml8
-rw-r--r--browser/base/content/test/tabcrashed/head.js8
-rw-r--r--browser/base/content/test/tabs/browser.toml6
-rw-r--r--browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js2
-rw-r--r--browser/base/content/test/tabs/browser_audioTabIcon.js4
-rw-r--r--browser/base/content/test/tabs/browser_blank_tab_label.js49
-rw-r--r--browser/base/content/test/tabs/browser_e10s_about_page_triggeringprincipal.js4
-rw-r--r--browser/base/content/test/tabs/browser_e10s_about_process.js4
-rw-r--r--browser/base/content/test/tabs/browser_lastSeenActive.js260
-rw-r--r--browser/base/content/test/tabs/browser_lazy_tab_browser_events.js14
-rw-r--r--browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_blank_target.js4
-rw-r--r--browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_by_script.js2
-rw-r--r--browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_no_target.js2
-rw-r--r--browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_other_target.js4
-rw-r--r--browser/base/content/test/tabs/browser_long_data_url_label_truncation.js2
-rw-r--r--browser/base/content/test/tabs/browser_multiselect_tabs_close_duplicate_tabs.js178
-rw-r--r--browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js16
-rw-r--r--browser/base/content/test/tabs/browser_new_tab_bookmarks_toolbar_height.js4
-rw-r--r--browser/base/content/test/tabs/browser_new_tab_in_privilegedabout_process_pref.js2
-rw-r--r--browser/base/content/test/tabs/browser_new_tab_url.js4
-rw-r--r--browser/base/content/test/tabs/browser_open_newtab_start_observer_notification.js4
-rw-r--r--browser/base/content/test/tabs/browser_pinnedTabs_closeByKeyboard.js4
-rw-r--r--browser/base/content/test/tabs/browser_privilegedmozilla_process_pref.js2
-rw-r--r--browser/base/content/test/tabs/browser_removeTabs_order.js2
-rw-r--r--browser/base/content/test/tabs/browser_tab_label_picture_in_picture.js2
-rw-r--r--browser/base/content/test/tabs/browser_tab_manager_visibility.js4
-rw-r--r--browser/base/content/test/tabs/browser_tab_preview.js263
-rw-r--r--browser/base/content/test/tabs/browser_tab_tooltips.js2
-rw-r--r--browser/base/content/test/tabs/browser_tabswitch_select.js4
-rw-r--r--browser/base/content/test/tabs/browser_tabswitch_updatecommands.js2
-rw-r--r--browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js2
-rw-r--r--browser/base/content/test/tabs/browser_visibleTabs_contextMenu.js19
-rw-r--r--browser/base/content/test/tabs/browser_window_open_modifiers.js2
-rw-r--r--browser/base/content/test/tabs/common_link_in_tab_title_and_url_prefilled.js2
-rw-r--r--browser/base/content/test/webextensions/browser_aboutaddons_blanktab.js2
-rw-r--r--browser/base/content/test/webextensions/browser_extension_sideloading.js10
-rw-r--r--browser/base/content/test/webextensions/browser_extension_update_background.js6
-rw-r--r--browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js2
-rw-r--r--browser/base/content/test/webextensions/browser_legacy_webext.xpibin4243 -> 362 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_permissions_installTrigger.js6
-rw-r--r--browser/base/content/test/webextensions/browser_permissions_local_file.js17
-rw-r--r--browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js13
-rw-r--r--browser/base/content/test/webextensions/browser_permissions_pointerevent.js6
-rw-r--r--browser/base/content/test/webextensions/browser_update_checkForUpdates.js2
-rw-r--r--browser/base/content/test/webextensions/browser_update_interactive_noprompt.js2
-rw-r--r--browser/base/content/test/webextensions/browser_webext_nopermissions.xpibin4273 -> 7500 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_permissions.xpibin16602 -> 19923 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update1.xpibin4271 -> 326 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update2.xpibin4291 -> 343 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update_icon1.xpibin16545 -> 12581 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update_icon2.xpibin16564 -> 12599 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update_perms1.xpibin4273 -> 320 bytes
-rw-r--r--browser/base/content/test/webextensions/browser_webext_update_perms2.xpibin4282 -> 331 bytes
-rw-r--r--browser/base/content/test/webextensions/head.js4
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js4
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_by_device_id.js2
-rw-r--r--browser/base/content/test/webrtc/browser_devices_get_user_media_grace.js6
-rw-r--r--browser/base/content/test/webrtc/browser_devices_select_audio_output.js2
-rw-r--r--browser/base/content/test/webrtc/browser_webrtc_hooks.js28
-rw-r--r--browser/base/content/test/webrtc/head.js6
-rw-r--r--browser/base/content/test/zoom/browser.toml2
-rw-r--r--browser/base/content/test/zoom/browser_sitespecific_video_zoom.js2
-rw-r--r--browser/base/content/test/zoom/browser_zoom_commands.js4
-rw-r--r--browser/base/content/test/zoom/head.js8
-rw-r--r--browser/base/content/titlebar-items.inc.xhtml2
-rw-r--r--browser/base/content/utilityOverlay.js9
-rw-r--r--browser/base/content/webext-panels.js12
-rw-r--r--browser/base/content/webext-panels.xhtml2
-rw-r--r--browser/base/content/webrtcIndicator.js2
285 files changed, 4966 insertions, 4612 deletions
diff --git a/browser/base/content/aboutDialog-appUpdater.js b/browser/base/content/aboutDialog-appUpdater.js
index 21bf83bc42..5a8cc0561b 100644
--- a/browser/base/content/aboutDialog-appUpdater.js
+++ b/browser/base/content/aboutDialog-appUpdater.js
@@ -28,7 +28,7 @@ var UPDATING_MIN_DISPLAY_TIME_MS = 1500;
var gAppUpdater;
-function onUnload(aEvent) {
+function onUnload(_aEvent) {
if (gAppUpdater) {
gAppUpdater.destroy();
gAppUpdater = null;
diff --git a/browser/base/content/aboutDialog.xhtml b/browser/base/content/aboutDialog.xhtml
index e0fcce367a..55de242415 100644
--- a/browser/base/content/aboutDialog.xhtml
+++ b/browser/base/content/aboutDialog.xhtml
@@ -138,7 +138,7 @@
<label is="text-link" useoriginprincipal="true" href="about:credits" data-l10n-name="community-creditsLink"/>
</description>
<description class="text-blurb" id="contributeDesc" data-l10n-id="helpus">
- <label is="text-link" href="https://donate.mozilla.org/?utm_source=firefox&#38;utm_medium=referral&#38;utm_campaign=firefox_about&#38;utm_content=firefox_about" data-l10n-name="helpus-donateLink"/>
+ <label is="text-link" href="https://foundation.mozilla.org/?form=firefox-about" data-l10n-name="helpus-donateLink"/>
<label is="text-link" href="https://www.mozilla.org/contribute/?utm_source=firefox-browser&#38;utm_medium=firefox-desktop&#38;utm_campaign=about-dialog" data-l10n-name="helpus-getInvolvedLink"/>
</description>
</vbox>
diff --git a/browser/base/content/appmenu-viewcache.inc.xhtml b/browser/base/content/appmenu-viewcache.inc.xhtml
index 04bba182fb..9633c7d79d 100644
--- a/browser/base/content/appmenu-viewcache.inc.xhtml
+++ b/browser/base/content/appmenu-viewcache.inc.xhtml
@@ -3,24 +3,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
<html:template id="appMenu-viewCache">
- <panelview id="appMenu-mainView" class="PanelUI-subView">
- <vbox class="panel-subview-body">
- <toolbarbutton id="appMenu-whatsnew-button"
- class="subviewbutton subviewbutton-iconic subviewbutton-nav"
- hidden="true"
- closemenu="none"
- oncommand="PanelUI.showSubView('PanelUI-whatsNew', this)"/>
- </vbox>
- </panelview>
-
- <!-- This is a placeholder app menu which should be replaced with the "real"
- Proton app menu before the Proton pref starts getting enabled. -->
- <panelview id="appMenu-protonMainView" class="PanelUI-subView"
+ <panelview id="appMenu-mainView" class="PanelUI-subView"
lockpanelvertical="true">
<vbox class="panel-subview-body">
- <vbox id="appMenu-proton-addon-banners"/>
- <toolbarbutton id="appMenu-proton-update-banner" class="panel-banner-item subviewbutton"
- oncommand="PanelUI._onBannerItemSelected(event)"
+ <vbox id="appMenu-addon-banners"/>
+ <toolbarbutton id="appMenu-update-banner" class="panel-banner-item subviewbutton"
wrap="true"
hidden="true"/>
<toolbaritem id="appMenu-fxa-status2"
@@ -29,7 +16,7 @@
<html:div id="appMenu-fxa-text" data-l10n-id="appmenu-fxa-sync-and-save-data2"/>
<toolbarbutton id="appMenu-fxa-label2"
class="subviewbutton"
- oncommand="gSync.toggleAccountPanel(this, event)">
+ >
<vbox flex="1">
<label id="appMenu-header-title"
crop="end"/>
@@ -43,7 +30,6 @@
data-l10n-id="appmenuitem-profiles"
data-l10n-args='{ "profilename": "" }'
closemenu="none"
- oncommand="gProfiles.updateView(this)"
hidden="true"/>
<toolbarseparator id="appMenu-fxa-separator" class="proton-zap"/>
<toolbarbutton id="appMenu-new-tab-button2"
@@ -66,12 +52,12 @@
class="subviewbutton subviewbutton-nav"
data-l10n-id="library-bookmarks-menu"
closemenu="none"
- oncommand="BookmarkingUI.showSubView(this);"/>
+ />
<toolbarbutton id="appMenu-history-button"
class="subviewbutton subviewbutton-nav"
data-l10n-id="appmenuitem-history"
closemenu="none"
- oncommand="PanelUI.showSubView('PanelUI-history', this)"/>
+ />
<toolbarbutton id="appMenu-downloads-button"
class="subviewbutton"
data-l10n-id="appmenuitem-downloads"
@@ -80,7 +66,6 @@
<toolbarbutton id="appMenu-passwords-button"
class="subviewbutton"
data-l10n-id="appmenuitem-passwords"
- oncommand="LoginHelper.openPasswordManager(window, { entryPoint: 'mainmenu' })"
/>
<toolbarbutton id="appMenu-extensions-themes-button"
class="subviewbutton"
@@ -129,13 +114,6 @@
class="subviewbutton subviewbutton-iconic"
data-l10n-id="appmenuitem-fullscreen"
type="checkbox"
-# Note that we're custom-handling this click to make sure the panel disappears
-# before entering fullscreen, as it does some odd moving about on the screen
-# in the middle of the fullscreen transition otherwise.
- oncommand="
- this.closest('panel').hidePopup();
- setTimeout(() => BrowserFullScreen(), 0);
- "
tooltip="dynamic-shortcut-tooltip">
<observes element="View:FullScreen" attribute="checked"/>
</toolbarbutton>
@@ -147,12 +125,12 @@
#ifdef XP_MACOSX
key="key_preferencesCmdMac"
#endif
- oncommand="openPreferences()"/>
+ />
<toolbarbutton id="appMenu-more-button2"
class="subviewbutton subviewbutton-nav"
data-l10n-id="appmenuitem-more-tools"
closemenu="none"
- oncommand="PanelUI.showMoreToolsPanel(this);"/>
+ />
<toolbarbutton id="appMenu-report-broken-site-button"
class="subviewbutton subviewbutton-nav"
data-l10n-id="appmenuitem-report-broken-site"
@@ -163,7 +141,7 @@
class="subviewbutton subviewbutton-nav"
data-l10n-id="appmenuitem-help"
closemenu="none"
- oncommand="PanelUI.showSubView('PanelUI-helpView', this)"/>
+ />
#ifndef XP_MACOSX
<toolbarseparator/>
<toolbarbutton id="appMenu-quit-button2"
@@ -181,16 +159,16 @@
data-l10n-id="appmenu-recently-closed-tabs"
class="subviewbutton subviewbutton-nav"
closemenu="none"
- oncommand="PanelUI.showSubView('appMenu-library-recentlyClosedTabs', this)"/>
+ />
<toolbarbutton id="appMenuRecentlyClosedWindows"
data-l10n-id="appmenu-recently-closed-windows"
class="subviewbutton subviewbutton-nav"
closemenu="none"
- oncommand="PanelUI.showSubView('appMenu-library-recentlyClosedWindows', this)"/>
+ />
<toolbarbutton id="appMenuSearchHistory"
data-l10n-id="appmenu-search-history"
class="subviewbutton"
- oncommand="PlacesCommandHook.searchHistory()"/>
+ />
<toolbarbutton id="appMenu-restoreSession"
data-l10n-id="appmenu-restore-session"
class="subviewbutton"
@@ -216,7 +194,7 @@
<toolbarbutton id="PanelUI-historyMore"
class="subviewbutton panel-subview-footer-button"
data-l10n-id="appmenu-manage-history"
- oncommand="PlacesCommandHook.showPlacesOrganizer('History'); CustomizableUI.hidePanelForNode(this);"/>
+ />
</panelview>
<panelview id="PanelUI-profiles" flex="1">
@@ -227,10 +205,10 @@
<hbox id="this-profile-buttons">
<toolbarbutton id="profiles-edit-this-delete-button"
class="subviewbutton toolbarbutton-1"
- oncommand="switchToTabHavingURI('about:profilemanager', true)"/>
+ />
<toolbarbutton id="profiles-delete-this-profile-button"
class="subviewbutton toolbarbutton-1"
- oncommand="switchToTabHavingURI('about:profilemanager', true)"/>
+ />
</hbox>
</vbox>
<toolbarseparator/>
@@ -240,15 +218,15 @@
class="subviewbutton"
data-l10n-id="appmenu-close-profile"
data-l10n-args='{ "profilename": "" }'
- oncommand=""/>
+ />
<toolbarbutton id="profiles-create-profile-button"
class="subviewbutton"
data-l10n-id="appmenu-create-profile"
- oncommand="switchToTabHavingURI('about:profilemanager', true)"/>
+ />
<toolbarbutton id="profiles-manage-profiles-button"
class="subviewbutton"
data-l10n-id="appmenu-manage-profiles"
- oncommand="switchToTabHavingURI('about:profilemanager', true)"/>
+ />
</vbox>
</panelview>
@@ -272,12 +250,12 @@
<toolbarbutton id="panelMenu_searchBookmarks"
data-l10n-id="bookmarks-search"
class="subviewbutton"
- oncommand="PlacesCommandHook.searchBookmarks();"/>
+ />
<toolbarbutton id="panelMenu_viewBookmarksToolbar"
class="subviewbutton"
data-l10n-id="bookmarks-tools-toolbar-visibility-panel"
data-l10n-args='{ "isVisible": false }'
- oncommand="BookmarkingUI.toggleBookmarksToolbar('bookmark-tools');"/>
+ />
<toolbarseparator/>
<html:h2 id="panelMenu_recentBookmarks"
data-l10n-id="bookmarks-recent-bookmarks-panel-subheader"
@@ -470,8 +448,6 @@
<toolbarbutton id="PanelUI-remotetabs-syncnow"
align="center"
class="subviewbutton"
- oncommand="gSync.doSync();"
- onmouseover="gSync.refreshSyncButtonsTooltip();"
closemenu="none">
<hbox flex="1">
<image class="syncNowBtn"/>
@@ -486,7 +462,7 @@
<toolbarbutton id="PanelUI-remotetabs-view-managedevices"
class="subviewbutton"
data-l10n-id="appmenuitem-fxa-manage-account"
- oncommand="gSync.openDevicesManagementPage('syncedtabs-menupanel');">
+ >
<observes element="sidebar-box" attribute="positionend"/>
</toolbarbutton>
<toolbarseparator id="PanelUI-remotetabs-separator"/>
@@ -513,7 +489,7 @@
<toolbarbutton class="PanelUI-remotetabs-button"
id="PanelUI-remotetabs-tabsdisabledpane-button"
data-l10n-id="appmenu-remote-tabs-opensettings"
- oncommand="gSync.openPrefs('synced-tabs');"/>
+ />
</hbox>
</vbox>
</hbox>
@@ -527,7 +503,7 @@
<toolbarbutton id="PanelUI-remotetabs-connect-device-button"
class="PanelUI-remotetabs-button"
data-l10n-id="appmenu-remote-tabs-connectdevice"
- oncommand="gSync.openConnectAnotherDevice('synced-tabs');"/>
+ />
</vbox>
</hbox>
</deck>
@@ -545,7 +521,7 @@
<toolbarbutton class="PanelUI-remotetabs-button"
id="PanelUI-remotetabs-setupsync-button"
data-l10n-id="appmenu-remote-tabs-sign-into-sync"
- oncommand="gSync.openPrefs('synced-tabs');"/>
+ />
</vbox>
<!-- When Sync is not enabled -->
<vbox id="PanelUI-remotetabs-syncdisabled"
@@ -558,7 +534,7 @@
<toolbarbutton class="PanelUI-remotetabs-button"
id="PanelUI-remotetabs-syncdisabled-button"
data-l10n-id="appmenu-remote-tabs-turn-on-sync"
- oncommand="gSync.openPrefs('synced-tabs');"/>
+ />
</vbox>
<!-- When Sync needs re-authentication -->
<vbox id="PanelUI-remotetabs-reauthsync"
@@ -571,7 +547,7 @@
<toolbarbutton class="PanelUI-remotetabs-button"
id="PanelUI-remotetabs-reauthsync-button"
data-l10n-id="appmenu-remote-tabs-sign-into-sync"
- oncommand="gSync.openPrefs('synced-tabs');"/>
+ />
</vbox>
<!-- When Sync needs verification -->
<vbox id="PanelUI-remotetabs-unverified"
@@ -584,7 +560,7 @@
<toolbarbutton class="PanelUI-remotetabs-button"
id="PanelUI-remotetabs-unverified-button"
data-l10n-id="appmenu-remote-tabs-opensettings"
- oncommand="gSync.openPrefs('synced-tabs');"/>
+ />
</vbox>
</hbox>
</vbox>
@@ -595,7 +571,7 @@
<toolbarbutton id="fxa-manage-account-button"
align="center"
class="subviewbutton"
- oncommand="gSync.clickFxAMenuHeaderButton(this);">
+ >
<vbox flex="1">
<label id="fxa-menu-header-title"
crop="end"
@@ -609,8 +585,6 @@
<toolbarbutton id="PanelUI-fxa-menu-syncnow-button"
align="center"
class="subviewbutton"
- oncommand="gSync.doSyncFromFxaMenu(this);"
- onmouseover="gSync.refreshSyncButtonsTooltip();"
closemenu="none">
<hbox flex="1">
<image id="PanelUI-appMenu-fxa-image-last-synced"
@@ -627,43 +601,34 @@
<toolbarbutton id="PanelUI-fxa-menu-setup-sync-button"
class="subviewbutton"
data-l10n-id="appmenu-fxa-setup-sync"
- oncommand="gSync.openPrefsFromFxaMenu('sync_settings', this);"/>
+ />
<!-- The `Connect Another Device` button is disabled by default until the user logs into Sync. -->
<toolbarbutton id="PanelUI-fxa-menu-connect-device-button"
class="subviewbutton"
data-l10n-id="fxa-menu-connect-another-device"
disabled="true"
- oncommand="gSync.openConnectAnotherDeviceFromFxaMenu(this);"/>
+ />
<toolbarbutton id="PanelUI-fxa-menu-sendtab-button"
class="subviewbutton subviewbutton-nav"
data-l10n-id="fxa-menu-send-tab-to-device"
data-l10n-args='{"tabCount":1}'
closemenu="none"
- oncommand="gSync.showSendToDeviceViewFromFxaMenu(this);"/>
+ />
<toolbarbutton id="PanelUI-fxa-menu-sync-prefs-button"
class="subviewbutton"
data-l10n-id="fxa-menu-sync-settings"
hidden="true"
- oncommand="gSync.openPrefsFromFxaMenu('sync_settings', this);"/>
+ />
<toolbarseparator id="PanelUI-sign-out-separator" />
<toolbarbutton id="PanelUI-fxa-menu-account-signout-button"
class="subviewbutton"
data-l10n-id="fxa-menu-sign-out"
- oncommand="gSync.disconnect();"
hidden="true"/>
</vbox>
<!-- updateCTAPanel will control if we show this panel -->
- <vbox id="PanelUI-fxa-cta-menu">
- <toolbarbutton id="PanelUI-fxa-menu-sync-button" class="subviewbutton subviewbutton-iconic"
- oncommand="gSync.openPrefsFromFxaButton('sync_cta', this);">
- <vbox flex="1">
- <label id="fxa-menu-header-title" crop="end" data-l10n-id="fxa-menu-sync-title" />
- <label id="cta-menu-header-description" crop="end" data-l10n-id="fxa-menu-sync-description" />
- </vbox>
- </toolbarbutton>
+ <vbox id="PanelUI-fxa-cta-menu" hidden="true">
<toolbarseparator id="PanelUI-products-separator" />
- <toolbarbutton id="PanelUI-fxa-menu-monitor-button" class="subviewbutton subviewbutton-iconic"
- oncommand="gSync.openMonitorLink(this)">
+ <toolbarbutton id="PanelUI-fxa-menu-monitor-button" class="fxa-cta-button subviewbutton subviewbutton-iconic">
<vbox flex="1">
<hbox align="center">
<image class="PanelUI-fxa-menu-monitor-button ctaMenuLogo" role="presentation" />
@@ -672,8 +637,7 @@
<label id="cta-menu-header-description" crop="end" data-l10n-id="appmenuitem-monitor-description" />
</vbox>
</toolbarbutton>
- <toolbarbutton id="PanelUI-fxa-menu-relay-button" class="subviewbutton subviewbutton-iconic"
- oncommand="gSync.openRelayLink(this)">
+ <toolbarbutton id="PanelUI-fxa-menu-relay-button" class="fxa-cta-button subviewbutton subviewbutton-iconic">
<vbox flex="1">
<hbox align="center">
<image class="PanelUI-fxa-menu-relay-button ctaMenuLogo" role="presentation" />
@@ -682,8 +646,7 @@
<label id="cta-menu-header-description" crop="end" data-l10n-id="appmenuitem-relay-description" />
</vbox>
</toolbarbutton>
- <toolbarbutton id="PanelUI-fxa-menu-vpn-button" class="subviewbutton subviewbutton-iconic"
- oncommand="gSync.openVPNLink(this)">
+ <toolbarbutton id="PanelUI-fxa-menu-vpn-button" class="fxa-cta-button subviewbutton subviewbutton-iconic">
<vbox flex="1">
<hbox align="center">
<image class="PanelUI-fxa-menu-vpn-button ctaMenuLogo" role="presentation" />
@@ -725,7 +688,7 @@
<toolbarbutton id="PanelUI-fxa-menu-sendtab-not-configured-button"
class="PanelUI-fxa-signin-button"
data-l10n-id="appmenuitem-fxa-sign-in"
- oncommand="gSync.openPrefsFromFxaMenu('send_tab', this);"/>
+ />
</vbox>
</panelview>
@@ -736,7 +699,15 @@
<toolbarbutton id="PanelUI-fxa-menu-sendtab-connect-device-button"
class="PanelUI-fxa-signin-button"
data-l10n-id="appmenu-remote-tabs-connectdevice"
- oncommand="gSync.openConnectAnotherDeviceFromFxaMenu(this);"/>
+ />
+ </vbox>
+ </panelview>
+
+ <!-- This panelview holds the list of "inactive" tabs for devices -->
+ <panelview id="PanelUI-fxa-menu-inactive-tabs" class="PanelUI-subView PanelUI-remotetabs-clientcontainer">
+ <label itemtype="client">
+ </label>
+ <vbox class="panel-subview-body">
</vbox>
</panelview>
@@ -746,40 +717,17 @@
class="subviewbutton subviewbutton-nav"
data-l10n-id="library-bookmarks-menu"
closemenu="none"
- oncommand="BookmarkingUI.showSubView(this);"/>
+ />
<toolbarbutton id="appMenu-library-history-button"
class="subviewbutton subviewbutton-nav"
data-l10n-id="appmenuitem-history"
closemenu="none"
- oncommand="PanelUI.showSubView('PanelUI-history', this)"/>
+ />
<toolbarbutton id="appMenu-library-downloads-button"
class="subviewbutton"
data-l10n-id="appmenuitem-downloads"
- oncommand="DownloadsPanel.showDownloadsHistory();"/>
- </vbox>
- </panelview>
-
- <panelview id="PanelUI-whatsNew" class="PanelUI-subView" mainview-with-header="true">
- <hbox id="PanelUI-whatsNew-title" class="panel-header">
- <html:h1>
- <html:span data-l10n-id="whatsnew-panel-header"></html:span>
- </html:h1>
- </hbox>
- <toolbarseparator/>
- <vbox class="panel-subview-body">
- <toolbaritem id="PanelUI-whatsNew-content"
- orient="vertical"
- smoothscroll="false">
- <html:div id="PanelUI-whatsNew-message-container" role="document">
- <!-- What's New messages will be rendered here -->
- </html:div>
- </toolbaritem>
+ />
</vbox>
- <toolbarseparator/>
- <checkbox id="panelMenu-toggleWhatsNew"
- class="panelMenu-toggleWhatsNew-checkbox"
- onclick="ToolbarPanelHub.toggleWhatsNewPref(event)"
- data-l10n-id="whatsnew-panel-footer-checkbox"/>
</panelview>
<panelview id="reset-pbm-panel" class="PanelUI-subView" role="document">
@@ -795,15 +743,29 @@
<button id="reset-pbm-panel-cancel-button"
class="footer-button"
data-l10n-id="reset-pbm-panel-cancel-button"
- oncommand="ResetPBMPanel.onCancel(this)"></button>
+ ></button>
<button slot="primary"
id="reset-pbm-panel-confirm-button"
class="footer-button"
data-l10n-id="reset-pbm-panel-confirm-button"
- oncommand="ResetPBMPanel.onConfirm(this)"></button>
+ ></button>
</html:moz-button-group>
</vbox>
</panelview>
+ <panelview id="content-analysis-panel" class="PanelUI-subView" role="document" mainview-with-header="true">
+ <vbox id="content-analysis-panel-container" role="alertdialog" aria-labelledby="content-analysis-header">
+ <hbox class="panel-header">
+ <html:h1 id="content-analysis-header" data-l10n-id="content-analysis-panel-title"/>
+ </hbox>
+ <description id="content-analysis-panel-description">
+ <html:a is="moz-support-link"
+ data-l10n-name="info"
+ class="learnMore"
+ support-page="data-loss-prevention"/>
+ </description>
+ </vbox>
+ </panelview>
+
#include ../../components/reportbrokensite/content/reportBrokenSitePanel.inc.xhtml
</html:template>
diff --git a/browser/base/content/browser-a11yUtils.js b/browser/base/content/browser-a11yUtils.js
index 9bedb9238c..935ddc6a55 100644
--- a/browser/base/content/browser-a11yUtils.js
+++ b/browser/base/content/browser-a11yUtils.js
@@ -21,6 +21,7 @@ var A11yUtils = {
* can thus hinder rather than help users if used incorrectly.
* Please only use this after consultation with the Mozilla accessibility
* team.
+ * @param {object} [options]
* @param {string} [options.id] The Fluent id of the message to announce. The
* ftl file must already be included in browser.xhtml. This must be
* specified unless a raw message is specified instead.
@@ -28,13 +29,8 @@ var A11yUtils = {
* @param {string} [options.raw] The raw, already localized message to
* announce. You should generally prefer a Fluent id instead, but in
* rare cases, this might not be feasible.
- * @param {Element} [options.source] The element with which the announcement
- * is associated. This should generally be something the user can
- * interact with to respond to the announcement. For example, for an
- * announcement indicating that Reader View is available, this should
- * be the Reader View button on the toolbar.
*/
- async announce({ id = null, args = {}, raw = null, source = document } = {}) {
+ async announce({ id = null, args = {}, raw = null } = {}) {
if ((!id && !raw) || (id && raw)) {
throw new Error("One of raw or id must be specified.");
}
diff --git a/browser/base/content/browser-addons.js b/browser/base/content/browser-addons.js
index 6f50745e8d..e00952b2dc 100644
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -525,7 +525,7 @@ var gXPInstallObserver = {
Services.console.logMessage(consoleMsg);
},
- async observe(aSubject, aTopic, aData) {
+ async observe(aSubject, aTopic) {
var installInfo = aSubject.wrappedJSObject;
var browser = installInfo.browser;
@@ -618,7 +618,6 @@ var gXPInstallObserver = {
break;
}
case "addon-install-blocked": {
- await window.ensureCustomElements("moz-support-link");
// Dismiss the progress notification. Note that this is bad if
// there are multiple simultaneous installs happening, see
// bug 1329884 for a longer explanation.
@@ -914,9 +913,9 @@ var gXPInstallObserver = {
let height = undefined;
if (PopupNotifications.isPanelOpen) {
- let rect = document
- .getElementById("addon-progress-notification")
- .getBoundingClientRect();
+ let rect = window.windowUtils.getBoundsWithoutFlushing(
+ document.getElementById("addon-progress-notification")
+ );
height = rect.height;
}
@@ -1009,7 +1008,7 @@ var gExtensionsNotifications = {
let items = 0;
if (lazy.AMBrowserExtensionsImport.canCompleteOrCancelInstalls) {
- this._createAddonButton("webext-imported-addons", null, evt => {
+ this._createAddonButton("webext-imported-addons", null, () => {
lazy.AMBrowserExtensionsImport.completeInstalls();
});
items++;
@@ -1022,7 +1021,7 @@ var gExtensionsNotifications = {
this._createAddonButton(
"webext-perms-update-menu-item",
update.addon,
- evt => {
+ () => {
ExtensionsUI.showUpdate(gBrowser, update);
}
);
@@ -1032,7 +1031,7 @@ var gExtensionsNotifications = {
if (++items > 4) {
break;
}
- this._createAddonButton("webext-perms-sideload-menu-item", addon, evt => {
+ this._createAddonButton("webext-perms-sideload-menu-item", addon, () => {
// We need to hide the main menu manually because the toolbarbutton is
// removed immediately while processing this event, and PanelUI is
// unable to identify which panel should be closed automatically.
@@ -1046,16 +1045,11 @@ var gExtensionsNotifications = {
var BrowserAddonUI = {
async promptRemoveExtension(addon) {
let { name } = addon;
- let [title, btnTitle, message] = await lazy.l10n.formatValues([
+ let [title, btnTitle] = await lazy.l10n.formatValues([
{ id: "addon-removal-title", args: { name } },
{ id: "addon-removal-button" },
- { id: "addon-removal-message", args: { name } },
]);
- if (Services.prefs.getBoolPref("prompts.windowPromptSubDialog", false)) {
- message = null;
- }
-
let {
BUTTON_TITLE_IS_STRING: titleString,
BUTTON_TITLE_CANCEL: titleCancel,
@@ -1082,7 +1076,7 @@ var BrowserAddonUI = {
let result = confirmEx(
window,
title,
- message,
+ null,
btnFlags,
btnTitle,
/* button1 */ null,
@@ -1094,30 +1088,21 @@ var BrowserAddonUI = {
return { remove: result === 0, report: checkboxState.value };
},
- async reportAddon(addonId, reportEntryPoint) {
+ async reportAddon(addonId, _reportEntryPoint) {
let addon = addonId && (await AddonManager.getAddonByID(addonId));
if (!addon) {
return;
}
- // Do not open an additional about:addons tab if the abuse report should be
- // opened in its own tab.
- if (lazy.AbuseReporter.amoFormEnabled) {
- const amoUrl = lazy.AbuseReporter.getAMOFormURL({ addonId });
- window.openTrustedLinkIn(amoUrl, "tab", {
- // Make sure the newly open tab is going to be focused, independently
- // from general user prefs.
- forceForeground: true,
- });
- return;
- }
-
- const win = await BrowserOpenAddonsMgr("addons://list/extension");
-
- win.openAbuseReport({ addonId, reportEntryPoint });
+ const amoUrl = lazy.AbuseReporter.getAMOFormURL({ addonId });
+ window.openTrustedLinkIn(amoUrl, "tab", {
+ // Make sure the newly open tab is going to be focused, independently
+ // from general user prefs.
+ forceForeground: true,
+ });
},
- async removeAddon(addonId, eventObject) {
+ async removeAddon(addonId) {
let addon = addonId && (await AddonManager.getAddonByID(addonId));
if (!addon || !(addon.permissions & AddonManager.PERM_CAN_UNINSTALL)) {
return;
@@ -1136,13 +1121,91 @@ var BrowserAddonUI = {
}
},
- async manageAddon(addonId, eventObject) {
+ async manageAddon(addonId) {
let addon = addonId && (await AddonManager.getAddonByID(addonId));
if (!addon) {
return;
}
- BrowserOpenAddonsMgr("addons://detail/" + encodeURIComponent(addon.id));
+ this.openAddonsMgr("addons://detail/" + encodeURIComponent(addon.id));
+ },
+
+ /**
+ * Open about:addons page by given view id.
+ * @param {String} aView
+ * View id of page that will open.
+ * e.g. "addons://discover/"
+ * @param {Object} options
+ * {
+ * selectTabByViewId: If true, if there is the tab opening page having
+ * same view id, select the tab. Else if the current
+ * page is blank, load on it. Otherwise, open a new
+ * tab, then load on it.
+ * If false, if there is the tab opening
+ * about:addoons page, select the tab and load page
+ * for view id on it. Otherwise, leave the loading
+ * behavior to switchToTabHavingURI().
+ * If no options, handles as false.
+ * }
+ * @returns {Promise} When the Promise resolves, returns window object loaded the
+ * view id.
+ */
+ openAddonsMgr(aView, { selectTabByViewId = false } = {}) {
+ return new Promise(resolve => {
+ let emWindow;
+ let browserWindow;
+
+ const receivePong = function (aSubject) {
+ const browserWin = aSubject.browsingContext.topChromeWindow;
+ if (!emWindow || browserWin == window /* favor the current window */) {
+ if (
+ selectTabByViewId &&
+ aSubject.gViewController.currentViewId !== aView
+ ) {
+ return;
+ }
+
+ emWindow = aSubject;
+ browserWindow = browserWin;
+ }
+ };
+ Services.obs.addObserver(receivePong, "EM-pong");
+ Services.obs.notifyObservers(null, "EM-ping");
+ Services.obs.removeObserver(receivePong, "EM-pong");
+
+ if (emWindow) {
+ if (aView && !selectTabByViewId) {
+ emWindow.loadView(aView);
+ }
+ let tab = browserWindow.gBrowser.getTabForBrowser(
+ emWindow.docShell.chromeEventHandler
+ );
+ browserWindow.gBrowser.selectedTab = tab;
+ emWindow.focus();
+ resolve(emWindow);
+ return;
+ }
+
+ if (selectTabByViewId) {
+ const target = isBlankPageURL(gBrowser.currentURI.spec)
+ ? "current"
+ : "tab";
+ openTrustedLinkIn("about:addons", target);
+ } else {
+ // This must be a new load, else the ping/pong would have
+ // found the window above.
+ switchToTabHavingURI("about:addons", true);
+ }
+
+ Services.obs.addObserver(function observer(aSubject, aTopic) {
+ Services.obs.removeObserver(observer, aTopic);
+ if (aView) {
+ aSubject.loadView(aView);
+ }
+ aSubject.focus();
+ resolve(aSubject);
+ }, "EM-loaded");
+ });
},
};
@@ -1556,7 +1619,7 @@ var gUnifiedExtensions = {
} else {
viewID = "addons://list/extension";
}
- await BrowserOpenAddonsMgr(viewID);
+ await BrowserAddonUI.openAddonsMgr(viewID);
return;
}
}
@@ -1798,7 +1861,7 @@ var gUnifiedExtensions = {
}
},
- onWidgetAdded(aWidgetId, aArea, aPosition) {
+ onWidgetAdded(aWidgetId, aArea) {
// When we pin a widget to the toolbar from a narrow window, the widget
// will be overflowed directly. In this case, we do not want to change the
// class name since it is going to be changed by `onWidgetOverflow()`
@@ -1813,7 +1876,7 @@ var gUnifiedExtensions = {
this._updateWidgetClassName(aWidgetId, inPanel);
},
- onWidgetOverflow(aNode, aContainer) {
+ onWidgetOverflow(aNode) {
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
@@ -1823,7 +1886,7 @@ var gUnifiedExtensions = {
this._updateWidgetClassName(aNode.getAttribute("widget-id"), true);
},
- onWidgetUnderflow(aNode, aContainer) {
+ onWidgetUnderflow(aNode) {
// We register a CUI listener for each window so we make sure that we
// handle the event for the right window here.
if (window !== aNode.ownerGlobal) {
@@ -1882,8 +1945,6 @@ var gUnifiedExtensions = {
supportPage = null,
type = "warning",
}) {
- window.ensureCustomElements("moz-message-bar");
-
const messageBar = document.createElement("moz-message-bar");
messageBar.setAttribute("type", type);
messageBar.classList.add("unified-extensions-message-bar");
@@ -1891,8 +1952,6 @@ var gUnifiedExtensions = {
messageBar.setAttribute("data-l10n-attrs", "heading, message");
if (supportPage) {
- window.ensureCustomElements("moz-support-link");
-
const supportUrl = document.createElement("a", {
is: "moz-support-link",
});
diff --git a/browser/base/content/browser-allTabsMenu.inc.xhtml b/browser/base/content/browser-allTabsMenu.inc.xhtml
index 71d26288f7..1be6576605 100644
--- a/browser/base/content/browser-allTabsMenu.inc.xhtml
+++ b/browser/base/content/browser-allTabsMenu.inc.xhtml
@@ -9,6 +9,10 @@
class="subviewbutton"
oncommand="gTabsPanel.searchTabs();"
data-l10n-id="all-tabs-menu-search-tabs"/>
+ <toolbarbutton id="allTabsMenu-closeDuplicateTabs"
+ class="subviewbutton"
+ oncommand="gBrowser.removeAllDuplicateTabs();"
+ data-l10n-id="all-tabs-menu-close-duplicate-tabs"/>
<toolbarbutton id="allTabsMenu-containerTabsButton"
class="subviewbutton subviewbutton-nav"
closemenu="none"
diff --git a/browser/base/content/browser-allTabsMenu.js b/browser/base/content/browser-allTabsMenu.js
index f11d4da71d..f4b15bc9c3 100644
--- a/browser/base/content/browser-allTabsMenu.js
+++ b/browser/base/content/browser-allTabsMenu.js
@@ -6,6 +6,7 @@
/* eslint-env mozilla/browser-window */
ChromeUtils.defineESModuleGetters(this, {
+ BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.sys.mjs",
TabsPanel: "resource:///modules/TabsList.sys.mjs",
});
@@ -58,7 +59,7 @@ var gTabsPanel = {
dropIndicator: this.dropIndicator,
});
- this.allTabsView.addEventListener("ViewShowing", e => {
+ this.allTabsView.addEventListener("ViewShowing", () => {
PanelUI._ensureShortcutsShown(this.allTabsView);
let containersEnabled =
@@ -72,9 +73,19 @@ var gTabsPanel = {
!hasHiddenTabs;
document.getElementById("allTabsMenu-hiddenTabsSeparator").hidden =
!hasHiddenTabs;
+
+ let closeDuplicateEnabled = Services.prefs.getBoolPref(
+ "browser.tabs.context.close-duplicate.enabled"
+ );
+ let closeDuplicateTabsItem = document.getElementById(
+ "allTabsMenu-closeDuplicateTabs"
+ );
+ closeDuplicateTabsItem.hidden = !closeDuplicateEnabled;
+ closeDuplicateTabsItem.disabled =
+ !closeDuplicateEnabled || !gBrowser.getAllDuplicateTabsToClose().length;
});
- this.allTabsView.addEventListener("ViewShown", e =>
+ this.allTabsView.addEventListener("ViewShown", () =>
this.allTabsView
.querySelector(".all-tabs-item[selected]")
?.scrollIntoView({ block: "center" })
@@ -149,6 +160,10 @@ var gTabsPanel = {
entrypoint,
1
);
+ BrowserUsageTelemetry.recordInteractionEvent(
+ entrypoint,
+ "all-tabs-panel-entrypoint"
+ );
PanelUI.showSubView(
this.kElements.allTabsView,
this.allTabsButton,
@@ -170,7 +185,7 @@ var gTabsPanel = {
}
this.allTabsView.addEventListener(
"ViewShown",
- e => {
+ () => {
PanelUI.showSubView(
this.kElements.hiddenTabsView,
this.hiddenTabsButton
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
index d445abe7e7..b030891144 100644
--- a/browser/base/content/browser-box.inc.xhtml
+++ b/browser/base/content/browser-box.inc.xhtml
@@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
<hbox flex="1" id="browser">
+ <html:sidebar-main id="sidebar-main" flex="1" hidden="true"></html:sidebar-main>
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
<box id="sidebar-header" align="center">
<toolbarbutton id="sidebar-switcher-target" class="tabbable" aria-expanded="false">
@@ -12,7 +13,7 @@
</toolbarbutton>
<image id="sidebar-throbber"/>
<spacer id="sidebar-spacer"/>
- <toolbarbutton id="sidebar-close" class="close-icon tabbable" data-l10n-id="sidebar-close-button" oncommand="SidebarUI.hide();"/>
+ <toolbarbutton id="sidebar-close" class="close-icon tabbable" data-l10n-id="sidebar-close-button" oncommand="SidebarController.hide();"/>
</box>
<browser id="sidebar" autoscroll="false" disablehistory="true" disablefullscreen="true" tooltip="aHTMLTooltip"/>
</vbox>
diff --git a/browser/base/content/browser-captivePortal.js b/browser/base/content/browser-captivePortal.js
index 247f8c397f..1fd5497273 100644
--- a/browser/base/content/browser-captivePortal.js
+++ b/browser/base/content/browser-captivePortal.js
@@ -95,7 +95,7 @@ var CaptivePortalWatcher = {
}
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
switch (aTopic) {
case "captive-portal-login":
this._captivePortalDetected();
diff --git a/browser/base/content/browser-commands.js b/browser/base/content/browser-commands.js
new file mode 100644
index 0000000000..d80f9588cd
--- /dev/null
+++ b/browser/base/content/browser-commands.js
@@ -0,0 +1,591 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * 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/. */
+
+/* eslint-env mozilla/browser-window */
+
+"use strict";
+
+var kSkipCacheFlags =
+ Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY |
+ Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
+
+var BrowserCommands = {
+ back(aEvent) {
+ const where = BrowserUtils.whereToOpenLink(aEvent, false, true);
+
+ if (where == "current") {
+ try {
+ gBrowser.goBack();
+ } catch (ex) {}
+ } else {
+ duplicateTabIn(gBrowser.selectedTab, where, -1);
+ }
+ },
+
+ forward(aEvent) {
+ const where = BrowserUtils.whereToOpenLink(aEvent, false, true);
+
+ if (where == "current") {
+ try {
+ gBrowser.goForward();
+ } catch (ex) {}
+ } else {
+ duplicateTabIn(gBrowser.selectedTab, where, 1);
+ }
+ },
+
+ handleBackspace() {
+ switch (Services.prefs.getIntPref("browser.backspace_action")) {
+ case 0:
+ this.back();
+ break;
+ case 1:
+ goDoCommand("cmd_scrollPageUp");
+ break;
+ }
+ },
+
+ handleShiftBackspace() {
+ switch (Services.prefs.getIntPref("browser.backspace_action")) {
+ case 0:
+ this.forward();
+ break;
+ case 1:
+ goDoCommand("cmd_scrollPageDown");
+ break;
+ }
+ },
+
+ gotoHistoryIndex(aEvent) {
+ aEvent = BrowserUtils.getRootEvent(aEvent);
+
+ const index = aEvent.target.getAttribute("index");
+ if (!index) {
+ return false;
+ }
+
+ const where = BrowserUtils.whereToOpenLink(aEvent);
+
+ if (where == "current") {
+ // Normal click. Go there in the current tab and update session history.
+
+ try {
+ gBrowser.gotoIndex(index);
+ } catch (ex) {
+ return false;
+ }
+ return true;
+ }
+ // Modified click. Go there in a new tab/window.
+
+ const historyindex = aEvent.target.getAttribute("historyindex");
+ duplicateTabIn(gBrowser.selectedTab, where, Number(historyindex));
+ return true;
+ },
+
+ reloadOrDuplicate(aEvent) {
+ aEvent = BrowserUtils.getRootEvent(aEvent);
+ const accelKeyPressed =
+ AppConstants.platform == "macosx" ? aEvent.metaKey : aEvent.ctrlKey;
+ const backgroundTabModifier = aEvent.button == 1 || accelKeyPressed;
+
+ if (aEvent.shiftKey && !backgroundTabModifier) {
+ this.reloadSkipCache();
+ return;
+ }
+
+ const where = BrowserUtils.whereToOpenLink(aEvent, false, true);
+ if (where == "current") {
+ this.reload();
+ } else {
+ duplicateTabIn(gBrowser.selectedTab, where);
+ }
+ },
+
+ reload() {
+ if (gBrowser.currentURI.schemeIs("view-source")) {
+ // Bug 1167797: For view source, we always skip the cache
+ this.reloadSkipCache();
+ return;
+ }
+ this.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
+ },
+
+ reloadSkipCache() {
+ // Bypass proxy and cache.
+ this.reloadWithFlags(kSkipCacheFlags);
+ },
+
+ reloadWithFlags(reloadFlags) {
+ const unchangedRemoteness = [];
+
+ for (const tab of gBrowser.selectedTabs) {
+ const browser = tab.linkedBrowser;
+ const url = browser.currentURI;
+ const urlSpec = url.spec;
+ // We need to cache the content principal here because the browser will be
+ // reconstructed when the remoteness changes and the content prinicpal will
+ // be cleared after reconstruction.
+ const principal = tab.linkedBrowser.contentPrincipal;
+ if (gBrowser.updateBrowserRemotenessByURL(browser, urlSpec)) {
+ // If the remoteness has changed, the new browser doesn't have any
+ // information of what was loaded before, so we need to load the previous
+ // URL again.
+ if (tab.linkedPanel) {
+ loadBrowserURI(browser, url, principal);
+ } else {
+ // Shift to fully loaded browser and make
+ // sure load handler is instantiated.
+ tab.addEventListener(
+ "SSTabRestoring",
+ () => loadBrowserURI(browser, url, principal),
+ { once: true }
+ );
+ gBrowser._insertBrowser(tab);
+ }
+ } else {
+ unchangedRemoteness.push(tab);
+ }
+ }
+
+ if (!unchangedRemoteness.length) {
+ return;
+ }
+
+ // Reset temporary permissions on the remaining tabs to reload.
+ // This is done here because we only want to reset
+ // permissions on user reload.
+ for (const tab of unchangedRemoteness) {
+ SitePermissions.clearTemporaryBlockPermissions(tab.linkedBrowser);
+ // Also reset DOS mitigations for the basic auth prompt on reload.
+ delete tab.linkedBrowser.authPromptAbuseCounter;
+ }
+ gIdentityHandler.hidePopup();
+ gPermissionPanel.hidePopup();
+
+ const handlingUserInput = document.hasValidTransientUserGestureActivation;
+
+ for (const tab of unchangedRemoteness) {
+ if (tab.linkedPanel) {
+ sendReloadMessage(tab);
+ } else {
+ // Shift to fully loaded browser and make
+ // sure load handler is instantiated.
+ tab.addEventListener("SSTabRestoring", () => sendReloadMessage(tab), {
+ once: true,
+ });
+ gBrowser._insertBrowser(tab);
+ }
+ }
+
+ function loadBrowserURI(browser, url, principal) {
+ browser.loadURI(url, {
+ flags: reloadFlags,
+ triggeringPrincipal: principal,
+ });
+ }
+
+ function sendReloadMessage(tab) {
+ tab.linkedBrowser.sendMessageToActor(
+ "Browser:Reload",
+ { flags: reloadFlags, handlingUserInput },
+ "BrowserTab"
+ );
+ }
+ },
+
+ stop() {
+ gBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
+ },
+
+ home(aEvent) {
+ if (aEvent?.button == 2) {
+ // right-click: do nothing
+ return;
+ }
+
+ const homePage = HomePage.get(window);
+ let where = BrowserUtils.whereToOpenLink(aEvent, false, true);
+
+ // Don't load the home page in pinned or hidden tabs (e.g. Firefox View).
+ if (
+ where == "current" &&
+ (gBrowser?.selectedTab.pinned || gBrowser?.selectedTab.hidden)
+ ) {
+ where = "tab";
+ }
+
+ // openTrustedLinkIn in utilityOverlay.js doesn't handle loading multiple pages
+ let notifyObservers;
+ switch (where) {
+ case "current":
+ // If we're going to load an initial page in the current tab as the
+ // home page, we set initialPageLoadedFromURLBar so that the URL
+ // bar is cleared properly (even during a remoteness flip).
+ if (isInitialPage(homePage)) {
+ gBrowser.selectedBrowser.initialPageLoadedFromUserAction = homePage;
+ }
+ loadOneOrMoreURIs(
+ homePage,
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ null
+ );
+ if (isBlankPageURL(homePage)) {
+ gURLBar.select();
+ } else {
+ gBrowser.selectedBrowser.focus();
+ }
+ notifyObservers = true;
+ aEvent?.preventDefault();
+ break;
+ case "tabshifted":
+ case "tab": {
+ const urls = homePage.split("|");
+ const loadInBackground = Services.prefs.getBoolPref(
+ "browser.tabs.loadBookmarksInBackground",
+ false
+ );
+ // The homepage observer event should only be triggered when the homepage opens
+ // in the foreground. This is mostly to support the homepage changed by extension
+ // doorhanger which doesn't currently support background pages. This may change in
+ // bug 1438396.
+ notifyObservers = !loadInBackground;
+ gBrowser.loadTabs(urls, {
+ inBackground: loadInBackground,
+ triggeringPrincipal:
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ csp: null,
+ });
+ if (!loadInBackground) {
+ if (isBlankPageURL(homePage)) {
+ gURLBar.select();
+ } else {
+ gBrowser.selectedBrowser.focus();
+ }
+ }
+ aEvent?.preventDefault();
+ break;
+ }
+ case "window":
+ // OpenBrowserWindow will trigger the observer event, so no need to do so here.
+ notifyObservers = false;
+ OpenBrowserWindow();
+ aEvent?.preventDefault();
+ break;
+ }
+
+ if (notifyObservers) {
+ // A notification for when a user has triggered their homepage. This is used
+ // to display a doorhanger explaining that an extension has modified the
+ // homepage, if necessary. Observers are only notified if the homepage
+ // becomes the active page.
+ Services.obs.notifyObservers(null, "browser-open-homepage-start");
+ }
+ },
+
+ openTab({ event, url } = {}) {
+ let werePassedURL = !!url;
+ url ??= BROWSER_NEW_TAB_URL;
+ let searchClipboard =
+ gMiddleClickNewTabUsesPasteboard && event?.button == 1;
+
+ let relatedToCurrent = false;
+ let where = "tab";
+
+ if (event) {
+ where = BrowserUtils.whereToOpenLink(event, false, true);
+
+ switch (where) {
+ case "tab":
+ case "tabshifted":
+ // When accel-click or middle-click are used, open the new tab as
+ // related to the current tab.
+ relatedToCurrent = true;
+ break;
+ case "current":
+ where = "tab";
+ break;
+ }
+ }
+
+ // A notification intended to be useful for modular peformance tracking
+ // starting as close as is reasonably possible to the time when the user
+ // expressed the intent to open a new tab. Since there are a lot of
+ // entry points, this won't catch every single tab created, but most
+ // initiated by the user should go through here.
+ //
+ // Note 1: This notification gets notified with a promise that resolves
+ // with the linked browser when the tab gets created
+ // Note 2: This is also used to notify a user that an extension has changed
+ // the New Tab page.
+ Services.obs.notifyObservers(
+ {
+ wrappedJSObject: new Promise(resolve => {
+ let options = {
+ relatedToCurrent,
+ resolveOnNewTabCreated: resolve,
+ };
+ if (!werePassedURL && searchClipboard) {
+ let clipboard = readFromClipboard();
+ clipboard =
+ UrlbarUtils.stripUnsafeProtocolOnPaste(clipboard).trim();
+ if (clipboard) {
+ url = clipboard;
+ options.allowThirdPartyFixup = true;
+ }
+ }
+ openTrustedLinkIn(url, where, options);
+ }),
+ },
+ "browser-open-newtab-start"
+ );
+ },
+
+ openFileWindow() {
+ // Get filepicker component.
+ try {
+ const nsIFilePicker = Ci.nsIFilePicker;
+ const fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+ const fpCallback = function fpCallback_done(aResult) {
+ if (aResult == nsIFilePicker.returnOK) {
+ try {
+ if (fp.file) {
+ gLastOpenDirectory.path = fp.file.parent.QueryInterface(
+ Ci.nsIFile
+ );
+ }
+ } catch (ex) {}
+ openTrustedLinkIn(fp.fileURL.spec, "current");
+ }
+ };
+
+ fp.init(
+ window.browsingContext,
+ gNavigatorBundle.getString("openFile"),
+ nsIFilePicker.modeOpen
+ );
+ fp.appendFilters(
+ nsIFilePicker.filterAll |
+ nsIFilePicker.filterText |
+ nsIFilePicker.filterImages |
+ nsIFilePicker.filterXML |
+ nsIFilePicker.filterHTML |
+ nsIFilePicker.filterPDF
+ );
+ fp.displayDirectory = gLastOpenDirectory.path;
+ fp.open(fpCallback);
+ } catch (ex) {}
+ },
+
+ closeTabOrWindow(event) {
+ // If we're not a browser window, just close the window.
+ if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
+ closeWindow(true);
+ return;
+ }
+
+ // In a multi-select context, close all selected tabs
+ if (gBrowser.multiSelectedTabsCount) {
+ gBrowser.removeMultiSelectedTabs();
+ return;
+ }
+
+ // Keyboard shortcuts that would close a tab that is pinned select the first
+ // unpinned tab instead.
+ if (
+ event &&
+ (event.ctrlKey || event.metaKey || event.altKey) &&
+ gBrowser.selectedTab.pinned
+ ) {
+ if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
+ gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
+ }
+ return;
+ }
+
+ // If the current tab is the last one, this will close the window.
+ gBrowser.removeCurrentTab({ animate: true });
+ },
+
+ tryToCloseWindow(event) {
+ if (WindowIsClosing(event)) {
+ window.close();
+ } // WindowIsClosing does all the necessary checks
+ },
+
+ /**
+ * Open the View Source dialog.
+ *
+ * @param args
+ * An object with the following properties:
+ *
+ * URL (required):
+ * A string URL for the page we'd like to view the source of.
+ * browser (optional):
+ * The browser containing the document that we would like to view the
+ * source of. This is required if outerWindowID is passed.
+ * outerWindowID (optional):
+ * The outerWindowID of the content window containing the document that
+ * we want to view the source of. You only need to provide this if you
+ * want to attempt to retrieve the document source from the network
+ * cache.
+ * lineNumber (optional):
+ * The line number to focus on once the source is loaded.
+ */
+ async viewSourceOfDocument(args) {
+ // Check if external view source is enabled. If so, try it. If it fails,
+ // fallback to internal view source.
+ if (Services.prefs.getBoolPref("view_source.editor.external")) {
+ try {
+ await top.gViewSourceUtils.openInExternalEditor(args);
+ return;
+ } catch (data) {}
+ }
+
+ let tabBrowser = gBrowser;
+ let preferredRemoteType;
+ let initialBrowsingContextGroupId;
+ if (args.browser) {
+ preferredRemoteType = args.browser.remoteType;
+ initialBrowsingContextGroupId = args.browser.browsingContext.group.id;
+ } else {
+ if (!tabBrowser) {
+ throw new Error(
+ "viewSourceOfDocument should be passed the " +
+ "subject browser if called from a window without " +
+ "gBrowser defined."
+ );
+ }
+ // Some internal URLs (such as specific chrome: and about: URLs that are
+ // not yet remote ready) cannot be loaded in a remote browser. View
+ // source in tab expects the new view source browser's remoteness to match
+ // that of the original URL, so disable remoteness if necessary for this
+ // URL.
+ const oa = E10SUtils.predictOriginAttributes({ window });
+ preferredRemoteType = E10SUtils.getRemoteTypeForURI(
+ args.URL,
+ gMultiProcessBrowser,
+ gFissionBrowser,
+ E10SUtils.DEFAULT_REMOTE_TYPE,
+ null,
+ oa
+ );
+ }
+
+ // In the case of popups, we need to find a non-popup browser window.
+ if (!tabBrowser || !window.toolbar.visible) {
+ // This returns only non-popup browser windows by default.
+ const browserWindow = BrowserWindowTracker.getTopWindow();
+ tabBrowser = browserWindow.gBrowser;
+ }
+
+ const inNewWindow = !Services.prefs.getBoolPref("view_source.tab");
+
+ // `viewSourceInBrowser` will load the source content from the page
+ // descriptor for the tab (when possible) or fallback to the network if
+ // that fails. Either way, the view source module will manage the tab's
+ // location, so use "about:blank" here to avoid unnecessary redundant
+ // requests.
+ const tab = tabBrowser.addTab("about:blank", {
+ relatedToCurrent: true,
+ inBackground: inNewWindow,
+ skipAnimation: inNewWindow,
+ preferredRemoteType,
+ initialBrowsingContextGroupId,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ skipLoad: true,
+ });
+ args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
+ top.gViewSourceUtils.viewSourceInBrowser(args);
+
+ if (inNewWindow) {
+ tabBrowser.hideTab(tab);
+ tabBrowser.replaceTabWithWindow(tab);
+ }
+ },
+
+ /**
+ * Opens the View Source dialog for the source loaded in the root
+ * top-level document of the browser. This is really just a
+ * convenience wrapper around viewSourceOfDocument.
+ *
+ * @param browser
+ * The browser that we want to load the source of.
+ */
+ viewSource(browser) {
+ this.viewSourceOfDocument({
+ browser,
+ outerWindowID: browser.outerWindowID,
+ URL: browser.currentURI.spec,
+ });
+ },
+
+ /**
+ * @param documentURL URL of the document to view, or null for this window's document
+ * @param initialTab name of the initial tab to display, or null for the first tab
+ * @param imageElement image to load in the Media Tab of the Page Info window; can be null/omitted
+ * @param browsingContext the browsingContext of the frame that we want to view information about; can be null/omitted
+ * @param browser the browser containing the document we're interested in inspecting; can be null/omitted
+ */
+ pageInfo(documentURL, initialTab, imageElement, browsingContext, browser) {
+ const args = { initialTab, imageElement, browsingContext, browser };
+
+ documentURL =
+ documentURL || window.gBrowser.selectedBrowser.currentURI.spec;
+
+ const isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
+
+ // Check for windows matching the url
+ for (const currentWindow of Services.wm.getEnumerator(
+ "Browser:page-info"
+ )) {
+ if (currentWindow.closed) {
+ continue;
+ }
+ if (
+ currentWindow.document.documentElement.getAttribute("relatedUrl") ==
+ documentURL &&
+ PrivateBrowsingUtils.isWindowPrivate(currentWindow) == isPrivate
+ ) {
+ currentWindow.focus();
+ currentWindow.resetPageInfo(args);
+ return currentWindow;
+ }
+ }
+
+ // We didn't find a matching window, so open a new one.
+ let options = "chrome,toolbar,dialog=no,resizable";
+
+ // Ensure the window groups correctly in the Windows taskbar
+ if (isPrivate) {
+ options += ",private";
+ }
+ return openDialog(
+ "chrome://browser/content/pageinfo/pageInfo.xhtml",
+ "",
+ options,
+ args
+ );
+ },
+
+ fullScreen() {
+ window.fullScreen = !window.fullScreen || BrowserHandler.kiosk;
+ },
+
+ downloadsUI() {
+ if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+ openTrustedLinkIn("about:downloads", "tab");
+ } else {
+ PlacesCommandHook.showPlacesOrganizer("Downloads");
+ }
+ },
+
+ forceEncodingDetection() {
+ gBrowser.selectedBrowser.forceEncodingDetection();
+ BrowserCommands.reloadWithFlags(
+ Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE
+ );
+ },
+};
diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc
index ff4015e3d4..3ce284a52f 100644
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -439,7 +439,7 @@
oncommand="gContextMenu.viewPartialSource();"/>
<menuitem id="context-viewsource"
data-l10n-id="main-context-menu-view-page-source"
- oncommand="BrowserViewSource(gContextMenu.browser);"/>
+ oncommand="BrowserCommands.viewSource(gContextMenu.browser);"/>
<menuitem id="context-inspect-a11y"
hidden="true"
data-l10n-id="main-context-menu-inspect-a11y-properties"
diff --git a/browser/base/content/browser-ctrlTab.js b/browser/base/content/browser-ctrlTab.js
index d4d79a6886..e5d16e605b 100644
--- a/browser/base/content/browser-ctrlTab.js
+++ b/browser/base/content/browser-ctrlTab.js
@@ -284,7 +284,7 @@ var ctrlTab = {
this.uninit();
}
},
- observe(aSubject, aTopic, aPrefName) {
+ observe() {
this.readPref();
},
@@ -654,7 +654,7 @@ var ctrlTab = {
// tab attribute modified (i.e. label, busy, image)
// update preview only if tab attribute modified in the list
if (
- event.detail.changed.some((elem, ind, arr) =>
+ event.detail.changed.some(elem =>
["label", "busy", "image"].includes(elem)
)
) {
diff --git a/browser/base/content/browser-data-submission-info-bar.js b/browser/base/content/browser-data-submission-info-bar.js
index 26d9affb29..104414d582 100644
--- a/browser/base/content/browser-data-submission-info-bar.js
+++ b/browser/base/content/browser-data-submission-info-bar.js
@@ -92,7 +92,7 @@ var gDataNotificationInfoBar = {
}
},
- observe(subject, topic, data) {
+ observe(subject, topic) {
switch (topic) {
case "datareporting:notify-data-policy:request":
let request = subject.wrappedJSObject.object;
diff --git a/browser/base/content/browser-fullScreenAndPointerLock.js b/browser/base/content/browser-fullScreenAndPointerLock.js
index aae596a0f7..c8794c760c 100644
--- a/browser/base/content/browser-fullScreenAndPointerLock.js
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -365,26 +365,19 @@ var FullScreen = {
passive: true,
});
- if (enterFS) {
- gNavToolbox.setAttribute("inFullscreen", true);
- document.documentElement.setAttribute("inFullscreen", true);
- let alwaysUsesNativeFullscreen =
+ document.documentElement.toggleAttribute("inFullscreen", enterFS);
+ document.documentElement.toggleAttribute(
+ "macOSNativeFullscreen",
+ enterFS &&
AppConstants.platform == "macosx" &&
- Services.prefs.getBoolPref("full-screen-api.macos-native-full-screen");
- if (
- (alwaysUsesNativeFullscreen || !document.fullscreenElement) &&
- AppConstants.platform == "macosx"
- ) {
- document.documentElement.setAttribute("macOSNativeFullscreen", true);
- }
- } else {
- gNavToolbox.removeAttribute("inFullscreen");
- document.documentElement.removeAttribute("inFullscreen");
- document.documentElement.removeAttribute("macOSNativeFullscreen");
- }
+ (Services.prefs.getBoolPref(
+ "full-screen-api.macos-native-full-screen"
+ ) ||
+ !document.fullscreenElement)
+ );
if (!document.fullscreenElement) {
- this._updateToolbars(enterFS);
+ ToolbarIconColor.inferFromText("fullscreen", enterFS);
}
if (enterFS) {
@@ -948,22 +941,6 @@ var FullScreen = {
MousePosTracker.removeListener(this);
},
-
- _updateToolbars(aEnterFS) {
- for (let el of document.querySelectorAll(
- "toolbar[fullscreentoolbar=true]"
- )) {
- // Set the inFullscreen attribute to allow specific styling
- // in fullscreen mode
- if (aEnterFS) {
- el.setAttribute("inFullscreen", true);
- } else {
- el.removeAttribute("inFullscreen");
- }
- }
-
- ToolbarIconColor.inferFromText("fullscreen", aEnterFS);
- },
};
ChromeUtils.defineLazyGetter(FullScreen, "_permissionNotificationIDs", () => {
diff --git a/browser/base/content/browser-gestureSupport.js b/browser/base/content/browser-gestureSupport.js
index 0ff42f5160..6bec059789 100644
--- a/browser/base/content/browser-gestureSupport.js
+++ b/browser/base/content/browser-gestureSupport.js
@@ -269,7 +269,7 @@ var gGestureSupport = {
gHistorySwipeAnimation.updateAnimation(aEvent.delta);
};
- this._doEnd = function GS__doEnd(aEvent) {
+ this._doEnd = function GS__doEnd() {
gHistorySwipeAnimation.swipeEndEventReceived();
this._doUpdate = function () {};
@@ -393,7 +393,7 @@ var gGestureSupport = {
* @param aEvent
* The continual motion update event to handle
*/
- _doUpdate(aEvent) {},
+ _doUpdate() {},
/**
* Handle gesture end events. This function will be set by _setupSwipe.
@@ -401,7 +401,7 @@ var gGestureSupport = {
* @param aEvent
* The gesture end event to handle
*/
- _doEnd(aEvent) {},
+ _doEnd() {},
/**
* Convert the swipe gesture into a browser action based on the direction.
@@ -874,7 +874,7 @@ var gHistorySwipeAnimation = {
}
},
- _completeFadeOut: function HSA__completeFadeOut(aEvent) {
+ _completeFadeOut: function HSA__completeFadeOut() {
if (!this._isStoppingAnimation) {
// The animation was restarted in the middle of our stopping fade out
// tranistion, so don't do anything.
@@ -943,7 +943,7 @@ var gHistorySwipeAnimation = {
return element;
},
- observe(subj, topic, data) {
+ observe(subj, topic) {
switch (topic) {
case "nsPref:changed":
this._initPrefValues();
diff --git a/browser/base/content/browser-init.js b/browser/base/content/browser-init.js
new file mode 100644
index 0000000000..0717ce2138
--- /dev/null
+++ b/browser/base/content/browser-init.js
@@ -0,0 +1,1107 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * 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/. */
+
+let _resolveDelayedStartup;
+var delayedStartupPromise = new Promise(resolve => {
+ _resolveDelayedStartup = resolve;
+});
+
+var gBrowserInit = {
+ delayedStartupFinished: false,
+ domContentLoaded: false,
+
+ _tabToAdopt: undefined,
+ _firstContentWindowPaintDeferred: Promise.withResolvers(),
+ idleTasksFinished: Promise.withResolvers(),
+
+ _setupFirstContentWindowPaintPromise() {
+ let lastTransactionId = window.windowUtils.lastTransactionId;
+ let layerTreeListener = () => {
+ if (this.getTabToAdopt()) {
+ // Need to wait until we finish adopting the tab, or we might end
+ // up focusing the initial browser and then losing focus when it
+ // gets swapped out for the tab to adopt.
+ return;
+ }
+ removeEventListener("MozLayerTreeReady", layerTreeListener);
+ let listener = e => {
+ if (e.transactionId > lastTransactionId) {
+ window.removeEventListener("MozAfterPaint", listener);
+ this._firstContentWindowPaintDeferred.resolve();
+ }
+ };
+ addEventListener("MozAfterPaint", listener);
+ };
+ addEventListener("MozLayerTreeReady", layerTreeListener);
+ },
+
+ getTabToAdopt() {
+ if (this._tabToAdopt !== undefined) {
+ return this._tabToAdopt;
+ }
+
+ if (window.arguments && window.XULElement.isInstance(window.arguments[0])) {
+ this._tabToAdopt = window.arguments[0];
+
+ // Clear the reference of the tab being adopted from the arguments.
+ window.arguments[0] = null;
+ } else {
+ // There was no tab to adopt in the arguments, set _tabToAdopt to null
+ // to avoid checking it again.
+ this._tabToAdopt = null;
+ }
+
+ return this._tabToAdopt;
+ },
+
+ _clearTabToAdopt() {
+ this._tabToAdopt = null;
+ },
+
+ // Used to check if the new window is still adopting an existing tab as its first tab
+ // (e.g. from the WebExtensions internals).
+ isAdoptingTab() {
+ return !!this.getTabToAdopt();
+ },
+
+ onBeforeInitialXULLayout() {
+ this._setupFirstContentWindowPaintPromise();
+
+ updateBookmarkToolbarVisibility();
+
+ // Set a sane starting width/height for all resolutions on new profiles.
+ if (ChromeUtils.shouldResistFingerprinting("RoundWindowSize", null)) {
+ // When the fingerprinting resistance is enabled, making sure that we don't
+ // have a maximum window to interfere with generating rounded window dimensions.
+ document.documentElement.setAttribute("sizemode", "normal");
+ } else if (!document.documentElement.hasAttribute("width")) {
+ const TARGET_WIDTH = 1280;
+ const TARGET_HEIGHT = 1040;
+ let width = Math.min(screen.availWidth * 0.9, TARGET_WIDTH);
+ let height = Math.min(screen.availHeight * 0.9, TARGET_HEIGHT);
+
+ document.documentElement.setAttribute("width", width);
+ document.documentElement.setAttribute("height", height);
+
+ if (width < TARGET_WIDTH && height < TARGET_HEIGHT) {
+ document.documentElement.setAttribute("sizemode", "maximized");
+ }
+ }
+ if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
+ const toolbarMenubar = document.getElementById("toolbar-menubar");
+ // set a default value
+ if (!toolbarMenubar.hasAttribute("autohide")) {
+ toolbarMenubar.setAttribute("autohide", true);
+ }
+ document.l10n.setAttributes(
+ toolbarMenubar,
+ "toolbar-context-menu-menu-bar-cmd"
+ );
+ toolbarMenubar.setAttribute("data-l10n-attrs", "toolbarname");
+ }
+
+ // Run menubar initialization first, to avoid TabsInTitlebar code picking
+ // up mutations from it and causing a reflow.
+ AutoHideMenubar.init();
+ // Update the chromemargin attribute so the window can be sized correctly.
+ window.TabBarVisibility.update();
+ TabsInTitlebar.init();
+
+ new LightweightThemeConsumer(document);
+
+ if (
+ Services.prefs.getBoolPref(
+ "toolkit.legacyUserProfileCustomizations.windowIcon",
+ false
+ )
+ ) {
+ document.documentElement.setAttribute("icon", "main-window");
+ }
+
+ // Call this after we set attributes that might change toolbars' computed
+ // text color.
+ ToolbarIconColor.init();
+ },
+
+ onDOMContentLoaded() {
+ // This needs setting up before we create the first remote browser.
+ window.docShell.treeOwner
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIAppWindow).XULBrowserWindow = window.XULBrowserWindow;
+ window.browserDOMWindow = new nsBrowserAccess();
+
+ gBrowser = window._gBrowser;
+ delete window._gBrowser;
+ gBrowser.init();
+
+ BrowserWindowTracker.track(window);
+
+ FirefoxViewHandler.init();
+
+ gNavToolbox.palette = document.getElementById(
+ "BrowserToolbarPalette"
+ ).content;
+ for (let area of CustomizableUI.areas) {
+ let type = CustomizableUI.getAreaType(area);
+ if (type == CustomizableUI.TYPE_TOOLBAR) {
+ let node = document.getElementById(area);
+ CustomizableUI.registerToolbarNode(node);
+ }
+ }
+ BrowserSearch.initPlaceHolder();
+
+ // Hack to ensure that the various initial pages favicon is loaded
+ // instantaneously, to avoid flickering and improve perceived performance.
+ this._callWithURIToLoad(uriToLoad => {
+ let url;
+ try {
+ url = Services.io.newURI(uriToLoad);
+ } catch (e) {
+ return;
+ }
+ let nonQuery = url.prePath + url.filePath;
+ if (nonQuery in gPageIcons) {
+ gBrowser.setIcon(gBrowser.selectedTab, gPageIcons[nonQuery]);
+ }
+ });
+
+ updateFxaToolbarMenu(gFxaToolbarEnabled, true);
+
+ updatePrintCommands(gPrintEnabled);
+
+ gUnifiedExtensions.init();
+
+ // Setting the focus will cause a style flush, it's preferable to call anything
+ // that will modify the DOM from within this function before this call.
+ this._setInitialFocus();
+
+ this.domContentLoaded = true;
+ },
+
+ onLoad() {
+ gBrowser.addEventListener("DOMUpdateBlockedPopups", gPopupBlockerObserver);
+ gBrowser.addEventListener(
+ "TranslationsParent:LanguageState",
+ FullPageTranslationsPanel
+ );
+ gBrowser.addEventListener(
+ "TranslationsParent:OfferTranslation",
+ FullPageTranslationsPanel
+ );
+ gBrowser.addTabsProgressListener(FullPageTranslationsPanel);
+
+ window.addEventListener("AppCommand", HandleAppCommandEvent, true);
+
+ // These routines add message listeners. They must run before
+ // loading the frame script to ensure that we don't miss any
+ // message sent between when the frame script is loaded and when
+ // the listener is registered.
+ CaptivePortalWatcher.init();
+ ZoomUI.init(window);
+
+ if (!gMultiProcessBrowser) {
+ // There is a Content:Click message manually sent from content.
+ gBrowser.tabpanels.addEventListener("click", contentAreaClick, {
+ capture: true,
+ mozSystemGroup: true,
+ });
+ }
+
+ // hook up UI through progress listener
+ gBrowser.addProgressListener(window.XULBrowserWindow);
+ gBrowser.addTabsProgressListener(window.TabsProgressListener);
+
+ SidebarController.init();
+
+ // We do this in onload because we want to ensure the button's state
+ // doesn't flicker as the window is being shown.
+ DownloadsButton.init();
+
+ // Certain kinds of automigration rely on this notification to complete
+ // their tasks BEFORE the browser window is shown. SessionStore uses it to
+ // restore tabs into windows AFTER important parts like gMultiProcessBrowser
+ // have been initialized.
+ Services.obs.notifyObservers(window, "browser-window-before-show");
+
+ if (!window.toolbar.visible) {
+ // adjust browser UI for popups
+ gURLBar.readOnly = true;
+ }
+
+ // Misc. inits.
+ gUIDensity.init();
+ TabletModeUpdater.init();
+ CombinedStopReload.ensureInitialized();
+ gPrivateBrowsingUI.init();
+ BrowserSearch.init();
+ BrowserPageActions.init();
+ if (gToolbarKeyNavEnabled) {
+ ToolbarKeyboardNavigator.init();
+ }
+
+ // Update UI if browser is under remote control.
+ gRemoteControl.updateVisualCue();
+
+ // If we are given a tab to swap in, take care of it before first paint to
+ // avoid an about:blank flash.
+ let tabToAdopt = this.getTabToAdopt();
+ if (tabToAdopt) {
+ let evt = new CustomEvent("before-initial-tab-adopted", {
+ bubbles: true,
+ });
+ gBrowser.tabpanels.dispatchEvent(evt);
+
+ // Stop the about:blank load
+ gBrowser.stop();
+
+ // Remove the speculative focus from the urlbar to let the url be formatted.
+ gURLBar.removeAttribute("focused");
+
+ let swapBrowsers = () => {
+ try {
+ gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToAdopt);
+ } catch (e) {
+ console.error(e);
+ }
+
+ // Clear the reference to the tab once its adoption has been completed.
+ this._clearTabToAdopt();
+ };
+ if (tabToAdopt.linkedBrowser.isRemoteBrowser) {
+ // For remote browsers, wait for the paint event, otherwise the tabs
+ // are not yet ready and focus gets confused because the browser swaps
+ // out while tabs are switching.
+ addEventListener("MozAfterPaint", swapBrowsers, { once: true });
+ } else {
+ swapBrowsers();
+ }
+ }
+
+ // Wait until chrome is painted before executing code not critical to making the window visible
+ this._boundDelayedStartup = this._delayedStartup.bind(this);
+ window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
+
+ if (!PrivateBrowsingUtils.enabled) {
+ document.getElementById("Tools:PrivateBrowsing").hidden = true;
+ // Setting disabled doesn't disable the shortcut, so we just remove
+ // the keybinding.
+ document.getElementById("key_privatebrowsing").remove();
+ }
+
+ if (BrowserUIUtils.quitShortcutDisabled) {
+ document.getElementById("key_quitApplication").remove();
+ document.getElementById("menu_FileQuitItem").removeAttribute("key");
+
+ PanelMultiView.getViewNode(
+ document,
+ "appMenu-quit-button2"
+ )?.removeAttribute("key");
+ }
+
+ this._loadHandled = true;
+ },
+
+ _cancelDelayedStartup() {
+ window.removeEventListener("MozAfterPaint", this._boundDelayedStartup);
+ this._boundDelayedStartup = null;
+ },
+
+ _delayedStartup() {
+ let { TelemetryTimestamps } = ChromeUtils.importESModule(
+ "resource://gre/modules/TelemetryTimestamps.sys.mjs"
+ );
+ TelemetryTimestamps.add("delayedStartupStarted");
+
+ this._cancelDelayedStartup();
+
+ // Bug 1531854 - The hidden window is force-created here
+ // until all of its dependencies are handled.
+ Services.appShell.hiddenDOMWindow;
+
+ gBrowser.addEventListener(
+ "PermissionStateChange",
+ function () {
+ gIdentityHandler.refreshIdentityBlock();
+ gPermissionPanel.updateSharingIndicator();
+ },
+ true
+ );
+
+ this._handleURIToLoad();
+
+ Services.obs.addObserver(gIdentityHandler, "perm-changed");
+ Services.obs.addObserver(gRemoteControl, "devtools-socket");
+ Services.obs.addObserver(gRemoteControl, "marionette-listening");
+ Services.obs.addObserver(gRemoteControl, "remote-listening");
+ Services.obs.addObserver(
+ gSessionHistoryObserver,
+ "browser:purge-session-history"
+ );
+ Services.obs.addObserver(
+ gStoragePressureObserver,
+ "QuotaManager::StoragePressure"
+ );
+ Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled");
+ Services.obs.addObserver(gXPInstallObserver, "addon-install-started");
+ Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked");
+ Services.obs.addObserver(
+ gXPInstallObserver,
+ "addon-install-fullscreen-blocked"
+ );
+ Services.obs.addObserver(
+ gXPInstallObserver,
+ "addon-install-origin-blocked"
+ );
+ Services.obs.addObserver(
+ gXPInstallObserver,
+ "addon-install-policy-blocked"
+ );
+ Services.obs.addObserver(
+ gXPInstallObserver,
+ "addon-install-webapi-blocked"
+ );
+ Services.obs.addObserver(gXPInstallObserver, "addon-install-failed");
+ Services.obs.addObserver(gXPInstallObserver, "addon-install-confirmation");
+ Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup");
+
+ BrowserOffline.init();
+ CanvasPermissionPromptHelper.init();
+ WebAuthnPromptHelper.init();
+ ContentAnalysis.initialize(document);
+
+ // Initialize the full zoom setting.
+ // We do this before the session restore service gets initialized so we can
+ // apply full zoom settings to tabs restored by the session restore service.
+ FullZoom.init();
+ PanelUI.init(shouldSuppressPopupNotifications);
+ ReportBrokenSite.init(gBrowser);
+
+ UpdateUrlbarSearchSplitterState();
+
+ BookmarkingUI.init();
+ BrowserSearch.delayedStartupInit();
+ SearchUIUtils.init();
+ gProtectionsHandler.init();
+ HomePage.delayedStartup().catch(console.error);
+
+ let safeMode = document.getElementById("helpSafeMode");
+ if (Services.appinfo.inSafeMode) {
+ document.l10n.setAttributes(safeMode, "menu-help-exit-troubleshoot-mode");
+ safeMode.setAttribute(
+ "appmenu-data-l10n-id",
+ "appmenu-help-exit-troubleshoot-mode"
+ );
+ }
+
+ // BiDi UI
+ gBidiUI = isBidiEnabled();
+ if (gBidiUI) {
+ document.getElementById("documentDirection-separator").hidden = false;
+ document.getElementById("documentDirection-swap").hidden = false;
+ document.getElementById("textfieldDirection-separator").hidden = false;
+ document.getElementById("textfieldDirection-swap").hidden = false;
+ }
+
+ // Setup click-and-hold gestures access to the session history
+ // menus if global click-and-hold isn't turned on
+ if (!Services.prefs.getBoolPref("ui.click_hold_context_menus", false)) {
+ SetClickAndHoldHandlers();
+ }
+
+ function initBackForwardButtonTooltip(tooltipId, l10nId, shortcutId) {
+ let shortcut = document.getElementById(shortcutId);
+ shortcut = ShortcutUtils.prettifyShortcut(shortcut);
+
+ let tooltip = document.getElementById(tooltipId);
+ document.l10n.setAttributes(tooltip, l10nId, { shortcut });
+ }
+
+ initBackForwardButtonTooltip(
+ "back-button-tooltip-description",
+ "navbar-tooltip-back-2",
+ "goBackKb"
+ );
+
+ initBackForwardButtonTooltip(
+ "forward-button-tooltip-description",
+ "navbar-tooltip-forward-2",
+ "goForwardKb"
+ );
+
+ PlacesToolbarHelper.init();
+
+ ctrlTab.readPref();
+ Services.prefs.addObserver(ctrlTab.prefName, ctrlTab);
+
+ // The object handling the downloads indicator is initialized here in the
+ // delayed startup function, but the actual indicator element is not loaded
+ // unless there are downloads to be displayed.
+ DownloadsButton.initializeIndicator();
+
+ if (AppConstants.platform != "macosx") {
+ updateEditUIVisibility();
+ let placesContext = document.getElementById("placesContext");
+ placesContext.addEventListener("popupshowing", updateEditUIVisibility);
+ placesContext.addEventListener("popuphiding", updateEditUIVisibility);
+ }
+
+ FullScreen.init();
+ MenuTouchModeObserver.init();
+
+ if (AppConstants.MOZ_DATA_REPORTING) {
+ gDataNotificationInfoBar.init();
+ }
+
+ if (!AppConstants.MOZILLA_OFFICIAL) {
+ DevelopmentHelpers.init();
+ }
+
+ gExtensionsNotifications.init();
+
+ let wasMinimized = window.windowState == window.STATE_MINIMIZED;
+ window.addEventListener("sizemodechange", () => {
+ let isMinimized = window.windowState == window.STATE_MINIMIZED;
+ if (wasMinimized != isMinimized) {
+ wasMinimized = isMinimized;
+ UpdatePopupNotificationsVisibility();
+ }
+ });
+
+ window.addEventListener("mousemove", MousePosTracker);
+ window.addEventListener("dragover", MousePosTracker);
+
+ gNavToolbox.addEventListener("customizationstarting", CustomizationHandler);
+ gNavToolbox.addEventListener("aftercustomization", CustomizationHandler);
+
+ SessionStore.promiseInitialized.then(() => {
+ // Bail out if the window has been closed in the meantime.
+ if (window.closed) {
+ return;
+ }
+
+ // Enable the Restore Last Session command if needed
+ RestoreLastSessionObserver.init();
+
+ SidebarController.startDelayedLoad();
+
+ PanicButtonNotifier.init();
+ });
+
+ if (BrowserHandler.kiosk) {
+ // We don't modify popup windows for kiosk mode
+ if (!gURLBar.readOnly) {
+ window.fullScreen = true;
+ }
+ }
+
+ if (Services.policies.status === Services.policies.ACTIVE) {
+ if (!Services.policies.isAllowed("hideShowMenuBar")) {
+ document
+ .getElementById("toolbar-menubar")
+ .removeAttribute("toolbarname");
+ }
+ if (!Services.policies.isAllowed("filepickers")) {
+ let savePageCommand = document.getElementById("Browser:SavePage");
+ let openFileCommand = document.getElementById("Browser:OpenFile");
+
+ savePageCommand.setAttribute("disabled", "true");
+ openFileCommand.setAttribute("disabled", "true");
+
+ document.addEventListener("FilePickerBlocked", function (event) {
+ let browser = event.target;
+
+ let notificationBox = browser
+ .getTabBrowser()
+ ?.getNotificationBox(browser);
+
+ // Prevent duplicate notifications
+ if (
+ notificationBox &&
+ !notificationBox.getNotificationWithValue("filepicker-blocked")
+ ) {
+ notificationBox.appendNotification("filepicker-blocked", {
+ label: {
+ "l10n-id": "filepicker-blocked-infobar",
+ },
+ priority: notificationBox.PRIORITY_INFO_LOW,
+ });
+ }
+ });
+ }
+ let policies = Services.policies.getActivePolicies();
+ if ("ManagedBookmarks" in policies) {
+ let managedBookmarks = policies.ManagedBookmarks;
+ let children = managedBookmarks.filter(
+ child => !("toplevel_name" in child)
+ );
+ if (children.length) {
+ let managedBookmarksButton =
+ document.createXULElement("toolbarbutton");
+ managedBookmarksButton.setAttribute("id", "managed-bookmarks");
+ managedBookmarksButton.setAttribute("class", "bookmark-item");
+ let toplevel = managedBookmarks.find(
+ element => "toplevel_name" in element
+ );
+ if (toplevel) {
+ managedBookmarksButton.setAttribute(
+ "label",
+ toplevel.toplevel_name
+ );
+ } else {
+ document.l10n.setAttributes(
+ managedBookmarksButton,
+ "managed-bookmarks"
+ );
+ }
+ managedBookmarksButton.setAttribute("context", "placesContext");
+ managedBookmarksButton.setAttribute("container", "true");
+ managedBookmarksButton.setAttribute("removable", "false");
+ managedBookmarksButton.setAttribute("type", "menu");
+
+ let managedBookmarksPopup = document.createXULElement("menupopup");
+ managedBookmarksPopup.setAttribute("id", "managed-bookmarks-popup");
+ managedBookmarksPopup.setAttribute(
+ "oncommand",
+ "PlacesToolbarHelper.openManagedBookmark(event);"
+ );
+ managedBookmarksPopup.setAttribute(
+ "ondragover",
+ "event.dataTransfer.effectAllowed='none';"
+ );
+ managedBookmarksPopup.setAttribute(
+ "ondragstart",
+ "PlacesToolbarHelper.onDragStartManaged(event);"
+ );
+ managedBookmarksPopup.setAttribute(
+ "onpopupshowing",
+ "PlacesToolbarHelper.populateManagedBookmarks(this);"
+ );
+ managedBookmarksPopup.setAttribute("placespopup", "true");
+ managedBookmarksPopup.setAttribute("is", "places-popup");
+ managedBookmarksPopup.classList.add("toolbar-menupopup");
+ managedBookmarksButton.appendChild(managedBookmarksPopup);
+
+ gNavToolbox.palette.appendChild(managedBookmarksButton);
+
+ CustomizableUI.ensureWidgetPlacedInWindow(
+ "managed-bookmarks",
+ window
+ );
+
+ // Add button if it doesn't exist
+ if (!CustomizableUI.getPlacementOfWidget("managed-bookmarks")) {
+ CustomizableUI.addWidgetToArea(
+ "managed-bookmarks",
+ CustomizableUI.AREA_BOOKMARKS,
+ 0
+ );
+ }
+ }
+ }
+ }
+
+ CaptivePortalWatcher.delayedStartup();
+
+ ShoppingSidebarManager.ensureInitialized();
+
+ SessionStore.promiseAllWindowsRestored.then(() => {
+ this._schedulePerWindowIdleTasks();
+ document.documentElement.setAttribute("sessionrestored", "true");
+ });
+
+ this.delayedStartupFinished = true;
+ _resolveDelayedStartup();
+ Services.obs.notifyObservers(window, "browser-delayed-startup-finished");
+ TelemetryTimestamps.add("delayedStartupFinished");
+ // We've announced that delayed startup has finished. Do not add code past this point.
+ },
+
+ /**
+ * Resolved on the first MozLayerTreeReady and next MozAfterPaint in the
+ * parent process.
+ */
+ get firstContentWindowPaintPromise() {
+ return this._firstContentWindowPaintDeferred.promise;
+ },
+
+ _setInitialFocus() {
+ let initiallyFocusedElement = document.commandDispatcher.focusedElement;
+
+ // To prevent startup flicker, the urlbar has the 'focused' attribute set
+ // by default. If we are not sure the urlbar will be focused in this
+ // window, we need to remove the attribute before first paint.
+ // TODO (bug 1629956): The urlbar having the 'focused' attribute by default
+ // isn't a useful optimization anymore since UrlbarInput needs layout
+ // information to focus the urlbar properly.
+ let shouldRemoveFocusedAttribute = true;
+
+ this._callWithURIToLoad(uriToLoad => {
+ if (
+ isBlankPageURL(uriToLoad) ||
+ uriToLoad == "about:privatebrowsing" ||
+ this.getTabToAdopt()?.isEmpty
+ ) {
+ gURLBar.select();
+ shouldRemoveFocusedAttribute = false;
+ return;
+ }
+
+ // If the initial browser is remote, in order to optimize for first paint,
+ // we'll defer switching focus to that browser until it has painted.
+ // Otherwise use a regular promise to guarantee that mutationobserver
+ // microtasks that could affect focusability have run.
+ let promise = gBrowser.selectedBrowser.isRemoteBrowser
+ ? this.firstContentWindowPaintPromise
+ : Promise.resolve();
+
+ promise.then(() => {
+ // If focus didn't move while we were waiting, we're okay to move to
+ // the browser.
+ if (
+ document.commandDispatcher.focusedElement == initiallyFocusedElement
+ ) {
+ gBrowser.selectedBrowser.focus();
+ }
+ });
+ });
+
+ // Delay removing the attribute using requestAnimationFrame to avoid
+ // invalidating styles multiple times in a row if uriToLoadPromise
+ // resolves before first paint.
+ if (shouldRemoveFocusedAttribute) {
+ window.requestAnimationFrame(() => {
+ if (shouldRemoveFocusedAttribute) {
+ gURLBar.removeAttribute("focused");
+ }
+ });
+ }
+ },
+
+ _handleURIToLoad() {
+ this._callWithURIToLoad(uriToLoad => {
+ if (!uriToLoad) {
+ // We don't check whether window.arguments[5] (userContextId) is set
+ // because tabbrowser.js takes care of that for the initial tab.
+ return;
+ }
+
+ // We don't check if uriToLoad is a XULElement because this case has
+ // already been handled before first paint, and the argument cleared.
+ if (Array.isArray(uriToLoad)) {
+ // This function throws for certain malformed URIs, so use exception handling
+ // so that we don't disrupt startup
+ try {
+ gBrowser.loadTabs(uriToLoad, {
+ inBackground: false,
+ replace: true,
+ // See below for the semantics of window.arguments. Only the minimum is supported.
+ userContextId: window.arguments[5],
+ triggeringPrincipal:
+ window.arguments[8] ||
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ allowInheritPrincipal: window.arguments[9],
+ csp: window.arguments[10],
+ fromExternal: true,
+ });
+ } catch (e) {}
+ } else if (window.arguments.length >= 3) {
+ // window.arguments[1]: extraOptions (nsIPropertyBag)
+ // [2]: referrerInfo (nsIReferrerInfo)
+ // [3]: postData (nsIInputStream)
+ // [4]: allowThirdPartyFixup (bool)
+ // [5]: userContextId (int)
+ // [6]: originPrincipal (nsIPrincipal)
+ // [7]: originStoragePrincipal (nsIPrincipal)
+ // [8]: triggeringPrincipal (nsIPrincipal)
+ // [9]: allowInheritPrincipal (bool)
+ // [10]: csp (nsIContentSecurityPolicy)
+ // [11]: nsOpenWindowInfo
+ let userContextId =
+ window.arguments[5] != undefined
+ ? window.arguments[5]
+ : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
+
+ let hasValidUserGestureActivation = undefined;
+ let fromExternal = undefined;
+ let globalHistoryOptions = undefined;
+ let triggeringRemoteType = undefined;
+ let forceAllowDataURI = false;
+ let wasSchemelessInput = false;
+ if (window.arguments[1]) {
+ if (!(window.arguments[1] instanceof Ci.nsIPropertyBag2)) {
+ throw new Error(
+ "window.arguments[1] must be null or Ci.nsIPropertyBag2!"
+ );
+ }
+
+ let extraOptions = window.arguments[1];
+ if (extraOptions.hasKey("hasValidUserGestureActivation")) {
+ hasValidUserGestureActivation = extraOptions.getPropertyAsBool(
+ "hasValidUserGestureActivation"
+ );
+ }
+ if (extraOptions.hasKey("fromExternal")) {
+ fromExternal = extraOptions.getPropertyAsBool("fromExternal");
+ }
+ if (extraOptions.hasKey("triggeringSponsoredURL")) {
+ globalHistoryOptions = {
+ triggeringSponsoredURL: extraOptions.getPropertyAsACString(
+ "triggeringSponsoredURL"
+ ),
+ };
+ if (extraOptions.hasKey("triggeringSponsoredURLVisitTimeMS")) {
+ globalHistoryOptions.triggeringSponsoredURLVisitTimeMS =
+ extraOptions.getPropertyAsUint64(
+ "triggeringSponsoredURLVisitTimeMS"
+ );
+ }
+ }
+ if (extraOptions.hasKey("triggeringRemoteType")) {
+ triggeringRemoteType = extraOptions.getPropertyAsACString(
+ "triggeringRemoteType"
+ );
+ }
+ if (extraOptions.hasKey("forceAllowDataURI")) {
+ forceAllowDataURI =
+ extraOptions.getPropertyAsBool("forceAllowDataURI");
+ }
+ if (extraOptions.hasKey("wasSchemelessInput")) {
+ wasSchemelessInput =
+ extraOptions.getPropertyAsBool("wasSchemelessInput");
+ }
+ }
+
+ try {
+ openLinkIn(uriToLoad, "current", {
+ referrerInfo: window.arguments[2] || null,
+ postData: window.arguments[3] || null,
+ allowThirdPartyFixup: window.arguments[4] || false,
+ userContextId,
+ // pass the origin principal (if any) and force its use to create
+ // an initial about:blank viewer if present:
+ originPrincipal: window.arguments[6],
+ originStoragePrincipal: window.arguments[7],
+ triggeringPrincipal: window.arguments[8],
+ // TODO fix allowInheritPrincipal to default to false.
+ // Default to true unless explicitly set to false because of bug 1475201.
+ allowInheritPrincipal: window.arguments[9] !== false,
+ csp: window.arguments[10],
+ forceAboutBlankViewerInCurrent: !!window.arguments[6],
+ forceAllowDataURI,
+ hasValidUserGestureActivation,
+ fromExternal,
+ globalHistoryOptions,
+ triggeringRemoteType,
+ wasSchemelessInput,
+ });
+ } catch (e) {
+ console.error(e);
+ }
+
+ window.focus();
+ } else {
+ // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
+ // Such callers expect that window.arguments[0] is handled as a single URI.
+ loadOneOrMoreURIs(
+ uriToLoad,
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ null
+ );
+ }
+ });
+ },
+
+ /**
+ * Use this function as an entry point to schedule tasks that
+ * need to run once per window after startup, and can be scheduled
+ * by using an idle callback.
+ *
+ * The functions scheduled here will fire from idle callbacks
+ * once every window has finished being restored by session
+ * restore, and after the equivalent only-once tasks
+ * have run (from _scheduleStartupIdleTasks in BrowserGlue.sys.mjs).
+ */
+ _schedulePerWindowIdleTasks() {
+ // Bail out if the window has been closed in the meantime.
+ if (window.closed) {
+ return;
+ }
+
+ function scheduleIdleTask(func, options) {
+ requestIdleCallback(function idleTaskRunner() {
+ if (!window.closed) {
+ func();
+ }
+ }, options);
+ }
+
+ scheduleIdleTask(() => {
+ // Initialize the Sync UI
+ gSync.init();
+ });
+
+ scheduleIdleTask(() => {
+ // Read prefers-reduced-motion setting
+ let reduceMotionQuery = window.matchMedia(
+ "(prefers-reduced-motion: reduce)"
+ );
+ function readSetting() {
+ gReduceMotionSetting = reduceMotionQuery.matches;
+ }
+ reduceMotionQuery.addListener(readSetting);
+ readSetting();
+ });
+
+ scheduleIdleTask(() => {
+ // setup simple gestures support
+ gGestureSupport.init(true);
+
+ // setup history swipe animation
+ gHistorySwipeAnimation.init();
+ });
+
+ scheduleIdleTask(() => {
+ gBrowserThumbnails.init();
+ });
+
+ scheduleIdleTask(
+ () => {
+ // Initialize the download manager some time after the app starts so that
+ // auto-resume downloads begin (such as after crashing or quitting with
+ // active downloads) and speeds up the first-load of the download manager UI.
+ // If the user manually opens the download manager before the timeout, the
+ // downloads will start right away, and initializing again won't hurt.
+ try {
+ DownloadsCommon.initializeAllDataLinks();
+ ChromeUtils.importESModule(
+ "resource:///modules/DownloadsTaskbar.sys.mjs"
+ ).DownloadsTaskbar.registerIndicator(window);
+ if (AppConstants.platform == "macosx") {
+ ChromeUtils.importESModule(
+ "resource:///modules/DownloadsMacFinderProgress.sys.mjs"
+ ).DownloadsMacFinderProgress.register();
+ }
+ Services.telemetry.setEventRecordingEnabled("downloads", true);
+ } catch (ex) {
+ console.error(ex);
+ }
+ },
+ { timeout: 10000 }
+ );
+
+ if (Win7Features) {
+ scheduleIdleTask(() => Win7Features.onOpenWindow());
+ }
+
+ scheduleIdleTask(async () => {
+ NewTabPagePreloading.maybeCreatePreloadedBrowser(window);
+ });
+
+ scheduleIdleTask(() => {
+ gGfxUtils.init();
+ });
+
+ // This should always go last, since the idle tasks (except for the ones with
+ // timeouts) should execute in order. Note that this observer notification is
+ // not guaranteed to fire, since the window could close before we get here.
+ scheduleIdleTask(() => {
+ this.idleTasksFinished.resolve();
+ Services.obs.notifyObservers(
+ window,
+ "browser-idle-startup-tasks-finished"
+ );
+ });
+
+ scheduleIdleTask(() => {
+ gProfiles.init();
+ });
+ },
+
+ // Returns the URI(s) to load at startup if it is immediately known, or a
+ // promise resolving to the URI to load.
+ get uriToLoadPromise() {
+ delete this.uriToLoadPromise;
+ return (this.uriToLoadPromise = (function () {
+ // window.arguments[0]: URI to load (string), or an nsIArray of
+ // nsISupportsStrings to load, or a xul:tab of
+ // a tabbrowser, which will be replaced by this
+ // window (for this case, all other arguments are
+ // ignored).
+ let uri = window.arguments?.[0];
+ if (!uri || window.XULElement.isInstance(uri)) {
+ return null;
+ }
+
+ let defaultArgs = BrowserHandler.defaultArgs;
+
+ // If the given URI is different from the homepage, we want to load it.
+ if (uri != defaultArgs) {
+ AboutNewTab.noteNonDefaultStartup();
+
+ if (uri instanceof Ci.nsIArray) {
+ // Transform the nsIArray of nsISupportsString's into a JS Array of
+ // JS strings.
+ return Array.from(
+ uri.enumerate(Ci.nsISupportsString),
+ supportStr => supportStr.data
+ );
+ } else if (uri instanceof Ci.nsISupportsString) {
+ return uri.data;
+ }
+ return uri;
+ }
+
+ // The URI appears to be the the homepage. We want to load it only if
+ // session restore isn't about to override the homepage.
+ let willOverride = SessionStartup.willOverrideHomepage;
+ if (typeof willOverride == "boolean") {
+ return willOverride ? null : uri;
+ }
+ return willOverride.then(willOverrideHomepage =>
+ willOverrideHomepage ? null : uri
+ );
+ })());
+ },
+
+ // Calls the given callback with the URI to load at startup.
+ // Synchronously if possible, or after uriToLoadPromise resolves otherwise.
+ _callWithURIToLoad(callback) {
+ let uriToLoad = this.uriToLoadPromise;
+ if (uriToLoad && uriToLoad.then) {
+ uriToLoad.then(callback);
+ } else {
+ callback(uriToLoad);
+ }
+ },
+
+ onUnload() {
+ gUIDensity.uninit();
+
+ TabsInTitlebar.uninit();
+
+ ToolbarIconColor.uninit();
+
+ // In certain scenarios it's possible for unload to be fired before onload,
+ // (e.g. if the window is being closed after browser.js loads but before the
+ // load completes). In that case, there's nothing to do here.
+ if (!this._loadHandled) {
+ return;
+ }
+
+ // First clean up services initialized in gBrowserInit.onLoad (or those whose
+ // uninit methods don't depend on the services having been initialized).
+
+ CombinedStopReload.uninit();
+
+ gGestureSupport.init(false);
+
+ gHistorySwipeAnimation.uninit();
+
+ FullScreen.uninit();
+
+ gSync.uninit();
+
+ gExtensionsNotifications.uninit();
+ gUnifiedExtensions.uninit();
+
+ try {
+ gBrowser.removeProgressListener(window.XULBrowserWindow);
+ gBrowser.removeTabsProgressListener(window.TabsProgressListener);
+ } catch (ex) {}
+
+ PlacesToolbarHelper.uninit();
+
+ BookmarkingUI.uninit();
+
+ TabletModeUpdater.uninit();
+
+ gTabletModePageCounter.finish();
+
+ CaptivePortalWatcher.uninit();
+
+ SidebarController.uninit();
+
+ DownloadsButton.uninit();
+
+ if (gToolbarKeyNavEnabled) {
+ ToolbarKeyboardNavigator.uninit();
+ }
+
+ BrowserSearch.uninit();
+
+ NewTabPagePreloading.removePreloadedBrowser(window);
+
+ FirefoxViewHandler.uninit();
+
+ // Now either cancel delayedStartup, or clean up the services initialized from
+ // it.
+ if (this._boundDelayedStartup) {
+ this._cancelDelayedStartup();
+ } else {
+ if (Win7Features) {
+ Win7Features.onCloseWindow();
+ }
+ Services.prefs.removeObserver(ctrlTab.prefName, ctrlTab);
+ ctrlTab.uninit();
+ gBrowserThumbnails.uninit();
+ gProtectionsHandler.uninit();
+ FullZoom.destroy();
+
+ Services.obs.removeObserver(gIdentityHandler, "perm-changed");
+ Services.obs.removeObserver(gRemoteControl, "devtools-socket");
+ Services.obs.removeObserver(gRemoteControl, "marionette-listening");
+ Services.obs.removeObserver(gRemoteControl, "remote-listening");
+ Services.obs.removeObserver(
+ gSessionHistoryObserver,
+ "browser:purge-session-history"
+ );
+ Services.obs.removeObserver(
+ gStoragePressureObserver,
+ "QuotaManager::StoragePressure"
+ );
+ Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
+ Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
+ Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
+ Services.obs.removeObserver(
+ gXPInstallObserver,
+ "addon-install-fullscreen-blocked"
+ );
+ Services.obs.removeObserver(
+ gXPInstallObserver,
+ "addon-install-origin-blocked"
+ );
+ Services.obs.removeObserver(
+ gXPInstallObserver,
+ "addon-install-policy-blocked"
+ );
+ Services.obs.removeObserver(
+ gXPInstallObserver,
+ "addon-install-webapi-blocked"
+ );
+ Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
+ Services.obs.removeObserver(
+ gXPInstallObserver,
+ "addon-install-confirmation"
+ );
+ Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
+
+ MenuTouchModeObserver.uninit();
+ BrowserOffline.uninit();
+ CanvasPermissionPromptHelper.uninit();
+ WebAuthnPromptHelper.uninit();
+ PanelUI.uninit();
+ }
+
+ // Final window teardown, do this last.
+ gBrowser.destroy();
+ window.XULBrowserWindow = null;
+ window.docShell.treeOwner
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIAppWindow).XULBrowserWindow = null;
+ window.browserDOMWindow = null;
+ },
+};
+
+gBrowserInit.idleTasksFinishedPromise = gBrowserInit.idleTasksFinished.promise;
diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc
index 66dd662137..0eebfea75a 100644
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -140,19 +140,7 @@
</menupopup>
</menu>
<menu id="viewSidebarMenuMenu" data-l10n-id="menu-view-sidebar">
- <menupopup id="viewSidebarMenu">
- <menuitem id="menu_bookmarksSidebar"
- type="checkbox"
- key="viewBookmarksSidebarKb"
- oncommand="SidebarUI.toggle('viewBookmarksSidebar');" data-l10n-id="menu-view-bookmarks"/>
- <menuitem id="menu_historySidebar"
- type="checkbox"
- key="key_gotoHistory"
- oncommand="SidebarUI.toggle('viewHistorySidebar');" data-l10n-id="menu-view-history-button"/>
- <menuitem id="menu_tabsSidebar"
- type="checkbox"
- class="sync-ui-item"
- oncommand="SidebarUI.toggle('viewTabsSidebar');" data-l10n-id="menu-view-synced-tabs-sidebar"/>
+ <menupopup id="viewSidebarMenu" onpopupshowing="SidebarController.setMegalistMenubarVisibility(event);">
</menupopup>
</menu>
<menuseparator/>
@@ -189,7 +177,7 @@
</menu>
<menuitem id="repair-text-encoding"
disabled="true"
- oncommand="BrowserForceEncodingDetection();"
+ oncommand="BrowserCommands.forceEncodingDetection();"
data-l10n-id="menu-view-repair-text-encoding"/>
<menuseparator/>
#ifdef XP_MACOSX
diff --git a/browser/base/content/browser-pageActions.js b/browser/base/content/browser-pageActions.js
index 1cc895434d..fe0453160d 100644
--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -970,7 +970,7 @@ var BrowserPageActions = {
this._contextAction = null;
let viewID = "addons://detail/" + encodeURIComponent(action.extensionID);
- window.BrowserOpenAddonsMgr(viewID);
+ window.BrowserAddonUI.openAddonsMgr(viewID);
},
/**
@@ -1008,7 +1008,7 @@ BrowserPageActions.bookmark = {
}
},
- onCommand(event, buttonNode) {
+ onCommand(event) {
PanelMultiView.hidePopup(BrowserPageActions.panelNode);
BookmarkingUI.onStarCommand(event);
},
diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js
index 58e61f7bf7..404a080983 100644
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -17,7 +17,7 @@ XPCOMUtils.defineLazyPreferenceGetter(
"SHOW_OTHER_BOOKMARKS",
"browser.toolbars.bookmarks.showOtherBookmarks",
true,
- (aPref, aPrevVal, aNewVal) => {
+ () => {
BookmarkingUI.maybeShowOtherBookmarksFolder().then(() => {
document
.getElementById("PlacesToolbar")
@@ -55,7 +55,6 @@ var StarUI = {
delete this.panel;
this._createPanelIfNeeded();
var element = this._element("editBookmarkPanel");
- window.ensureCustomElements("moz-button-group");
// initially the panel is hidden
// to avoid impacting startup / new window performance
element.hidden = false;
@@ -253,7 +252,7 @@ var StarUI = {
}
target.addEventListener(
"popupshown",
- function (event) {
+ function () {
fn();
},
{ capture: true, once: true }
@@ -1174,7 +1173,7 @@ var PlacesToolbarHelper = {
return null;
},
- onWidgetUnderflow(aNode, aContainer) {
+ onWidgetUnderflow(aNode) {
// The view gets broken by being removed and reinserted by the overflowable
// toolbar, so we have to force an uninit and reinit.
let win = aNode.ownerGlobal;
@@ -1183,7 +1182,7 @@ var PlacesToolbarHelper = {
}
},
- onWidgetAdded(aWidgetId, aArea, aPosition) {
+ onWidgetAdded(aWidgetId) {
if (aWidgetId == "personal-bookmarks" && !this._isCustomizing) {
// It's possible (with the "Add to Menu", "Add to Toolbar" context
// options) that the Places Toolbar Items have been moved without
@@ -1378,7 +1377,7 @@ var BookmarkingUI = {
this.updateLabel(
"BMB_viewBookmarksSidebar",
- SidebarUI.currentID == "viewBookmarksSidebar"
+ SidebarController.currentID == "viewBookmarksSidebar"
);
this.updateLabel("BMB_viewBookmarksToolbar", !this.toolbar.collapsed);
},
@@ -1659,13 +1658,13 @@ var BookmarkingUI = {
}
},
- onWidgetReset: function BUI_widgetReset(aNode, aContainer) {
+ onWidgetReset: function BUI_widgetReset(aNode) {
if (aNode == this.button) {
this._onWidgetWasMoved();
}
},
- onWidgetUndoMove: function BUI_undoWidgetUndoMove(aNode, aContainer) {
+ onWidgetUndoMove: function BUI_undoWidgetUndoMove(aNode) {
if (aNode == this.button) {
this._onWidgetWasMoved();
}
@@ -1999,6 +1998,13 @@ var BookmarkingUI = {
case "ViewHiding":
this.onPanelMenuViewHiding(aEvent);
break;
+ case "command":
+ if (aEvent.target.id == "panelMenu_searchBookmarks") {
+ PlacesCommandHook.searchBookmarks();
+ } else if (aEvent.target.id == "panelMenu_viewBookmarksToolbar") {
+ this.toggleBookmarksToolbar("bookmark-tools");
+ }
+ break;
}
},
@@ -2026,12 +2032,15 @@ var BookmarkingUI = {
panelview
);
panelview.removeEventListener("ViewShowing", this);
+ panelview.addEventListener("command", this);
},
onPanelMenuViewHiding: function BUI_onViewHiding(aEvent) {
this._panelMenuView.uninit();
delete this._panelMenuView;
- aEvent.target.removeEventListener("ViewHiding", this);
+ let panelview = aEvent.target;
+ panelview.removeEventListener("ViewHiding", this);
+ panelview.removeEventListener("command", this);
},
handlePlacesEvents(aEvents) {
@@ -2155,7 +2164,7 @@ var BookmarkingUI = {
});
},
- onWidgetUnderflow(aNode, aContainer) {
+ onWidgetUnderflow(aNode) {
let win = aNode.ownerGlobal;
if (aNode.id != this.BOOKMARK_BUTTON_ID || win != window) {
return;
diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc
index 090e94b684..f77ce1661e 100644
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -16,12 +16,12 @@
<commandset id="mainCommandSet">
<command id="cmd_newNavigator" oncommand="OpenBrowserWindow()"/>
- <command id="cmd_handleBackspace" oncommand="BrowserHandleBackspace();" />
- <command id="cmd_handleShiftBackspace" oncommand="BrowserHandleShiftBackspace();" />
+ <command id="cmd_handleBackspace" oncommand="BrowserCommands.handleBackspace();" />
+ <command id="cmd_handleShiftBackspace" oncommand="BrowserCommands.handleShiftBackspace();" />
- <command id="cmd_newNavigatorTab" oncommand="BrowserOpenTab({ event });"/>
- <command id="cmd_newNavigatorTabNoEvent" oncommand="BrowserOpenTab();"/>
- <command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
+ <command id="cmd_newNavigatorTab" oncommand="BrowserCommands.openTab({ event });"/>
+ <command id="cmd_newNavigatorTabNoEvent" oncommand="BrowserCommands.openTab();"/>
+ <command id="Browser:OpenFile" oncommand="BrowserCommands.openFileWindow();"/>
<command id="Browser:SavePage" oncommand="saveBrowser(gBrowser.selectedBrowser);"/>
<command id="Browser:SendLink"
@@ -32,17 +32,17 @@
<command id="cmd_printPreviewToggle" oncommand="PrintUtils.togglePrintPreview(gBrowser.selectedBrowser.browsingContext);"/>
<command id="cmd_file_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, { entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.FILE_MENU });"/>
<command id="cmd_help_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, { entrypoint: MigrationUtils.MIGRATION_ENTRYPOINTS.HELP_MENU });"/>
- <command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
- <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow(event)"/>
+ <command id="cmd_close" oncommand="BrowserCommands.closeTabOrWindow(event);"/>
+ <command id="cmd_closeWindow" oncommand="BrowserCommands.tryToCloseWindow(event)"/>
<command id="cmd_toggleMute" oncommand="gBrowser.toggleMuteAudioOnMultiSelectedTabs(gBrowser.selectedTab)"/>
<command id="cmd_CustomizeToolbars" oncommand="gCustomizeMode.enter()"/>
<command id="cmd_toggleOfflineStatus" oncommand="BrowserOffline.toggleOfflineStatus();"/>
<command id="cmd_quitApplication" oncommand="goQuitApplication(event)"/>
<command id="View:AboutProcesses" oncommand="switchToTabHavingURI('about:processes', true)"/>
- <command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);"/>
- <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
- <command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
+ <command id="View:PageSource" oncommand="BrowserCommands.viewSource(window.gBrowser.selectedBrowser);"/>
+ <command id="View:PageInfo" oncommand="BrowserCommands.pageInfo();"/>
+ <command id="View:FullScreen" oncommand="BrowserCommands.fullScreen();"/>
<command id="View:ReaderView" oncommand="AboutReaderParent.toggleReaderMode(event);"/>
<command id="View:PictureInPicture" oncommand="PictureInPicture.onCommand(event);"/>
<command id="cmd_find" oncommand="gLazyFindCommand('onFindCommand')"/>
@@ -60,20 +60,20 @@
oncommand="PlacesCommandHook.searchBookmarks();"/>
<command id="Browser:BookmarkAllTabs"
oncommand="PlacesCommandHook.bookmarkTabs();"/>
- <command id="Browser:Back" oncommand="BrowserBack();" disabled="true"/>
- <command id="Browser:BackOrBackDuplicate" oncommand="BrowserBack(event);" disabled="true">
+ <command id="Browser:Back" oncommand="BrowserCommands.back();" disabled="true"/>
+ <command id="Browser:BackOrBackDuplicate" oncommand="BrowserCommands.back(event);" disabled="true">
<observes element="Browser:Back" attribute="disabled"/>
</command>
- <command id="Browser:Forward" oncommand="BrowserForward();" disabled="true"/>
- <command id="Browser:ForwardOrForwardDuplicate" oncommand="BrowserForward(event);" disabled="true">
+ <command id="Browser:Forward" oncommand="BrowserCommands.forward();" disabled="true"/>
+ <command id="Browser:ForwardOrForwardDuplicate" oncommand="BrowserCommands.forward(event);" disabled="true">
<observes element="Browser:Forward" attribute="disabled"/>
</command>
- <command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
- <command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
- <command id="Browser:ReloadOrDuplicate" oncommand="BrowserReloadOrDuplicate(event)" disabled="true">
+ <command id="Browser:Stop" oncommand="BrowserCommands.stop();" disabled="true"/>
+ <command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserCommands.reloadSkipCache(); else BrowserCommands.reload()" disabled="true"/>
+ <command id="Browser:ReloadOrDuplicate" oncommand="BrowserCommands.reloadOrDuplicate(event)" disabled="true">
<observes element="Browser:Reload" attribute="disabled"/>
</command>
- <command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true">
+ <command id="Browser:ReloadSkipCache" oncommand="BrowserCommands.reloadSkipCache()" disabled="true">
<observes element="Browser:Reload" attribute="disabled"/>
</command>
<command id="Browser:NextTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(1, true);"/>
@@ -91,8 +91,8 @@
<command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);"/>
<command id="Browser:OpenAboutContainers" oncommand="openPreferences('paneContainers');"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
- <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
- <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
+ <command id="Tools:Downloads" oncommand="BrowserCommands.downloadsUI();"/>
+ <command id="Tools:Addons" oncommand="BrowserAddonUI.openAddonsMgr();"/>
<command id="Tools:Sanitize" oncommand="Sanitizer.showUI(window);"/>
<command id="Tools:PrivateBrowsing"
oncommand="OpenBrowserWindow({private: true});"/>
@@ -216,7 +216,7 @@
<key id="goBackKb2" data-l10n-id="nav-back-shortcut-alt" command="Browser:Back" modifiers="accel"/>
<key id="goForwardKb2" data-l10n-id="nav-fwd-shortcut-alt" command="Browser:Forward" modifiers="accel"/>
#endif
- <key id="goHome" keycode="VK_HOME" oncommand="BrowserHome();" modifiers="alt"/>
+ <key id="goHome" keycode="VK_HOME" oncommand="BrowserCommands.home();" modifiers="alt"/>
<key keycode="VK_F5" command="Browser:Reload"/>
#ifndef XP_MACOSX
<key id="showAllHistoryKb" data-l10n-id="history-show-all-shortcut" command="Browser:ShowAllHistory" modifiers="accel,shift"/>
@@ -276,7 +276,7 @@
<key id="viewBookmarksSidebarKb"
data-l10n-id="bookmark-show-sidebar-shortcut"
modifiers="accel"
- oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
+ oncommand="SidebarController.toggle('viewBookmarksSidebar');"/>
<key id="viewBookmarksToolbarKb"
data-l10n-id="bookmark-show-toolbar-shortcut"
oncommand="BookmarkingUI.toggleBookmarksToolbar('shortcut');"
@@ -295,7 +295,7 @@
#else
modifiers="accel"
#endif
- oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
+ oncommand="SidebarController.toggle('viewHistorySidebar');"/>
<key id="key_fullZoomReduce" data-l10n-id="full-zoom-reduce-shortcut" command="cmd_fullZoomReduce" modifiers="accel"/>
<key data-l10n-id="full-zoom-reduce-shortcut-alt-a" command="cmd_fullZoomReduce" modifiers="accel"/>
diff --git a/browser/base/content/browser-sidebar.js b/browser/base/content/browser-sidebar.js
deleted file mode 100644
index 2d730700a6..0000000000
--- a/browser/base/content/browser-sidebar.js
+++ /dev/null
@@ -1,674 +0,0 @@
-/* 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/. */
-
-/**
- * SidebarUI controls showing and hiding the browser sidebar.
- */
-var SidebarUI = {
- get sidebars() {
- if (this._sidebars) {
- return this._sidebars;
- }
-
- function makeSidebar({ elementId, ...rest }) {
- return {
- get sourceL10nEl() {
- return document.getElementById(elementId);
- },
- get title() {
- return document.getElementById(elementId).getAttribute("label");
- },
- ...rest,
- };
- }
-
- return (this._sidebars = new Map([
- [
- "viewBookmarksSidebar",
- makeSidebar({
- elementId: "sidebar-switcher-bookmarks",
- url: "chrome://browser/content/places/bookmarksSidebar.xhtml",
- menuId: "menu_bookmarksSidebar",
- }),
- ],
- [
- "viewHistorySidebar",
- makeSidebar({
- elementId: "sidebar-switcher-history",
- url: "chrome://browser/content/places/historySidebar.xhtml",
- menuId: "menu_historySidebar",
- triggerButtonId: "appMenuViewHistorySidebar",
- }),
- ],
- [
- "viewTabsSidebar",
- makeSidebar({
- elementId: "sidebar-switcher-tabs",
- url: "chrome://browser/content/syncedtabs/sidebar.xhtml",
- menuId: "menu_tabsSidebar",
- }),
- ],
- ]));
- },
-
- // Avoid getting the browser element from init() to avoid triggering the
- // <browser> constructor during startup if the sidebar is hidden.
- get browser() {
- if (this._browser) {
- return this._browser;
- }
- return (this._browser = document.getElementById("sidebar"));
- },
- POSITION_START_PREF: "sidebar.position_start",
- DEFAULT_SIDEBAR_ID: "viewBookmarksSidebar",
-
- // lastOpenedId is set in show() but unlike currentID it's not cleared out on hide
- // and isn't persisted across windows
- lastOpenedId: null,
-
- _box: null,
- // The constructor of this label accesses the browser element due to the
- // control="sidebar" attribute, so avoid getting this label during startup.
- get _title() {
- if (this.__title) {
- return this.__title;
- }
- return (this.__title = document.getElementById("sidebar-title"));
- },
- _splitter: null,
- _reversePositionButton: null,
- _switcherPanel: null,
- _switcherTarget: null,
- _switcherArrow: null,
- _inited: false,
-
- /**
- * @type {MutationObserver | null}
- */
- _observer: null,
-
- _initDeferred: Promise.withResolvers(),
-
- get promiseInitialized() {
- return this._initDeferred.promise;
- },
-
- get initialized() {
- return this._inited;
- },
-
- init() {
- this._box = document.getElementById("sidebar-box");
- this._splitter = document.getElementById("sidebar-splitter");
- this._reversePositionButton = document.getElementById(
- "sidebar-reverse-position"
- );
- this._switcherPanel = document.getElementById("sidebarMenu-popup");
- this._switcherTarget = document.getElementById("sidebar-switcher-target");
- this._switcherArrow = document.getElementById("sidebar-switcher-arrow");
-
- this._switcherTarget.addEventListener("command", () => {
- this.toggleSwitcherPanel();
- });
- this._switcherTarget.addEventListener("keydown", event => {
- this.handleKeydown(event);
- });
-
- this._inited = true;
-
- Services.obs.addObserver(this, "intl:app-locales-changed");
-
- this._initDeferred.resolve();
- },
-
- uninit() {
- // If this is the last browser window, persist various values that should be
- // remembered for after a restart / reopening a browser window.
- let enumerator = Services.wm.getEnumerator("navigator:browser");
- if (!enumerator.hasMoreElements()) {
- let xulStore = Services.xulStore;
- xulStore.persist(this._box, "sidebarcommand");
-
- if (this._box.hasAttribute("positionend")) {
- xulStore.persist(this._box, "positionend");
- } else {
- xulStore.removeValue(
- document.documentURI,
- "sidebar-box",
- "positionend"
- );
- }
- if (this._box.hasAttribute("checked")) {
- xulStore.persist(this._box, "checked");
- } else {
- xulStore.removeValue(document.documentURI, "sidebar-box", "checked");
- }
-
- xulStore.persist(this._box, "style");
- xulStore.persist(this._title, "value");
- }
-
- Services.obs.removeObserver(this, "intl:app-locales-changed");
-
- if (this._observer) {
- this._observer.disconnect();
- this._observer = null;
- }
- },
-
- /**
- * The handler for Services.obs.addObserver.
- **/
- observe(_subject, topic, _data) {
- switch (topic) {
- case "intl:app-locales-changed": {
- if (this.isOpen) {
- // The <tree> component used in history and bookmarks, but it does not
- // support live switching the app locale. Reload the entire sidebar to
- // invalidate any old text.
- this.hide();
- this.showInitially(this.lastOpenedId);
- break;
- }
- }
- }
- },
-
- /**
- * Ensure the title stays in sync with the source element, which updates for
- * l10n changes.
- *
- * @param {HTMLElement} [element]
- */
- observeTitleChanges(element) {
- if (!element) {
- return;
- }
- let observer = this._observer;
- if (!observer) {
- observer = new MutationObserver(() => {
- this.title = this.sidebars.get(this.lastOpenedId).title;
- });
- // Re-use the observer.
- this._observer = observer;
- }
- observer.disconnect();
- observer.observe(element, {
- attributes: true,
- attributeFilter: ["label"],
- });
- },
-
- /**
- * Opens the switcher panel if it's closed, or closes it if it's open.
- */
- toggleSwitcherPanel() {
- if (
- this._switcherPanel.state == "open" ||
- this._switcherPanel.state == "showing"
- ) {
- this.hideSwitcherPanel();
- } else if (this._switcherPanel.state == "closed") {
- this.showSwitcherPanel();
- }
- },
-
- /**
- * Handles keydown on the the switcherTarget button
- * @param {Event} event
- */
- handleKeydown(event) {
- switch (event.key) {
- case "Enter":
- case " ": {
- this.toggleSwitcherPanel();
- event.stopPropagation();
- event.preventDefault();
- break;
- }
- case "Escape": {
- this.hideSwitcherPanel();
- event.stopPropagation();
- event.preventDefault();
- break;
- }
- }
- },
-
- hideSwitcherPanel() {
- this._switcherPanel.hidePopup();
- },
-
- showSwitcherPanel() {
- this._switcherPanel.addEventListener(
- "popuphiding",
- () => {
- this._switcherTarget.classList.remove("active");
- this._switcherTarget.setAttribute("aria-expanded", false);
- },
- { once: true }
- );
-
- // Combine start/end position with ltr/rtl to set the label in the popup appropriately.
- let label =
- this._positionStart == RTL_UI
- ? gNavigatorBundle.getString("sidebar.moveToLeft")
- : gNavigatorBundle.getString("sidebar.moveToRight");
- this._reversePositionButton.setAttribute("label", label);
-
- // Open the sidebar switcher popup, anchored off the switcher toggle
- this._switcherPanel.hidden = false;
- this._switcherPanel.openPopup(this._switcherTarget);
-
- this._switcherTarget.classList.add("active");
- this._switcherTarget.setAttribute("aria-expanded", true);
- },
-
- updateShortcut({ keyId }) {
- let menuitem = this._switcherPanel?.querySelector(`[key="${keyId}"]`);
- if (!menuitem) {
- // If the menu item doesn't exist yet then the accel text will be set correctly
- // upon creation so there's nothing to do now.
- return;
- }
- menuitem.removeAttribute("acceltext");
- },
-
- /**
- * Change the pref that will trigger a call to setPosition
- */
- reversePosition() {
- Services.prefs.setBoolPref(this.POSITION_START_PREF, !this._positionStart);
- },
-
- /**
- * Read the positioning pref and position the sidebar and the splitter
- * appropriately within the browser container.
- */
- setPosition() {
- // First reset all ordinals to match DOM ordering.
- let browser = document.getElementById("browser");
- [...browser.children].forEach((node, i) => {
- node.style.order = i + 1;
- });
-
- if (!this._positionStart) {
- // DOM ordering is: | sidebar-box | splitter | appcontent |
- // Want to display as: | appcontent | splitter | sidebar-box |
- // So we just swap box and appcontent ordering
- let appcontent = document.getElementById("appcontent");
- let boxOrdinal = this._box.style.order;
- this._box.style.order = appcontent.style.order;
- appcontent.style.order = boxOrdinal;
- // Indicate we've switched ordering to the box
- this._box.setAttribute("positionend", true);
- } else {
- this._box.removeAttribute("positionend");
- }
-
- this.hideSwitcherPanel();
-
- let content = SidebarUI.browser.contentWindow;
- if (content && content.updatePosition) {
- content.updatePosition();
- }
- },
-
- /**
- * Try and adopt the status of the sidebar from another window.
- * @param {Window} sourceWindow - Window to use as a source for sidebar status.
- * @return true if we adopted the state, or false if the caller should
- * initialize the state itself.
- */
- adoptFromWindow(sourceWindow) {
- // If the opener had a sidebar, open the same sidebar in our window.
- // The opener can be the hidden window too, if we're coming from the state
- // where no windows are open, and the hidden window has no sidebar box.
- let sourceUI = sourceWindow.SidebarUI;
- if (!sourceUI || !sourceUI._box) {
- // no source UI or no _box means we also can't adopt the state.
- return false;
- }
-
- // Set sidebar command even if hidden, so that we keep the same sidebar
- // even if it's currently closed.
- let commandID = sourceUI._box.getAttribute("sidebarcommand");
- if (commandID) {
- this._box.setAttribute("sidebarcommand", commandID);
- }
-
- if (sourceUI._box.hidden) {
- // just hidden means we have adopted the hidden state.
- return true;
- }
-
- // dynamically generated sidebars will fail this check, but we still
- // consider it adopted.
- if (!this.sidebars.has(commandID)) {
- return true;
- }
-
- this._box.style.width = sourceUI._box.getBoundingClientRect().width + "px";
- this.showInitially(commandID);
-
- return true;
- },
-
- windowPrivacyMatches(w1, w2) {
- return (
- PrivateBrowsingUtils.isWindowPrivate(w1) ===
- PrivateBrowsingUtils.isWindowPrivate(w2)
- );
- },
-
- /**
- * If loading a sidebar was delayed on startup, start the load now.
- */
- startDelayedLoad() {
- let sourceWindow = window.opener;
- // No source window means this is the initial window. If we're being
- // opened from another window, check that it is one we might open a sidebar
- // for.
- if (sourceWindow) {
- if (
- sourceWindow.closed ||
- sourceWindow.location.protocol != "chrome:" ||
- !this.windowPrivacyMatches(sourceWindow, window)
- ) {
- return;
- }
- // Try to adopt the sidebar state from the source window
- if (this.adoptFromWindow(sourceWindow)) {
- return;
- }
- }
-
- // If we're not adopting settings from a parent window, set them now.
- let wasOpen = this._box.getAttribute("checked");
- if (!wasOpen) {
- return;
- }
-
- let commandID = this._box.getAttribute("sidebarcommand");
- if (commandID && this.sidebars.has(commandID)) {
- this.showInitially(commandID);
- } else {
- this._box.removeAttribute("checked");
- // Remove the |sidebarcommand| attribute, because the element it
- // refers to no longer exists, so we should assume this sidebar
- // panel has been uninstalled. (249883)
- // We use setAttribute rather than removeAttribute so it persists
- // correctly.
- this._box.setAttribute("sidebarcommand", "");
- // On a startup in which the startup cache was invalidated (e.g. app update)
- // extensions will not be started prior to delayedLoad, thus the
- // sidebarcommand element will not exist yet. Store the commandID so
- // extensions may reopen if necessary. A startup cache invalidation
- // can be forced (for testing) by deleting compatibility.ini from the
- // profile.
- this.lastOpenedId = commandID;
- }
- },
-
- /**
- * Fire a "SidebarShown" event on the sidebar to give any interested parties
- * a chance to update the button or whatever.
- */
- _fireShowEvent() {
- let event = new CustomEvent("SidebarShown", { bubbles: true });
- this._switcherTarget.dispatchEvent(event);
- },
-
- /**
- * Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
- * a chance to adjust focus as needed. An additional event is needed, because
- * we don't want to focus the sidebar when it's opened on startup or in a new
- * window, only when the user opens the sidebar.
- */
- _fireFocusedEvent() {
- let event = new CustomEvent("SidebarFocused", { bubbles: true });
- this.browser.contentWindow.dispatchEvent(event);
- },
-
- /**
- * True if the sidebar is currently open.
- */
- get isOpen() {
- return !this._box.hidden;
- },
-
- /**
- * The ID of the current sidebar.
- */
- get currentID() {
- return this.isOpen ? this._box.getAttribute("sidebarcommand") : "";
- },
-
- get title() {
- return this._title.value;
- },
-
- set title(value) {
- this._title.value = value;
- },
-
- /**
- * Toggle the visibility of the sidebar. If the sidebar is hidden or is open
- * with a different commandID, then the sidebar will be opened using the
- * specified commandID. Otherwise the sidebar will be hidden.
- *
- * @param {string} commandID ID of the sidebar.
- * @param {DOMNode} [triggerNode] Node, usually a button, that triggered the
- * visibility toggling of the sidebar.
- * @return {Promise}
- */
- toggle(commandID = this.lastOpenedId, triggerNode) {
- if (
- CustomizationHandler.isCustomizing() ||
- CustomizationHandler.isExitingCustomizeMode
- ) {
- return Promise.resolve();
- }
- // First priority for a default value is this.lastOpenedId which is set during show()
- // and not reset in hide(), unlike currentID. If show() hasn't been called and we don't
- // have a persisted command either, or the command doesn't exist anymore, then
- // fallback to a default sidebar.
- if (!commandID) {
- commandID = this._box.getAttribute("sidebarcommand");
- }
- if (!commandID || !this.sidebars.has(commandID)) {
- commandID = this.DEFAULT_SIDEBAR_ID;
- }
-
- if (this.isOpen && commandID == this.currentID) {
- this.hide(triggerNode);
- return Promise.resolve();
- }
- return this.show(commandID, triggerNode);
- },
-
- _loadSidebarExtension(commandID) {
- let sidebar = this.sidebars.get(commandID);
- let { extensionId } = sidebar;
- if (extensionId) {
- SidebarUI.browser.contentWindow.loadPanel(
- extensionId,
- sidebar.panel,
- sidebar.browserStyle
- );
- }
- },
-
- /**
- * Show the sidebar.
- *
- * This wraps the internal method, including a ping to telemetry.
- *
- * @param {string} commandID ID of the sidebar to use.
- * @param {DOMNode} [triggerNode] Node, usually a button, that triggered the
- * showing of the sidebar.
- * @return {Promise<boolean>}
- */
- async show(commandID, triggerNode) {
- let panelType = commandID.substring(4, commandID.length - 7);
- Services.telemetry.keyedScalarAdd("sidebar.opened", panelType, 1);
-
- // Extensions without private window access wont be in the
- // sidebars map.
- if (!this.sidebars.has(commandID)) {
- return false;
- }
- return this._show(commandID).then(() => {
- this._loadSidebarExtension(commandID);
-
- if (triggerNode) {
- updateToggleControlLabel(triggerNode);
- }
-
- this._fireFocusedEvent();
- return true;
- });
- },
-
- /**
- * Show the sidebar, without firing the focused event or logging telemetry.
- * This is intended to be used when the sidebar is opened automatically
- * when a window opens (not triggered by user interaction).
- *
- * @param {string} commandID ID of the sidebar.
- * @return {Promise<boolean>}
- */
- async showInitially(commandID) {
- let panelType = commandID.substring(4, commandID.length - 7);
- Services.telemetry.keyedScalarAdd("sidebar.opened", panelType, 1);
-
- // Extensions without private window access wont be in the
- // sidebars map.
- if (!this.sidebars.has(commandID)) {
- return false;
- }
- return this._show(commandID).then(() => {
- this._loadSidebarExtension(commandID);
- return true;
- });
- },
-
- /**
- * Implementation for show. Also used internally for sidebars that are shown
- * when a window is opened and we don't want to ping telemetry.
- *
- * @param {string} commandID ID of the sidebar.
- * @return {Promise<void>}
- */
- _show(commandID) {
- return new Promise(resolve => {
- this.selectMenuItem(commandID);
-
- this._box.hidden = this._splitter.hidden = false;
- this.setPosition();
-
- this.hideSwitcherPanel();
-
- this._box.setAttribute("checked", "true");
- this._box.setAttribute("sidebarcommand", commandID);
- this.lastOpenedId = commandID;
-
- let { url, title, sourceL10nEl } = this.sidebars.get(commandID);
- this.title = title;
- // Keep the title element in sync with any l10n changes.
- this.observeTitleChanges(sourceL10nEl);
- this.browser.setAttribute("src", url); // kick off async load
-
- if (this.browser.contentDocument.location.href != url) {
- this.browser.addEventListener(
- "load",
- event => {
- // We're handling the 'load' event before it bubbles up to the usual
- // (non-capturing) event handlers. Let it bubble up before resolving.
- setTimeout(() => {
- resolve();
-
- // Now that the currentId is updated, fire a show event.
- this._fireShowEvent();
- }, 0);
- },
- { capture: true, once: true }
- );
- } else {
- resolve();
-
- // Now that the currentId is updated, fire a show event.
- this._fireShowEvent();
- }
- });
- },
-
- /**
- * Hide the sidebar.
- *
- * @param {DOMNode} [triggerNode] Node, usually a button, that triggered the
- * hiding of the sidebar.
- */
- hide(triggerNode) {
- if (!this.isOpen) {
- return;
- }
-
- this.hideSwitcherPanel();
-
- this.selectMenuItem("");
-
- // Replace the document currently displayed in the sidebar with about:blank
- // so that we can free memory by unloading the page. We need to explicitly
- // create a new content viewer because the old one doesn't get destroyed
- // until about:blank has loaded (which does not happen as long as the
- // element is hidden).
- this.browser.setAttribute("src", "about:blank");
- this.browser.docShell.createAboutBlankDocumentViewer(null, null);
-
- this._box.removeAttribute("checked");
- this._box.hidden = this._splitter.hidden = true;
-
- let selBrowser = gBrowser.selectedBrowser;
- selBrowser.focus();
- if (triggerNode) {
- updateToggleControlLabel(triggerNode);
- }
- },
-
- /**
- * Sets the checked state only on the menu items of the specified sidebar, or
- * none if the argument is an empty string.
- */
- selectMenuItem(commandID) {
- for (let [id, { menuId, triggerButtonId }] of this.sidebars) {
- let menu = document.getElementById(menuId);
- let triggerbutton =
- triggerButtonId && document.getElementById(triggerButtonId);
- if (id == commandID) {
- menu.setAttribute("checked", "true");
- if (triggerbutton) {
- triggerbutton.setAttribute("checked", "true");
- updateToggleControlLabel(triggerbutton);
- }
- } else {
- menu.removeAttribute("checked");
- if (triggerbutton) {
- triggerbutton.removeAttribute("checked");
- updateToggleControlLabel(triggerbutton);
- }
- }
- }
- },
-};
-
-// Add getters related to the position here, since we will want them
-// available for both startDelayedLoad and init.
-XPCOMUtils.defineLazyPreferenceGetter(
- SidebarUI,
- "_positionStart",
- SidebarUI.POSITION_START_PREF,
- true,
- SidebarUI.setPosition.bind(SidebarUI)
-);
diff --git a/browser/base/content/browser-siteIdentity.js b/browser/base/content/browser-siteIdentity.js
index a2a5f6ff71..eaed3950fe 100644
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -177,7 +177,6 @@ var gIdentityHandler = {
_popupInitialized: false,
_initializePopup() {
- window.ensureCustomElements("moz-support-link");
if (!this._popupInitialized) {
let wrapper = document.getElementById("template-identity-popup");
wrapper.replaceWith(wrapper.content);
@@ -456,7 +455,9 @@ var gIdentityHandler = {
);
// Reload the page with the content unblocked
- BrowserReloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
+ BrowserCommands.reloadWithFlags(
+ Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE
+ );
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
@@ -475,7 +476,7 @@ var gIdentityHandler = {
"mixed-content"
);
if (reload) {
- BrowserReload();
+ BrowserCommands.reload();
}
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
@@ -496,7 +497,7 @@ var gIdentityHandler = {
port,
gBrowser.contentPrincipal.originAttributes
);
- BrowserReloadSkipCache();
+ BrowserCommands.reloadSkipCache();
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
@@ -611,7 +612,7 @@ var gIdentityHandler = {
// Because "off" is 1 and "off temporarily" is 2, we can just check if the
// sum of newValue and oldValue is 3.
if (newValue + oldValue !== 3) {
- BrowserReloadSkipCache();
+ BrowserCommands.reloadSkipCache();
if (this._popupInitialized) {
PanelMultiView.hidePopup(this._identityPopup);
}
@@ -1260,7 +1261,7 @@ var gIdentityHandler = {
}
},
- handleEvent(event) {
+ handleEvent() {
let elem = document.activeElement;
let position = elem.compareDocumentPosition(this._identityPopup);
@@ -1278,7 +1279,7 @@ var gIdentityHandler = {
}
},
- observe(subject, topic, data) {
+ observe(subject, topic) {
switch (topic) {
case "perm-changed": {
// Exclude permissions which do not appear in the UI in order to avoid
diff --git a/browser/base/content/browser-sitePermissionPanel.js b/browser/base/content/browser-sitePermissionPanel.js
index d81b636668..de7b2cc39a 100644
--- a/browser/base/content/browser-sitePermissionPanel.js
+++ b/browser/base/content/browser-sitePermissionPanel.js
@@ -14,9 +14,6 @@ var gPermissionPanel = {
if (!this._popupInitialized) {
let wrapper = document.getElementById("template-permission-popup");
wrapper.replaceWith(wrapper.content);
-
- window.ensureCustomElements("moz-support-link");
-
this._popupInitialized = true;
}
},
@@ -353,7 +350,7 @@ var gPermissionPanel = {
}
},
- handleEvent(event) {
+ handleEvent() {
let elem = document.activeElement;
let position = elem.compareDocumentPosition(this._permissionPopup);
@@ -371,7 +368,7 @@ var gPermissionPanel = {
}
},
- observe(subject, topic, data) {
+ observe(subject, topic) {
switch (topic) {
case "fullscreen-painted": {
if (subject != window || !this._exitedEventReceived) {
diff --git a/browser/base/content/browser-siteProtections.js b/browser/base/content/browser-siteProtections.js
index c44b4d3e8e..31b87ac7e0 100644
--- a/browser/base/content/browser-siteProtections.js
+++ b/browser/base/content/browser-siteProtections.js
@@ -31,8 +31,6 @@ class ProtectionCategory {
* @param {Object} options - Category options.
* @param {string} options.prefEnabled - ID of pref which controls the
* category enabled state.
- * @param {string} [options.l10nId] - Identifier l10n strings are keyed under
- * for this category. Defaults to protection ID.
* @param {Object} flags - Flags for this category to look for in the content
* blocking event and content blocking log.
* @param {Number} [flags.load] - Load flag for this protection category. If
@@ -49,7 +47,7 @@ class ProtectionCategory {
*/
constructor(
id,
- { prefEnabled, l10nId },
+ { prefEnabled },
{
load,
block,
@@ -416,7 +414,6 @@ let TrackingProtection =
super(
"trackers",
{
- l10nId: "trackingContent",
prefEnabled: "privacy.trackingprotection.enabled",
},
{
@@ -1065,7 +1062,6 @@ let SocialTracking =
super(
"socialblock",
{
- l10nId: "socialMediaTrackers",
prefEnabled: "privacy.socialtracking.block_cookies.enabled",
},
{
@@ -1381,7 +1377,6 @@ var gProtectionsHandler = {
let wrapper = document.getElementById("template-protections-popup");
this._protectionsPopup = wrapper.content.firstElementChild;
wrapper.replaceWith(wrapper.content);
- window.ensureCustomElements("moz-support-link");
this.maybeSetMilestoneCounterText();
@@ -1595,8 +1590,6 @@ var gProtectionsHandler = {
// Add an observer to observe that the history has been cleared.
Services.obs.addObserver(this, "browser:purge-session-history");
-
- window.ensureCustomElements("moz-button-group", "moz-toggle");
},
uninit() {
@@ -1641,42 +1634,42 @@ var gProtectionsHandler = {
);
},
- async showTrackersSubview(event) {
+ async showTrackersSubview() {
await TrackingProtection.updateSubView();
this._protectionsPopupMultiView.showSubView(
"protections-popup-trackersView"
);
},
- async showSocialblockerSubview(event) {
+ async showSocialblockerSubview() {
await SocialTracking.updateSubView();
this._protectionsPopupMultiView.showSubView(
"protections-popup-socialblockView"
);
},
- async showCookiesSubview(event) {
+ async showCookiesSubview() {
await ThirdPartyCookies.updateSubView();
this._protectionsPopupMultiView.showSubView(
"protections-popup-cookiesView"
);
},
- async showFingerprintersSubview(event) {
+ async showFingerprintersSubview() {
await Fingerprinting.updateSubView();
this._protectionsPopupMultiView.showSubView(
"protections-popup-fingerprintersView"
);
},
- async showCryptominersSubview(event) {
+ async showCryptominersSubview() {
await Cryptomining.updateSubView();
this._protectionsPopupMultiView.showSubView(
"protections-popup-cryptominersView"
);
},
- async onCookieBannerClick(event) {
+ async onCookieBannerClick() {
if (!cookieBannerHandling.isSiteSupported) {
return;
}
@@ -2055,7 +2048,7 @@ var gProtectionsHandler = {
}
},
- observe(subject, topic, data) {
+ observe(subject, topic) {
switch (topic) {
case "browser:purge-session-history":
// We need to update the earliest recorded date if history has been
@@ -2194,7 +2187,7 @@ var gProtectionsHandler = {
ContentBlockingAllowList.add(gBrowser.selectedBrowser);
if (shouldReload) {
this._hidePopup();
- BrowserReload();
+ BrowserCommands.reload();
}
},
@@ -2202,11 +2195,11 @@ var gProtectionsHandler = {
ContentBlockingAllowList.remove(gBrowser.selectedBrowser);
if (shouldReload) {
this._hidePopup();
- BrowserReload();
+ BrowserCommands.reload();
}
},
- async onTPSwitchCommand(event) {
+ async onTPSwitchCommand() {
// When the switch is clicked, we wait 500ms and then disable/enable
// protections, causing the page to refresh, and close the popup.
// We need to ensure we don't handle more clicks during the 500ms delay,
@@ -2533,12 +2526,12 @@ var gProtectionsHandler = {
};
const doc = event.target.ownerDocument;
- const container = doc.getElementById("messaging-system-message-container");
+ const container = doc.getElementById("info-message-container");
const infoButton = doc.getElementById("protections-popup-info-button");
const panelContainer = doc.getElementById("protections-popup");
const toggleMessage = () => {
const learnMoreLink = doc.querySelector(
- "#messaging-system-message-container .text-link"
+ "#info-message-container .text-link"
);
if (learnMoreLink) {
container.toggleAttribute("disabled");
@@ -2605,14 +2598,14 @@ var gProtectionsHandler = {
_createHeroElement(doc, message) {
const messageEl = this._createElement(doc, "div");
messageEl.setAttribute("id", "protections-popup-message");
- messageEl.classList.add("whatsNew-hero-message");
+ messageEl.classList.add("protections-hero-message");
const wrapperEl = this._createElement(doc, "div");
- wrapperEl.classList.add("whatsNew-message-body");
+ wrapperEl.classList.add("protections-popup-message-body");
messageEl.appendChild(wrapperEl);
wrapperEl.appendChild(
this._createElement(doc, "h2", {
- classList: "whatsNew-message-title",
+ classList: "protections-popup-message-title",
content: message.content.title,
})
);
diff --git a/browser/base/content/browser-sync.js b/browser/base/content/browser-sync.js
index a94bf2b896..9aa6cc5cd4 100644
--- a/browser/base/content/browser-sync.js
+++ b/browser/base/content/browser-sync.js
@@ -55,7 +55,7 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
this.createSyncedTabs();
}
- observe(subject, topic, data) {
+ observe(subject, topic) {
if (topic == SyncedTabs.TOPIC_TABS_CHANGED) {
this._showSyncedTabs();
}
@@ -202,10 +202,7 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
}
_appendSyncClient(client, container, labelId, paginationInfo) {
- let {
- maxTabs = SyncedTabsPanelList.sRemoteTabsPerPage,
- showInactive = false,
- } = paginationInfo;
+ let { maxTabs = SyncedTabsPanelList.sRemoteTabsPerPage } = paginationInfo;
// Create the element for the remote client.
let clientItem = document.createXULElement("label");
clientItem.setAttribute("id", labelId);
@@ -227,11 +224,24 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
);
label.setAttribute("class", "PanelUI-remotetabs-notabsforclient-label");
} else {
- let tabs = client.tabs.filter(t => showInactive || !t.inactive);
- let numInactive = client.tabs.length - tabs.length;
+ // We have the client obj but we need the FxA device obj so we use the clients
+ // engine to get us the FxA device
+ let device =
+ fxAccounts.device.recentDeviceList &&
+ fxAccounts.device.recentDeviceList.find(
+ d =>
+ d.id === Weave.Service.clientsEngine.getClientFxaDeviceId(client.id)
+ );
+ let remoteTabCloseAvailable =
+ device && fxAccounts.commands.closeTab.isDeviceCompatible(device);
+
+ let tabs = client.tabs.filter(t => !t.inactive);
+ let hasInactive = tabs.length != client.tabs.length;
- // If this page will display all tabs, show no additional buttons.
- // Otherwise, show a "Show More" button
+ if (hasInactive) {
+ container.append(this._createShowInactiveTabsElement(client, device));
+ }
+ // If this page isn't displaying all (regular, active) tabs, show a "Show More" button.
let hasNextPage = tabs.length > maxTabs;
let nextPageIsLastPage =
hasNextPage &&
@@ -248,15 +258,13 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
tabs = tabs.slice(0, maxTabs);
}
for (let [index, tab] of tabs.entries()) {
- let tabEnt = this._createSyncedTabElement(tab, index);
- container.appendChild(tabEnt);
- }
- if (numInactive) {
- let elt = this._createShowInactiveTabsElement(
- paginationInfo,
- numInactive
+ let tabEnt = this._createSyncedTabElement(
+ tab,
+ index,
+ device,
+ remoteTabCloseAvailable
);
- container.appendChild(elt);
+ container.appendChild(tabEnt);
}
if (hasNextPage) {
let showAllEnt = this._createShowMoreSyncedTabsElement(paginationInfo);
@@ -265,7 +273,10 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
}
}
- _createSyncedTabElement(tabInfo, index) {
+ _createSyncedTabElement(tabInfo, index, device, canCloseTabs) {
+ let tabContainer = document.createXULElement("hbox");
+ tabContainer.setAttribute("class", "PanelUI-tabitem-container");
+
let item = document.createXULElement("toolbarbutton");
let tooltipText = (tabInfo.title ? tabInfo.title + "\n" : "") + tabInfo.url;
item.setAttribute("itemtype", "tab");
@@ -296,25 +307,29 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
{}
),
});
- if (document.defaultView.whereToOpenLink(e) != "current") {
+ if (BrowserUtils.whereToOpenLink(e) != "current") {
e.preventDefault();
e.stopPropagation();
} else {
CustomizableUI.hidePanelForNode(item);
}
});
- return item;
+ tabContainer.appendChild(item);
+ // We should only add an X button next to tabs if the device
+ // is broadcasting that it can remotely close tabs
+ if (canCloseTabs) {
+ tabContainer.appendChild(
+ this._createCloseTabElement(tabInfo.url, device)
+ );
+ }
+ return tabContainer;
}
_createShowMoreSyncedTabsElement(paginationInfo) {
let showMoreItem = document.createXULElement("toolbarbutton");
showMoreItem.setAttribute("itemtype", "showmorebutton");
showMoreItem.setAttribute("closemenu", "none");
- showMoreItem.classList.add(
- "subviewbutton",
- "subviewbutton-nav",
- "subviewbutton-nav-down"
- );
+ showMoreItem.classList.add("subviewbutton", "subviewbutton-nav-down");
document.l10n.setAttributes(showMoreItem, "appmenu-remote-tabs-showmore");
paginationInfo.maxTabs = Infinity;
@@ -326,27 +341,56 @@ this.SyncedTabsPanelList = class SyncedTabsPanelList {
return showMoreItem;
}
- _createShowInactiveTabsElement(paginationInfo, count) {
+ _createShowInactiveTabsElement(client, device) {
let showItem = document.createXULElement("toolbarbutton");
- showItem.setAttribute("itemtype", "showmorebutton");
showItem.setAttribute("closemenu", "none");
- showItem.classList.add(
- "subviewbutton",
- "subviewbutton-nav",
- "subviewbutton-nav-down"
+ showItem.classList.add("subviewbutton", "subviewbutton-nav");
+ document.l10n.setAttributes(
+ showItem,
+ "appmenu-remote-tabs-show-inactive-tabs"
);
- document.l10n.setAttributes(showItem, "appmenu-remote-tabs-showinactive");
- document.l10n.setArgs(showItem, { count });
- paginationInfo.showInactive = true;
+ let canClose =
+ device && fxAccounts.commands.closeTab.isDeviceCompatible(device);
+
showItem.addEventListener("click", e => {
- e.preventDefault();
- e.stopPropagation();
- this._showSyncedTabs(paginationInfo);
+ let node = PanelMultiView.getViewNode(
+ document,
+ "PanelUI-fxa-menu-inactive-tabs"
+ );
+
+ // device name.
+ let label = node.querySelector("label[itemtype='client']");
+ label.textContent = client.name;
+
+ // Update the tab list.
+ let container = node.querySelector(".panel-subview-body");
+ container.replaceChildren(
+ ...client.tabs
+ .filter(t => t.inactive)
+ .map((tab, index) =>
+ this._createSyncedTabElement(tab, index, device, canClose)
+ )
+ );
+ PanelUI.showSubView("PanelUI-fxa-menu-inactive-tabs", showItem, e);
});
return showItem;
}
+ _createCloseTabElement(url, device) {
+ let closeBtn = document.createXULElement("image");
+ closeBtn.setAttribute("class", "close-icon remotetabs-close");
+
+ closeBtn.addEventListener("click", function (e) {
+ e.stopPropagation();
+ // The user could be hitting multiple tabs across multiple devices, with a few
+ // seconds in-between -- we should not immediately fire off pushes, so we
+ // add it to a queue and send in bulk at a later time
+ fxAccounts.commands.closeTab.enqueueTabToClose(device, url);
+ });
+ return closeBtn;
+ }
+
destroy() {
Services.obs.removeObserver(this, SyncedTabs.TOPIC_TABS_CHANGED);
this.tabsList = null;
@@ -384,7 +428,7 @@ var gSync = {
"browser/accounts.ftl",
"browser/appmenu.ftl",
"browser/sync.ftl",
- "toolkit/branding/accounts.ftl",
+ "browser/syncedTabs.ftl",
],
true
));
@@ -445,7 +489,7 @@ var gSync = {
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
- "PXI_TOOLBAR_ENABLED",
+ "FXA_CTA_MENU_ENABLED",
"identity.fxaccounts.toolbar.pxiToolbarEnabled"
);
},
@@ -533,10 +577,23 @@ var gSync = {
let fxaPanelView = PanelMultiView.getViewNode(document, "PanelUI-fxa");
fxaPanelView.addEventListener("ViewShowing", this);
fxaPanelView.addEventListener("ViewHiding", this);
+ fxaPanelView.addEventListener("command", this);
+ PanelMultiView.getViewNode(
+ document,
+ "PanelUI-fxa-menu-syncnow-button"
+ ).addEventListener("mouseover", this);
+ PanelMultiView.getViewNode(
+ document,
+ "PanelUI-fxa-menu-sendtab-not-configured-button"
+ ).addEventListener("command", this);
+ PanelMultiView.getViewNode(
+ document,
+ "PanelUI-fxa-menu-sendtab-connect-device-button"
+ ).addEventListener("command", this);
// If the experiment is enabled, we'll need to update the panels
// to show some different text to the user
- if (this.PXI_TOOLBAR_ENABLED) {
+ if (this.FXA_CTA_MENU_ENABLED) {
this.updateFxAPanel(UIState.get());
this.updateCTAPanel();
}
@@ -558,6 +615,13 @@ var gSync = {
handleEvent(event) {
switch (event.type) {
+ case "mouseover":
+ this.refreshSyncButtonsTooltip();
+ break;
+ case "command": {
+ this.onCommand(event.target);
+ break;
+ }
case "ViewShowing": {
this.onFxAPanelViewShowing(event.target);
break;
@@ -606,16 +670,61 @@ var gSync = {
panelview.syncedTabsPanelList = null;
},
+ onCommand(button) {
+ switch (button.id) {
+ case "PanelUI-fxa-menu-sync-prefs-button":
+ // fall through
+ case "PanelUI-fxa-menu-setup-sync-button":
+ this.openPrefsFromFxaMenu("sync_settings", button);
+ break;
+
+ case "PanelUI-fxa-menu-sendtab-connect-device-button":
+ // fall through
+ case "PanelUI-fxa-menu-connect-device-button":
+ this.openConnectAnotherDeviceFromFxaMenu(button);
+ break;
+
+ case "fxa-manage-account-button":
+ this.clickFxAMenuHeaderButton(button);
+ break;
+ case "PanelUI-fxa-menu-syncnow-button":
+ this.doSyncFromFxaMenu(button);
+ break;
+ case "PanelUI-fxa-menu-sendtab-button":
+ this.showSendToDeviceViewFromFxaMenu(button);
+ break;
+ case "PanelUI-fxa-menu-account-signout-button":
+ this.disconnect();
+ break;
+ case "PanelUI-fxa-menu-sync-button":
+ this.openPrefsFromFxaButton("sync_cta", button);
+ break;
+ case "PanelUI-fxa-menu-monitor-button":
+ this.openMonitorLink(button);
+ break;
+ case "PanelUI-fxa-menu-relay-button":
+ this.openRelayLink(button);
+ break;
+ case "PanelUI-fxa-menu-vpn-button":
+ this.openVPNLink(button);
+ break;
+ case "PanelUI-fxa-menu-sendtab-not-configured-button":
+ this.openPrefsFromFxaMenu("send_tab", button);
+ break;
+ }
+ },
+
observe(subject, topic, data) {
if (!this._initialized) {
console.error("browser-sync observer called after unload: ", topic);
return;
}
switch (topic) {
- case UIState.ON_UPDATE:
+ case UIState.ON_UPDATE: {
const state = UIState.get();
this.updateAllUI(state);
break;
+ }
case "quit-application":
// Stop the animation timer on shutdown, since we can't update the UI
// after this.
@@ -637,7 +746,6 @@ var gSync = {
this.updateSyncButtonsTooltip(state);
this.updateSyncStatus(state);
this.updateFxAPanel(state);
- this.updateCTAPanel(state);
// Ensure we have something in the device list in the background.
this.ensureFxaDevices();
},
@@ -648,7 +756,7 @@ var gSync = {
// shows the device list will start with `recentDeviceList`, but should also
// force a refresh, both of which should mean in the worst-case, the UI is up
// to date after a very short delay.
- async ensureFxaDevices(options) {
+ async ensureFxaDevices() {
if (UIState.get().status != UIState.STATUS_SIGNED_IN) {
console.info("Skipping device list refresh; not signed in");
return;
@@ -720,16 +828,6 @@ var gSync = {
this.emitFxaToolbarTelemetry("send_tab", anchor);
},
- showRemoteTabsFromFxaMenu(panel) {
- PanelUI.showSubView("PanelUI-remotetabs", panel);
- this.emitFxaToolbarTelemetry("sync_tabs", panel);
- },
-
- showSidebarFromFxaMenu(panel) {
- SidebarUI.toggle("viewTabsSidebar");
- this.emitFxaToolbarTelemetry("sync_tabs_sidebar", panel);
- },
-
_populateSendTabToDevicesView(panelViewNode, reloadDevices = true) {
let bodyNode = panelViewNode.querySelector(".panel-subview-body");
let panelNode = panelViewNode.closest("panel");
@@ -768,7 +866,7 @@ var gSync = {
}
}
- item.addEventListener("command", event => {
+ item.addEventListener("command", () => {
if (panelNode) {
PanelMultiView.hidePopup(panelNode);
}
@@ -830,12 +928,20 @@ var gSync = {
let fxaStatus = document.documentElement.getAttribute("fxastatus");
if (fxaStatus == "not_configured") {
+ // sign in button in app (hamburger) menu
+ // should take you straight to fxa sign in page
+ if (anchor.id == "appMenu-fxa-label2") {
+ this.openFxAEmailFirstPageFromFxaMenu(anchor);
+ PanelUI.hide();
+ return;
+ }
+
// If we're signed out but have the PXI pref enabled
// we should show the PXI panel instead of taking the user
// straight to FxA sign-in
- if (this.PXI_TOOLBAR_ENABLED) {
+ if (this.FXA_CTA_MENU_ENABLED) {
this.updateFxAPanel(UIState.get());
- this.updateCTAPanel();
+ this.updateCTAPanel(anchor);
PanelUI.showSubView("PanelUI-fxa", anchor, aEvent);
} else if (anchor == document.getElementById("fxa-toolbar-menu-button")) {
// The fxa toolbar button doesn't have much context before the user
@@ -844,20 +950,13 @@ var gSync = {
this.emitFxaToolbarTelemetry("toolbar_icon", anchor);
openTrustedLinkIn("about:preferences#sync", "tab");
PanelUI.hide();
- } else {
- let panel =
- anchor.id == "appMenu-fxa-label2"
- ? PanelMultiView.getViewNode(document, "PanelUI-fxa")
- : undefined;
- this.openFxAEmailFirstPageFromFxaMenu(panel);
- PanelUI.hide();
}
return;
}
// If the user is signed in and we have the PXI pref enabled then add
// the pxi panel to the existing toolbar
- if (this.PXI_TOOLBAR_ENABLED) {
- this.updateCTAPanel();
+ if (this.FXA_CTA_MENU_ENABLED) {
+ this.updateCTAPanel(anchor);
}
if (!gFxaToolbarAccessed) {
@@ -932,21 +1031,16 @@ var gSync = {
fxaMenuAccountButtonEl.removeAttribute("closemenu");
syncSetupButtonEl.removeAttribute("hidden");
- let headerTitleL10nId = this.PXI_TOOLBAR_ENABLED
- ? "appmenuitem-sign-in-account"
- : "appmenuitem-fxa-sign-in";
+ let headerTitleL10nId = this.FXA_CTA_MENU_ENABLED
+ ? "synced-tabs-fxa-sign-in"
+ : "appmenuitem-sign-in-account";
let headerDescription;
if (state.status === UIState.STATUS_NOT_CONFIGURED) {
mainWindowEl.style.removeProperty("--avatar-image-url");
- headerDescription = this.fluentStrings.formatValueSync(
- "appmenu-fxa-signed-in-label"
- );
- // Signed out, expeirment enabled is the only state we want to hide the
- // header description, so we make it empty and check for that when setting
- // the value
- if (this.PXI_TOOLBAR_ENABLED) {
- headerDescription = "";
- }
+ const headerDescString = this.FXA_CTA_MENU_ENABLED
+ ? "fxa-menu-sync-description"
+ : "appmenu-fxa-signed-in-label";
+ headerDescription = this.fluentStrings.formatValueSync(headerDescString);
} else if (state.status === UIState.STATUS_LOGIN_FAILED) {
stateValue = "login-failed";
headerTitleL10nId = "account-disconnected2";
@@ -1020,8 +1114,8 @@ var gSync = {
).hidden = !canSendAllURIs;
},
- emitFxaToolbarTelemetry(type, panel) {
- if (UIState.isReady() && panel) {
+ emitFxaToolbarTelemetry(type, sourceElement) {
+ if (UIState.isReady() && sourceElement) {
const state = UIState.get();
const hasAvatar = state.avatarURL && !state.avatarIsDefault;
let extraOptions = {
@@ -1029,10 +1123,10 @@ var gSync = {
fxa_avatar: hasAvatar ? "true" : "false",
};
- // When the fxa avatar panel is within the Firefox app menu,
+ // When the source element is within the Firefox app menu,
// we emit different telemetry.
let eventName = "fxa_avatar_menu";
- if (this.isPanelInsideAppMenu(panel)) {
+ if (this.isInsideAppMenu(sourceElement)) {
eventName = "fxa_app_menu";
}
@@ -1046,9 +1140,9 @@ var gSync = {
}
},
- isPanelInsideAppMenu(panel = undefined) {
+ isInsideAppMenu(sourceElement = undefined) {
const appMenuPanel = document.getElementById("appMenu-popup");
- if (panel && appMenuPanel.contains(panel)) {
+ if (sourceElement && appMenuPanel.contains(sourceElement)) {
return true;
}
return false;
@@ -1225,10 +1319,10 @@ var gSync = {
openTrustedLinkIn(url, "tab");
},
- async openConnectAnotherDeviceFromFxaMenu(panel = undefined) {
- this.emitFxaToolbarTelemetry("cad", panel);
+ async openConnectAnotherDeviceFromFxaMenu(sourceElement = undefined) {
+ this.emitFxaToolbarTelemetry("cad", sourceElement);
let entryPoint = "fxa_discoverability_native";
- if (this.isPanelInsideAppMenu(panel)) {
+ if (this.isInsideAppMenu(sourceElement)) {
entryPoint = "fxa_app_menu";
}
this.openConnectAnotherDevice(entryPoint);
@@ -1241,7 +1335,7 @@ var gSync = {
switchToTabHavingURI(url, true, { replaceQueryString: true });
},
- async clickFxAMenuHeaderButton(panel = undefined) {
+ async clickFxAMenuHeaderButton(sourceElement = undefined) {
// Depending on the current logged in state of a user,
// clicking the FxA header will either open
// a sign-in page, account management page, or sync
@@ -1249,16 +1343,16 @@ var gSync = {
const { status } = UIState.get();
switch (status) {
case UIState.STATUS_NOT_CONFIGURED:
- this.openFxAEmailFirstPageFromFxaMenu(panel);
+ this.openFxAEmailFirstPageFromFxaMenu(sourceElement);
break;
case UIState.STATUS_LOGIN_FAILED:
- this.openPrefsFromFxaMenu("sync_settings", panel);
+ this.openPrefsFromFxaMenu("sync_settings", sourceElement);
break;
case UIState.STATUS_NOT_VERIFIED:
this.openFxAEmailFirstPage("fxa_app_menu_reverify");
break;
case UIState.STATUS_SIGNED_IN:
- this.openFxAManagePageFromFxaMenu(panel);
+ this.openFxAManagePageFromFxaMenu(sourceElement);
}
},
@@ -1273,10 +1367,13 @@ var gSync = {
switchToTabHavingURI(url, true, { replaceQueryString: true });
},
- async openFxAEmailFirstPageFromFxaMenu(panel = undefined, extraParams = {}) {
- this.emitFxaToolbarTelemetry("login", panel);
+ async openFxAEmailFirstPageFromFxaMenu(
+ sourceElement = undefined,
+ extraParams = {}
+ ) {
+ this.emitFxaToolbarTelemetry("login", sourceElement);
let entryPoint = "fxa_discoverability_native";
- if (panel) {
+ if (sourceElement) {
entryPoint = "fxa_toolbar_button";
}
this.openFxAEmailFirstPage(entryPoint, extraParams);
@@ -1287,10 +1384,10 @@ var gSync = {
switchToTabHavingURI(url, true, { replaceQueryString: true });
},
- async openFxAManagePageFromFxaMenu(panel = undefined) {
- this.emitFxaToolbarTelemetry("account_settings", panel);
+ async openFxAManagePageFromFxaMenu(sourceElement = undefined) {
+ this.emitFxaToolbarTelemetry("account_settings", sourceElement);
let entryPoint = "fxa_discoverability_native";
- if (this.isPanelInsideAppMenu(panel)) {
+ if (this.isInsideAppMenu(sourceElement)) {
entryPoint = "fxa_app_menu";
}
this.openFxAManagePage(entryPoint);
@@ -1364,7 +1461,7 @@ var gSync = {
return;
}
if (!createDeviceNodeFn) {
- createDeviceNodeFn = (targetId, name, targetType, lastModified) => {
+ createDeviceNodeFn = (targetId, name) => {
let eltName = name ? "menuitem" : "menuseparator";
return document.createXULElement(eltName);
};
@@ -1462,7 +1559,7 @@ var gSync = {
fxAccounts.flushLogFile();
});
};
- const onSendAllCommand = event => {
+ const onSendAllCommand = () => {
send(targets);
};
const onTargetDeviceCommand = event => {
@@ -1893,9 +1990,9 @@ var gSync = {
}
},
- doSyncFromFxaMenu(panel) {
+ doSyncFromFxaMenu(sourceElement) {
this.doSync();
- this.emitFxaToolbarTelemetry("sync_now", panel);
+ this.emitFxaToolbarTelemetry("sync_now", sourceElement);
},
openPrefs(entryPoint = "syncbutton", origin = undefined) {
@@ -1905,18 +2002,18 @@ var gSync = {
});
},
- openPrefsFromFxaMenu(type, panel) {
- this.emitFxaToolbarTelemetry(type, panel);
+ openPrefsFromFxaMenu(type, sourceElement) {
+ this.emitFxaToolbarTelemetry(type, sourceElement);
let entryPoint = "fxa_discoverability_native";
- if (this.isPanelInsideAppMenu(panel)) {
+ if (this.isInsideAppMenu(sourceElement)) {
entryPoint = "fxa_app_menu";
}
this.openPrefs(entryPoint);
},
- openPrefsFromFxaButton(type, panel) {
+ openPrefsFromFxaButton(type, sourceElement) {
let entryPoint = "fxa_toolbar_button_sync";
- this.emitFxaToolbarTelemetry(type, panel);
+ this.emitFxaToolbarTelemetry(type, sourceElement);
this.openPrefs(entryPoint);
},
@@ -2049,27 +2146,24 @@ var gSync = {
// This should only be shown if we have enabled the pxiPanel via
// an experiment or explicitly through prefs
- updateCTAPanel() {
+ updateCTAPanel(anchor) {
const mainPanelEl = PanelMultiView.getViewNode(
document,
"PanelUI-fxa-cta-menu"
);
- const syncCtaEl = PanelMultiView.getViewNode(
- document,
- "PanelUI-fxa-menu-sync-button"
- );
- // If we're not in the experiment then we do not enable this at all
- if (!this.PXI_TOOLBAR_ENABLED) {
+ // If we're not in the experiment or in the app menu (hamburger)
+ // do not show this CTA panel
+ if (
+ !this.FXA_CTA_MENU_ENABLED ||
+ (anchor && anchor.id === "appMenu-fxa-label2")
+ ) {
// If we've previously shown this but got disabled
// we should ensure we hide the panel
mainPanelEl.hidden = true;
return;
}
- // If we're already signed in an syncing, we shouldn't show the sync CTA
- syncCtaEl.hidden = this.isSignedIn;
-
// Monitor checks
let monitorPanelEl = PanelMultiView.getViewNode(
document,
@@ -2112,8 +2206,8 @@ var gSync = {
!monitorEnabled && !relayEnabled && !vpnEnabled;
mainPanelEl.hidden = false;
},
- async openMonitorLink(panel) {
- this.emitFxaToolbarTelemetry("monitor_cta", panel);
+ async openMonitorLink(sourceElement) {
+ this.emitFxaToolbarTelemetry("monitor_cta", sourceElement);
await this.openCtaLink(
FX_MONITOR_OAUTH_CLIENT_ID,
new URL("https://monitor.firefox.com"),
@@ -2121,8 +2215,8 @@ var gSync = {
);
},
- async openRelayLink(panel) {
- this.emitFxaToolbarTelemetry("relay_cta", panel);
+ async openRelayLink(sourceElement) {
+ this.emitFxaToolbarTelemetry("relay_cta", sourceElement);
await this.openCtaLink(
FX_RELAY_OAUTH_CLIENT_ID,
new URL("https://relay.firefox.com"),
@@ -2130,8 +2224,8 @@ var gSync = {
);
},
- async openVPNLink(panel) {
- this.emitFxaToolbarTelemetry("vpn_cta", panel);
+ async openVPNLink(sourceElement) {
+ this.emitFxaToolbarTelemetry("vpn_cta", sourceElement);
await this.openCtaLink(
VPN_OAUTH_CLIENT_ID,
new URL("https://www.mozilla.org/en-US/products/vpn/"),
diff --git a/browser/base/content/browser-tabsintitlebar.js b/browser/base/content/browser-tabsintitlebar.js
index caf9986b2f..d7f71ed450 100644
--- a/browser/base/content/browser-tabsintitlebar.js
+++ b/browser/base/content/browser-tabsintitlebar.js
@@ -43,7 +43,7 @@ var TabsInTitlebar = {
return document.documentElement.getAttribute("tabsintitlebar") == "true";
},
- observe(subject, topic, data) {
+ observe(subject, topic) {
if (topic == "nsPref:changed") {
this._readPref();
}
diff --git a/browser/base/content/browser-thumbnails.js b/browser/base/content/browser-thumbnails.js
index 1162914ddf..2ca6148b67 100644
--- a/browser/base/content/browser-thumbnails.js
+++ b/browser/base/content/browser-thumbnails.js
@@ -103,7 +103,7 @@ var gBrowserThumbnails = {
ChromeUtils.defineLazyGetter(this, "_topSiteURLs", getTopSiteURLs);
},
- notify: function Thumbnails_notify(timer) {
+ notify: function Thumbnails_notify() {
gBrowserThumbnails._topSiteURLsRefreshTimer = null;
gBrowserThumbnails.clearTopSiteURLCache();
},
@@ -116,7 +116,7 @@ var gBrowserThumbnails = {
aWebProgress,
aRequest,
aStateFlags,
- aStatus
+ _aStatus
) {
if (
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
diff --git a/browser/base/content/browser-toolbarKeyNav.js b/browser/base/content/browser-toolbarKeyNav.js
index caa01100c5..c65d99f6f0 100644
--- a/browser/base/content/browser-toolbarKeyNav.js
+++ b/browser/base/content/browser-toolbarKeyNav.js
@@ -137,7 +137,7 @@ ToolbarKeyboardNavigator = {
},
// CustomizableUI event handler
- onWidgetAdded(aWidgetId, aArea, aPosition) {
+ onWidgetAdded(aWidgetId, aArea) {
if (!this.kToolbars.includes(aArea)) {
return;
}
diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css
index c9ebddb7f5..6e776a9ce7 100644
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -250,8 +250,7 @@ toolbar[customizing] > .overflow-button {
display: none;
}
-toolbar[customizing] #ion-button,
-toolbar[customizing] #whats-new-menu-button {
+toolbar[customizing] #ion-button {
display: none;
}
@@ -382,7 +381,7 @@ toolbarpaletteitem {
toolbar[brighttext] & {
list-style-image: var(--webextension-toolbar-image-light, inherit);
}
- toolbar:not([brighttext]) &:-moz-lwtheme {
+ :root[lwtheme] toolbar:not([brighttext]) & {
list-style-image: var(--webextension-toolbar-image-dark, inherit);
}
toolbaritem:is([overflowedItem="true"], [cui-areatype="panel"]) > & {
@@ -480,12 +479,6 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
flex: 1;
}
-@media (-moz-platform: macos) {
- :root[inFullscreen="true"] {
- padding-top: 0; /* override drawintitlebar="true" */
- }
-}
-
/* Hide menu elements intended for keyboard access support */
#main-menubar[openedwithkey=false] .show-only-for-keyboard {
display: none;
@@ -916,7 +909,7 @@ menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
position: absolute;
}
-browser[tabmodalPromptShowing], browser[tabDialogShowing] {
+browser[tabDialogShowing] {
-moz-user-focus: none !important;
}
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index c91a5d4db2..5f41ca7781 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -9,6 +9,9 @@ var { XPCOMUtils } = ChromeUtils.importESModule(
var { AppConstants } = ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
+ChromeUtils.importESModule(
+ "resource://gre/modules/MemoryNotificationDB.sys.mjs"
+);
ChromeUtils.importESModule("resource://gre/modules/NotificationDB.sys.mjs");
// lazy module getters
@@ -35,8 +38,6 @@ ChromeUtils.defineESModuleGetters(this, {
DownloadsCommon: "resource:///modules/DownloadsCommon.sys.mjs",
E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs",
ExtensionsUI: "resource:///modules/ExtensionsUI.sys.mjs",
- FirefoxViewNotificationManager:
- "resource:///modules/firefox-view-notification-manager.sys.mjs",
HomePage: "resource:///modules/HomePage.sys.mjs",
isProductURL: "chrome://global/content/shopping/ShoppingProduct.mjs",
LightweightThemeConsumer:
@@ -79,7 +80,6 @@ ChromeUtils.defineESModuleGetters(this, {
SubDialog: "resource://gre/modules/SubDialog.sys.mjs",
SubDialogManager: "resource://gre/modules/SubDialog.sys.mjs",
TabCrashHandler: "resource:///modules/ContentCrashHandlers.sys.mjs",
- TabModalPrompt: "chrome://global/content/tabprompts.sys.mjs",
TabsSetupFlowManager:
"resource:///modules/firefox-view-tabs-setup-manager.sys.mjs",
TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs",
@@ -109,6 +109,12 @@ ChromeUtils.defineLazyGetter(this, "fxAccounts", () => {
XPCOMUtils.defineLazyScriptGetter(
this,
+ ["BrowserCommands", "kSkipCacheFlags"],
+ "chrome://browser/content/browser-commands.js"
+);
+
+XPCOMUtils.defineLazyScriptGetter(
+ this,
"PlacesTreeView",
"chrome://browser/content/places/treeView.js"
);
@@ -546,7 +552,7 @@ XPCOMUtils.defineLazyPreferenceGetter(
"gFxaToolbarAccessed",
"identity.fxaccounts.toolbar.accessed",
false,
- (aPref, aOldVal, aNewVal) => {
+ () => {
updateFxaToolbarMenu(gFxaToolbarEnabled);
}
);
@@ -691,7 +697,6 @@ function shouldSuppressPopupNotifications() {
// don't cover up the prompt.
return (
window.windowState == window.STATE_MINIMIZED ||
- gBrowser?.selectedBrowser.hasAttribute("tabmodalChromePromptShowing") ||
gBrowser?.selectedBrowser.hasAttribute("tabDialogShowing") ||
gDialogBox?.isOpen
);
@@ -1019,7 +1024,7 @@ const gClickAndHoldListenersOnElement = {
};
const gSessionHistoryObserver = {
- observe(subject, topic, data) {
+ observe(subject, topic) {
if (topic != "browser:purge-session-history") {
return;
}
@@ -1037,7 +1042,7 @@ const gSessionHistoryObserver = {
const gStoragePressureObserver = {
_lastNotificationTime: -1,
- async observe(subject, topic, data) {
+ async observe(subject, topic) {
if (topic != "QuotaManager::StoragePressure") {
return;
}
@@ -1088,7 +1093,7 @@ const gStoragePressureObserver = {
document.l10n.setAttributes(message, "space-alert-over-5gb-message2");
buttons.push({
"l10n-id": "space-alert-over-5gb-settings-button",
- callback(notificationBar, button) {
+ callback() {
// The advanced subpanes are only supported in the old organization, which will
// be removed by bug 1349689.
openPreferences("privacy-sitedata");
@@ -1475,7 +1480,7 @@ var gKeywordURIFixup = {
);
},
- observe(fixupInfo, topic, data) {
+ observe(fixupInfo) {
fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);
let browser = fixupInfo.consumer?.top?.embedderElement;
@@ -1499,1154 +1504,36 @@ function _createNullPrincipalFromTabUserContextId(tab = gBrowser.selectedTab) {
});
}
-let _resolveDelayedStartup;
-var delayedStartupPromise = new Promise(resolve => {
- _resolveDelayedStartup = resolve;
-});
-
-var gBrowserInit = {
- delayedStartupFinished: false,
- idleTasksFinishedPromise: null,
- idleTaskPromiseResolve: null,
- domContentLoaded: false,
-
- _tabToAdopt: undefined,
-
- _setupFirstContentWindowPaintPromise() {
- let lastTransactionId = window.windowUtils.lastTransactionId;
- let layerTreeListener = () => {
- if (this.getTabToAdopt()) {
- // Need to wait until we finish adopting the tab, or we might end
- // up focusing the initial browser and then losing focus when it
- // gets swapped out for the tab to adopt.
- return;
- }
- removeEventListener("MozLayerTreeReady", layerTreeListener);
- let listener = e => {
- if (e.transactionId > lastTransactionId) {
- window.removeEventListener("MozAfterPaint", listener);
- this._firstContentWindowPaintDeferred.resolve();
- }
- };
- addEventListener("MozAfterPaint", listener);
- };
- addEventListener("MozLayerTreeReady", layerTreeListener);
- },
-
- getTabToAdopt() {
- if (this._tabToAdopt !== undefined) {
- return this._tabToAdopt;
- }
-
- if (window.arguments && window.XULElement.isInstance(window.arguments[0])) {
- this._tabToAdopt = window.arguments[0];
-
- // Clear the reference of the tab being adopted from the arguments.
- window.arguments[0] = null;
- } else {
- // There was no tab to adopt in the arguments, set _tabToAdopt to null
- // to avoid checking it again.
- this._tabToAdopt = null;
- }
-
- return this._tabToAdopt;
- },
-
- _clearTabToAdopt() {
- this._tabToAdopt = null;
- },
-
- // Used to check if the new window is still adopting an existing tab as its first tab
- // (e.g. from the WebExtensions internals).
- isAdoptingTab() {
- return !!this.getTabToAdopt();
- },
-
- onBeforeInitialXULLayout() {
- this._setupFirstContentWindowPaintPromise();
-
- updateBookmarkToolbarVisibility();
-
- // Set a sane starting width/height for all resolutions on new profiles.
- if (ChromeUtils.shouldResistFingerprinting("RoundWindowSize", null)) {
- // When the fingerprinting resistance is enabled, making sure that we don't
- // have a maximum window to interfere with generating rounded window dimensions.
- document.documentElement.setAttribute("sizemode", "normal");
- } else if (!document.documentElement.hasAttribute("width")) {
- const TARGET_WIDTH = 1280;
- const TARGET_HEIGHT = 1040;
- let width = Math.min(screen.availWidth * 0.9, TARGET_WIDTH);
- let height = Math.min(screen.availHeight * 0.9, TARGET_HEIGHT);
-
- document.documentElement.setAttribute("width", width);
- document.documentElement.setAttribute("height", height);
-
- if (width < TARGET_WIDTH && height < TARGET_HEIGHT) {
- document.documentElement.setAttribute("sizemode", "maximized");
- }
- }
- if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
- const toolbarMenubar = document.getElementById("toolbar-menubar");
- // set a default value
- if (!toolbarMenubar.hasAttribute("autohide")) {
- toolbarMenubar.setAttribute("autohide", true);
- }
- document.l10n.setAttributes(
- toolbarMenubar,
- "toolbar-context-menu-menu-bar-cmd"
- );
- toolbarMenubar.setAttribute("data-l10n-attrs", "toolbarname");
- }
-
- // Run menubar initialization first, to avoid TabsInTitlebar code picking
- // up mutations from it and causing a reflow.
- AutoHideMenubar.init();
- // Update the chromemargin attribute so the window can be sized correctly.
- window.TabBarVisibility.update();
- TabsInTitlebar.init();
-
- new LightweightThemeConsumer(document);
-
- if (
- Services.prefs.getBoolPref(
- "toolkit.legacyUserProfileCustomizations.windowIcon",
- false
- )
- ) {
- document.documentElement.setAttribute("icon", "main-window");
- }
-
- // Call this after we set attributes that might change toolbars' computed
- // text color.
- ToolbarIconColor.init();
- },
-
- onDOMContentLoaded() {
- // This needs setting up before we create the first remote browser.
- window.docShell.treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIAppWindow).XULBrowserWindow = window.XULBrowserWindow;
- window.browserDOMWindow = new nsBrowserAccess();
-
- gBrowser = window._gBrowser;
- delete window._gBrowser;
- gBrowser.init();
-
- BrowserWindowTracker.track(window);
-
- FirefoxViewHandler.init();
-
- gNavToolbox.palette = document.getElementById(
- "BrowserToolbarPalette"
- ).content;
- for (let area of CustomizableUI.areas) {
- let type = CustomizableUI.getAreaType(area);
- if (type == CustomizableUI.TYPE_TOOLBAR) {
- let node = document.getElementById(area);
- CustomizableUI.registerToolbarNode(node);
- }
- }
- BrowserSearch.initPlaceHolder();
-
- // Hack to ensure that the various initial pages favicon is loaded
- // instantaneously, to avoid flickering and improve perceived performance.
- this._callWithURIToLoad(uriToLoad => {
- let url;
- try {
- url = Services.io.newURI(uriToLoad);
- } catch (e) {
- return;
- }
- let nonQuery = url.prePath + url.filePath;
- if (nonQuery in gPageIcons) {
- gBrowser.setIcon(gBrowser.selectedTab, gPageIcons[nonQuery]);
- }
- });
-
- updateFxaToolbarMenu(gFxaToolbarEnabled, true);
-
- updatePrintCommands(gPrintEnabled);
-
- gUnifiedExtensions.init();
-
- // Setting the focus will cause a style flush, it's preferable to call anything
- // that will modify the DOM from within this function before this call.
- this._setInitialFocus();
-
- this.domContentLoaded = true;
- },
-
- onLoad() {
- gBrowser.addEventListener("DOMUpdateBlockedPopups", gPopupBlockerObserver);
- gBrowser.addEventListener(
- "TranslationsParent:LanguageState",
- FullPageTranslationsPanel
- );
- gBrowser.addEventListener(
- "TranslationsParent:OfferTranslation",
- FullPageTranslationsPanel
- );
- gBrowser.addTabsProgressListener(FullPageTranslationsPanel);
-
- window.addEventListener("AppCommand", HandleAppCommandEvent, true);
-
- // These routines add message listeners. They must run before
- // loading the frame script to ensure that we don't miss any
- // message sent between when the frame script is loaded and when
- // the listener is registered.
- CaptivePortalWatcher.init();
- ZoomUI.init(window);
-
- if (!gMultiProcessBrowser) {
- // There is a Content:Click message manually sent from content.
- gBrowser.tabpanels.addEventListener("click", contentAreaClick, {
- capture: true,
- mozSystemGroup: true,
- });
- }
-
- // hook up UI through progress listener
- gBrowser.addProgressListener(window.XULBrowserWindow);
- gBrowser.addTabsProgressListener(window.TabsProgressListener);
-
- SidebarUI.init();
-
- // We do this in onload because we want to ensure the button's state
- // doesn't flicker as the window is being shown.
- DownloadsButton.init();
-
- // Certain kinds of automigration rely on this notification to complete
- // their tasks BEFORE the browser window is shown. SessionStore uses it to
- // restore tabs into windows AFTER important parts like gMultiProcessBrowser
- // have been initialized.
- Services.obs.notifyObservers(window, "browser-window-before-show");
-
- if (!window.toolbar.visible) {
- // adjust browser UI for popups
- gURLBar.readOnly = true;
- }
-
- // Misc. inits.
- gUIDensity.init();
- TabletModeUpdater.init();
- CombinedStopReload.ensureInitialized();
- gPrivateBrowsingUI.init();
- BrowserSearch.init();
- BrowserPageActions.init();
- if (gToolbarKeyNavEnabled) {
- ToolbarKeyboardNavigator.init();
- }
-
- // Update UI if browser is under remote control.
- gRemoteControl.updateVisualCue();
-
- // If we are given a tab to swap in, take care of it before first paint to
- // avoid an about:blank flash.
- let tabToAdopt = this.getTabToAdopt();
- if (tabToAdopt) {
- let evt = new CustomEvent("before-initial-tab-adopted", {
- bubbles: true,
- });
- gBrowser.tabpanels.dispatchEvent(evt);
-
- // Stop the about:blank load
- gBrowser.stop();
-
- // Remove the speculative focus from the urlbar to let the url be formatted.
- gURLBar.removeAttribute("focused");
-
- let swapBrowsers = () => {
- try {
- gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToAdopt);
- } catch (e) {
- console.error(e);
- }
-
- // Clear the reference to the tab once its adoption has been completed.
- this._clearTabToAdopt();
- };
- if (tabToAdopt.linkedBrowser.isRemoteBrowser) {
- // For remote browsers, wait for the paint event, otherwise the tabs
- // are not yet ready and focus gets confused because the browser swaps
- // out while tabs are switching.
- addEventListener("MozAfterPaint", swapBrowsers, { once: true });
- } else {
- swapBrowsers();
- }
- }
-
- // Wait until chrome is painted before executing code not critical to making the window visible
- this._boundDelayedStartup = this._delayedStartup.bind(this);
- window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
-
- if (!PrivateBrowsingUtils.enabled) {
- document.getElementById("Tools:PrivateBrowsing").hidden = true;
- // Setting disabled doesn't disable the shortcut, so we just remove
- // the keybinding.
- document.getElementById("key_privatebrowsing").remove();
- }
-
- if (BrowserUIUtils.quitShortcutDisabled) {
- document.getElementById("key_quitApplication").remove();
- document.getElementById("menu_FileQuitItem").removeAttribute("key");
-
- PanelMultiView.getViewNode(
- document,
- "appMenu-quit-button2"
- )?.removeAttribute("key");
- }
-
- this._loadHandled = true;
- },
-
- _cancelDelayedStartup() {
- window.removeEventListener("MozAfterPaint", this._boundDelayedStartup);
- this._boundDelayedStartup = null;
- },
-
- _delayedStartup() {
- let { TelemetryTimestamps } = ChromeUtils.importESModule(
- "resource://gre/modules/TelemetryTimestamps.sys.mjs"
- );
- TelemetryTimestamps.add("delayedStartupStarted");
-
- this._cancelDelayedStartup();
-
- // Bug 1531854 - The hidden window is force-created here
- // until all of its dependencies are handled.
- Services.appShell.hiddenDOMWindow;
-
- gBrowser.addEventListener(
- "PermissionStateChange",
- function () {
- gIdentityHandler.refreshIdentityBlock();
- gPermissionPanel.updateSharingIndicator();
- },
- true
- );
-
- this._handleURIToLoad();
-
- Services.obs.addObserver(gIdentityHandler, "perm-changed");
- Services.obs.addObserver(gRemoteControl, "devtools-socket");
- Services.obs.addObserver(gRemoteControl, "marionette-listening");
- Services.obs.addObserver(gRemoteControl, "remote-listening");
- Services.obs.addObserver(
- gSessionHistoryObserver,
- "browser:purge-session-history"
- );
- Services.obs.addObserver(
- gStoragePressureObserver,
- "QuotaManager::StoragePressure"
- );
- Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled");
- Services.obs.addObserver(gXPInstallObserver, "addon-install-started");
- Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked");
- Services.obs.addObserver(
- gXPInstallObserver,
- "addon-install-fullscreen-blocked"
- );
- Services.obs.addObserver(
- gXPInstallObserver,
- "addon-install-origin-blocked"
- );
- Services.obs.addObserver(
- gXPInstallObserver,
- "addon-install-policy-blocked"
- );
- Services.obs.addObserver(
- gXPInstallObserver,
- "addon-install-webapi-blocked"
- );
- Services.obs.addObserver(gXPInstallObserver, "addon-install-failed");
- Services.obs.addObserver(gXPInstallObserver, "addon-install-confirmation");
- Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup");
-
- BrowserOffline.init();
- CanvasPermissionPromptHelper.init();
- WebAuthnPromptHelper.init();
- ContentAnalysis.initialize();
-
- // Initialize the full zoom setting.
- // We do this before the session restore service gets initialized so we can
- // apply full zoom settings to tabs restored by the session restore service.
- FullZoom.init();
- PanelUI.init(shouldSuppressPopupNotifications);
- ReportBrokenSite.init(gBrowser);
-
- UpdateUrlbarSearchSplitterState();
-
- BookmarkingUI.init();
- BrowserSearch.delayedStartupInit();
- SearchUIUtils.init();
- gProtectionsHandler.init();
- HomePage.delayedStartup().catch(console.error);
-
- let safeMode = document.getElementById("helpSafeMode");
- if (Services.appinfo.inSafeMode) {
- document.l10n.setAttributes(safeMode, "menu-help-exit-troubleshoot-mode");
- safeMode.setAttribute(
- "appmenu-data-l10n-id",
- "appmenu-help-exit-troubleshoot-mode"
- );
- }
-
- // BiDi UI
- gBidiUI = isBidiEnabled();
- if (gBidiUI) {
- document.getElementById("documentDirection-separator").hidden = false;
- document.getElementById("documentDirection-swap").hidden = false;
- document.getElementById("textfieldDirection-separator").hidden = false;
- document.getElementById("textfieldDirection-swap").hidden = false;
- }
-
- // Setup click-and-hold gestures access to the session history
- // menus if global click-and-hold isn't turned on
- if (!Services.prefs.getBoolPref("ui.click_hold_context_menus", false)) {
- SetClickAndHoldHandlers();
- }
-
- function initBackForwardButtonTooltip(tooltipId, l10nId, shortcutId) {
- let shortcut = document.getElementById(shortcutId);
- shortcut = ShortcutUtils.prettifyShortcut(shortcut);
-
- let tooltip = document.getElementById(tooltipId);
- document.l10n.setAttributes(tooltip, l10nId, { shortcut });
- }
-
- initBackForwardButtonTooltip(
- "back-button-tooltip-description",
- "navbar-tooltip-back-2",
- "goBackKb"
- );
-
- initBackForwardButtonTooltip(
- "forward-button-tooltip-description",
- "navbar-tooltip-forward-2",
- "goForwardKb"
- );
-
- PlacesToolbarHelper.init();
-
- ctrlTab.readPref();
- Services.prefs.addObserver(ctrlTab.prefName, ctrlTab);
-
- // The object handling the downloads indicator is initialized here in the
- // delayed startup function, but the actual indicator element is not loaded
- // unless there are downloads to be displayed.
- DownloadsButton.initializeIndicator();
-
- if (AppConstants.platform != "macosx") {
- updateEditUIVisibility();
- let placesContext = document.getElementById("placesContext");
- placesContext.addEventListener("popupshowing", updateEditUIVisibility);
- placesContext.addEventListener("popuphiding", updateEditUIVisibility);
- }
-
- FullScreen.init();
- MenuTouchModeObserver.init();
-
- if (AppConstants.MOZ_DATA_REPORTING) {
- gDataNotificationInfoBar.init();
- }
-
- if (!AppConstants.MOZILLA_OFFICIAL) {
- DevelopmentHelpers.init();
- }
-
- gExtensionsNotifications.init();
-
- let wasMinimized = window.windowState == window.STATE_MINIMIZED;
- window.addEventListener("sizemodechange", () => {
- let isMinimized = window.windowState == window.STATE_MINIMIZED;
- if (wasMinimized != isMinimized) {
- wasMinimized = isMinimized;
- UpdatePopupNotificationsVisibility();
- }
- });
-
- window.addEventListener("mousemove", MousePosTracker);
- window.addEventListener("dragover", MousePosTracker);
-
- gNavToolbox.addEventListener("customizationstarting", CustomizationHandler);
- gNavToolbox.addEventListener("aftercustomization", CustomizationHandler);
-
- SessionStore.promiseInitialized.then(() => {
- // Bail out if the window has been closed in the meantime.
- if (window.closed) {
- return;
- }
-
- // Enable the Restore Last Session command if needed
- RestoreLastSessionObserver.init();
-
- SidebarUI.startDelayedLoad();
-
- PanicButtonNotifier.init();
- });
-
- if (BrowserHandler.kiosk) {
- // We don't modify popup windows for kiosk mode
- if (!gURLBar.readOnly) {
- window.fullScreen = true;
- }
- }
-
- if (Services.policies.status === Services.policies.ACTIVE) {
- if (!Services.policies.isAllowed("hideShowMenuBar")) {
- document
- .getElementById("toolbar-menubar")
- .removeAttribute("toolbarname");
- }
- if (!Services.policies.isAllowed("filepickers")) {
- let savePageCommand = document.getElementById("Browser:SavePage");
- let openFileCommand = document.getElementById("Browser:OpenFile");
-
- savePageCommand.setAttribute("disabled", "true");
- openFileCommand.setAttribute("disabled", "true");
-
- document.addEventListener("FilePickerBlocked", function (event) {
- let browser = event.target;
-
- let notificationBox = browser
- .getTabBrowser()
- ?.getNotificationBox(browser);
-
- // Prevent duplicate notifications
- if (
- notificationBox &&
- !notificationBox.getNotificationWithValue("filepicker-blocked")
- ) {
- notificationBox.appendNotification("filepicker-blocked", {
- label: {
- "l10n-id": "filepicker-blocked-infobar",
- },
- priority: notificationBox.PRIORITY_INFO_LOW,
- });
- }
- });
- }
- let policies = Services.policies.getActivePolicies();
- if ("ManagedBookmarks" in policies) {
- let managedBookmarks = policies.ManagedBookmarks;
- let children = managedBookmarks.filter(
- child => !("toplevel_name" in child)
- );
- if (children.length) {
- let managedBookmarksButton =
- document.createXULElement("toolbarbutton");
- managedBookmarksButton.setAttribute("id", "managed-bookmarks");
- managedBookmarksButton.setAttribute("class", "bookmark-item");
- let toplevel = managedBookmarks.find(
- element => "toplevel_name" in element
- );
- if (toplevel) {
- managedBookmarksButton.setAttribute(
- "label",
- toplevel.toplevel_name
- );
- } else {
- document.l10n.setAttributes(
- managedBookmarksButton,
- "managed-bookmarks"
- );
- }
- managedBookmarksButton.setAttribute("context", "placesContext");
- managedBookmarksButton.setAttribute("container", "true");
- managedBookmarksButton.setAttribute("removable", "false");
- managedBookmarksButton.setAttribute("type", "menu");
-
- let managedBookmarksPopup = document.createXULElement("menupopup");
- managedBookmarksPopup.setAttribute("id", "managed-bookmarks-popup");
- managedBookmarksPopup.setAttribute(
- "oncommand",
- "PlacesToolbarHelper.openManagedBookmark(event);"
- );
- managedBookmarksPopup.setAttribute(
- "ondragover",
- "event.dataTransfer.effectAllowed='none';"
- );
- managedBookmarksPopup.setAttribute(
- "ondragstart",
- "PlacesToolbarHelper.onDragStartManaged(event);"
- );
- managedBookmarksPopup.setAttribute(
- "onpopupshowing",
- "PlacesToolbarHelper.populateManagedBookmarks(this);"
- );
- managedBookmarksPopup.setAttribute("placespopup", "true");
- managedBookmarksPopup.setAttribute("is", "places-popup");
- managedBookmarksPopup.classList.add("toolbar-menupopup");
- managedBookmarksButton.appendChild(managedBookmarksPopup);
-
- gNavToolbox.palette.appendChild(managedBookmarksButton);
-
- CustomizableUI.ensureWidgetPlacedInWindow(
- "managed-bookmarks",
- window
- );
-
- // Add button if it doesn't exist
- if (!CustomizableUI.getPlacementOfWidget("managed-bookmarks")) {
- CustomizableUI.addWidgetToArea(
- "managed-bookmarks",
- CustomizableUI.AREA_BOOKMARKS,
- 0
- );
- }
- }
- }
- }
-
- CaptivePortalWatcher.delayedStartup();
-
- ShoppingSidebarManager.ensureInitialized();
-
- SessionStore.promiseAllWindowsRestored.then(() => {
- this._schedulePerWindowIdleTasks();
- document.documentElement.setAttribute("sessionrestored", "true");
- });
-
- this.delayedStartupFinished = true;
- _resolveDelayedStartup();
- Services.obs.notifyObservers(window, "browser-delayed-startup-finished");
- TelemetryTimestamps.add("delayedStartupFinished");
- // We've announced that delayed startup has finished. Do not add code past this point.
- },
-
- /**
- * Resolved on the first MozLayerTreeReady and next MozAfterPaint in the
- * parent process.
- */
- get firstContentWindowPaintPromise() {
- return this._firstContentWindowPaintDeferred.promise;
- },
-
- _setInitialFocus() {
- let initiallyFocusedElement = document.commandDispatcher.focusedElement;
-
- // To prevent startup flicker, the urlbar has the 'focused' attribute set
- // by default. If we are not sure the urlbar will be focused in this
- // window, we need to remove the attribute before first paint.
- // TODO (bug 1629956): The urlbar having the 'focused' attribute by default
- // isn't a useful optimization anymore since UrlbarInput needs layout
- // information to focus the urlbar properly.
- let shouldRemoveFocusedAttribute = true;
-
- this._callWithURIToLoad(uriToLoad => {
- if (
- isBlankPageURL(uriToLoad) ||
- uriToLoad == "about:privatebrowsing" ||
- this.getTabToAdopt()?.isEmpty
- ) {
- gURLBar.select();
- shouldRemoveFocusedAttribute = false;
- return;
- }
-
- // If the initial browser is remote, in order to optimize for first paint,
- // we'll defer switching focus to that browser until it has painted.
- // Otherwise use a regular promise to guarantee that mutationobserver
- // microtasks that could affect focusability have run.
- let promise = gBrowser.selectedBrowser.isRemoteBrowser
- ? this.firstContentWindowPaintPromise
- : Promise.resolve();
-
- promise.then(() => {
- // If focus didn't move while we were waiting, we're okay to move to
- // the browser.
- if (
- document.commandDispatcher.focusedElement == initiallyFocusedElement
- ) {
- gBrowser.selectedBrowser.focus();
- }
- });
- });
-
- // Delay removing the attribute using requestAnimationFrame to avoid
- // invalidating styles multiple times in a row if uriToLoadPromise
- // resolves before first paint.
- if (shouldRemoveFocusedAttribute) {
- window.requestAnimationFrame(() => {
- if (shouldRemoveFocusedAttribute) {
- gURLBar.removeAttribute("focused");
- }
- });
- }
- },
-
- _handleURIToLoad() {
- this._callWithURIToLoad(uriToLoad => {
- if (!uriToLoad) {
- // We don't check whether window.arguments[5] (userContextId) is set
- // because tabbrowser.js takes care of that for the initial tab.
- return;
- }
-
- // We don't check if uriToLoad is a XULElement because this case has
- // already been handled before first paint, and the argument cleared.
- if (Array.isArray(uriToLoad)) {
- // This function throws for certain malformed URIs, so use exception handling
- // so that we don't disrupt startup
- try {
- gBrowser.loadTabs(uriToLoad, {
- inBackground: false,
- replace: true,
- // See below for the semantics of window.arguments. Only the minimum is supported.
- userContextId: window.arguments[5],
- triggeringPrincipal:
- window.arguments[8] ||
- Services.scriptSecurityManager.getSystemPrincipal(),
- allowInheritPrincipal: window.arguments[9],
- csp: window.arguments[10],
- fromExternal: true,
- });
- } catch (e) {}
- } else if (window.arguments.length >= 3) {
- // window.arguments[1]: extraOptions (nsIPropertyBag)
- // [2]: referrerInfo (nsIReferrerInfo)
- // [3]: postData (nsIInputStream)
- // [4]: allowThirdPartyFixup (bool)
- // [5]: userContextId (int)
- // [6]: originPrincipal (nsIPrincipal)
- // [7]: originStoragePrincipal (nsIPrincipal)
- // [8]: triggeringPrincipal (nsIPrincipal)
- // [9]: allowInheritPrincipal (bool)
- // [10]: csp (nsIContentSecurityPolicy)
- // [11]: nsOpenWindowInfo
- let userContextId =
- window.arguments[5] != undefined
- ? window.arguments[5]
- : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
-
- let hasValidUserGestureActivation = undefined;
- let fromExternal = undefined;
- let globalHistoryOptions = undefined;
- let triggeringRemoteType = undefined;
- let forceAllowDataURI = false;
- let wasSchemelessInput = false;
- if (window.arguments[1]) {
- if (!(window.arguments[1] instanceof Ci.nsIPropertyBag2)) {
- throw new Error(
- "window.arguments[1] must be null or Ci.nsIPropertyBag2!"
- );
- }
-
- let extraOptions = window.arguments[1];
- if (extraOptions.hasKey("hasValidUserGestureActivation")) {
- hasValidUserGestureActivation = extraOptions.getPropertyAsBool(
- "hasValidUserGestureActivation"
- );
- }
- if (extraOptions.hasKey("fromExternal")) {
- fromExternal = extraOptions.getPropertyAsBool("fromExternal");
- }
- if (extraOptions.hasKey("triggeringSponsoredURL")) {
- globalHistoryOptions = {
- triggeringSponsoredURL: extraOptions.getPropertyAsACString(
- "triggeringSponsoredURL"
- ),
- };
- if (extraOptions.hasKey("triggeringSponsoredURLVisitTimeMS")) {
- globalHistoryOptions.triggeringSponsoredURLVisitTimeMS =
- extraOptions.getPropertyAsUint64(
- "triggeringSponsoredURLVisitTimeMS"
- );
- }
- }
- if (extraOptions.hasKey("triggeringRemoteType")) {
- triggeringRemoteType = extraOptions.getPropertyAsACString(
- "triggeringRemoteType"
- );
- }
- if (extraOptions.hasKey("forceAllowDataURI")) {
- forceAllowDataURI =
- extraOptions.getPropertyAsBool("forceAllowDataURI");
- }
- if (extraOptions.hasKey("wasSchemelessInput")) {
- wasSchemelessInput =
- extraOptions.getPropertyAsBool("wasSchemelessInput");
- }
- }
-
- try {
- openLinkIn(uriToLoad, "current", {
- referrerInfo: window.arguments[2] || null,
- postData: window.arguments[3] || null,
- allowThirdPartyFixup: window.arguments[4] || false,
- userContextId,
- // pass the origin principal (if any) and force its use to create
- // an initial about:blank viewer if present:
- originPrincipal: window.arguments[6],
- originStoragePrincipal: window.arguments[7],
- triggeringPrincipal: window.arguments[8],
- // TODO fix allowInheritPrincipal to default to false.
- // Default to true unless explicitly set to false because of bug 1475201.
- allowInheritPrincipal: window.arguments[9] !== false,
- csp: window.arguments[10],
- forceAboutBlankViewerInCurrent: !!window.arguments[6],
- forceAllowDataURI,
- hasValidUserGestureActivation,
- fromExternal,
- globalHistoryOptions,
- triggeringRemoteType,
- wasSchemelessInput,
- });
- } catch (e) {
- console.error(e);
- }
-
- window.focus();
- } else {
- // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
- // Such callers expect that window.arguments[0] is handled as a single URI.
- loadOneOrMoreURIs(
- uriToLoad,
- Services.scriptSecurityManager.getSystemPrincipal(),
- null
- );
- }
- });
- },
-
- /**
- * Use this function as an entry point to schedule tasks that
- * need to run once per window after startup, and can be scheduled
- * by using an idle callback.
- *
- * The functions scheduled here will fire from idle callbacks
- * once every window has finished being restored by session
- * restore, and after the equivalent only-once tasks
- * have run (from _scheduleStartupIdleTasks in BrowserGlue.sys.mjs).
- */
- _schedulePerWindowIdleTasks() {
- // Bail out if the window has been closed in the meantime.
- if (window.closed) {
- return;
- }
-
- function scheduleIdleTask(func, options) {
- requestIdleCallback(function idleTaskRunner() {
- if (!window.closed) {
- func();
- }
- }, options);
- }
-
- scheduleIdleTask(() => {
- // Initialize the Sync UI
- gSync.init();
- });
-
- scheduleIdleTask(() => {
- // Read prefers-reduced-motion setting
- let reduceMotionQuery = window.matchMedia(
- "(prefers-reduced-motion: reduce)"
- );
- function readSetting() {
- gReduceMotionSetting = reduceMotionQuery.matches;
- }
- reduceMotionQuery.addListener(readSetting);
- readSetting();
- });
-
- scheduleIdleTask(() => {
- // load the tab preview component
- import("chrome://browser/content/tabpreview/tabpreview.mjs").catch(
- console.error
- );
- });
-
- scheduleIdleTask(() => {
- // setup simple gestures support
- gGestureSupport.init(true);
-
- // setup history swipe animation
- gHistorySwipeAnimation.init();
- });
-
- scheduleIdleTask(() => {
- gBrowserThumbnails.init();
- });
-
- scheduleIdleTask(
- () => {
- // Initialize the download manager some time after the app starts so that
- // auto-resume downloads begin (such as after crashing or quitting with
- // active downloads) and speeds up the first-load of the download manager UI.
- // If the user manually opens the download manager before the timeout, the
- // downloads will start right away, and initializing again won't hurt.
- try {
- DownloadsCommon.initializeAllDataLinks();
- ChromeUtils.importESModule(
- "resource:///modules/DownloadsTaskbar.sys.mjs"
- ).DownloadsTaskbar.registerIndicator(window);
- if (AppConstants.platform == "macosx") {
- ChromeUtils.importESModule(
- "resource:///modules/DownloadsMacFinderProgress.sys.mjs"
- ).DownloadsMacFinderProgress.register();
- }
- Services.telemetry.setEventRecordingEnabled("downloads", true);
- } catch (ex) {
- console.error(ex);
- }
- },
- { timeout: 10000 }
- );
-
- if (Win7Features) {
- scheduleIdleTask(() => Win7Features.onOpenWindow());
- }
-
- scheduleIdleTask(async () => {
- NewTabPagePreloading.maybeCreatePreloadedBrowser(window);
- });
-
- scheduleIdleTask(() => {
- gGfxUtils.init();
- });
-
- // This should always go last, since the idle tasks (except for the ones with
- // timeouts) should execute in order. Note that this observer notification is
- // not guaranteed to fire, since the window could close before we get here.
- scheduleIdleTask(() => {
- this.idleTaskPromiseResolve();
- Services.obs.notifyObservers(
- window,
- "browser-idle-startup-tasks-finished"
- );
- });
-
- scheduleIdleTask(() => {
- gProfiles.init();
- });
- },
-
- // Returns the URI(s) to load at startup if it is immediately known, or a
- // promise resolving to the URI to load.
- get uriToLoadPromise() {
- delete this.uriToLoadPromise;
- return (this.uriToLoadPromise = (function () {
- // window.arguments[0]: URI to load (string), or an nsIArray of
- // nsISupportsStrings to load, or a xul:tab of
- // a tabbrowser, which will be replaced by this
- // window (for this case, all other arguments are
- // ignored).
- let uri = window.arguments?.[0];
- if (!uri || window.XULElement.isInstance(uri)) {
- return null;
- }
-
- let defaultArgs = BrowserHandler.defaultArgs;
-
- // If the given URI is different from the homepage, we want to load it.
- if (uri != defaultArgs) {
- AboutNewTab.noteNonDefaultStartup();
-
- if (uri instanceof Ci.nsIArray) {
- // Transform the nsIArray of nsISupportsString's into a JS Array of
- // JS strings.
- return Array.from(
- uri.enumerate(Ci.nsISupportsString),
- supportStr => supportStr.data
- );
- } else if (uri instanceof Ci.nsISupportsString) {
- return uri.data;
- }
- return uri;
- }
-
- // The URI appears to be the the homepage. We want to load it only if
- // session restore isn't about to override the homepage.
- let willOverride = SessionStartup.willOverrideHomepage;
- if (typeof willOverride == "boolean") {
- return willOverride ? null : uri;
- }
- return willOverride.then(willOverrideHomepage =>
- willOverrideHomepage ? null : uri
- );
- })());
- },
-
- // Calls the given callback with the URI to load at startup.
- // Synchronously if possible, or after uriToLoadPromise resolves otherwise.
- _callWithURIToLoad(callback) {
- let uriToLoad = this.uriToLoadPromise;
- if (uriToLoad && uriToLoad.then) {
- uriToLoad.then(callback);
- } else {
- callback(uriToLoad);
- }
- },
-
- onUnload() {
- gUIDensity.uninit();
-
- TabsInTitlebar.uninit();
-
- ToolbarIconColor.uninit();
-
- // In certain scenarios it's possible for unload to be fired before onload,
- // (e.g. if the window is being closed after browser.js loads but before the
- // load completes). In that case, there's nothing to do here.
- if (!this._loadHandled) {
- return;
- }
-
- // First clean up services initialized in gBrowserInit.onLoad (or those whose
- // uninit methods don't depend on the services having been initialized).
-
- CombinedStopReload.uninit();
-
- gGestureSupport.init(false);
-
- gHistorySwipeAnimation.uninit();
-
- FullScreen.uninit();
-
- gSync.uninit();
-
- gExtensionsNotifications.uninit();
- gUnifiedExtensions.uninit();
-
- try {
- gBrowser.removeProgressListener(window.XULBrowserWindow);
- gBrowser.removeTabsProgressListener(window.TabsProgressListener);
- } catch (ex) {}
-
- PlacesToolbarHelper.uninit();
-
- BookmarkingUI.uninit();
-
- TabletModeUpdater.uninit();
-
- gTabletModePageCounter.finish();
-
- CaptivePortalWatcher.uninit();
-
- SidebarUI.uninit();
-
- DownloadsButton.uninit();
-
- if (gToolbarKeyNavEnabled) {
- ToolbarKeyboardNavigator.uninit();
- }
-
- BrowserSearch.uninit();
-
- NewTabPagePreloading.removePreloadedBrowser(window);
-
- FirefoxViewHandler.uninit();
-
- // Now either cancel delayedStartup, or clean up the services initialized from
- // it.
- if (this._boundDelayedStartup) {
- this._cancelDelayedStartup();
- } else {
- if (Win7Features) {
- Win7Features.onCloseWindow();
- }
- Services.prefs.removeObserver(ctrlTab.prefName, ctrlTab);
- ctrlTab.uninit();
- gBrowserThumbnails.uninit();
- gProtectionsHandler.uninit();
- FullZoom.destroy();
-
- Services.obs.removeObserver(gIdentityHandler, "perm-changed");
- Services.obs.removeObserver(gRemoteControl, "devtools-socket");
- Services.obs.removeObserver(gRemoteControl, "marionette-listening");
- Services.obs.removeObserver(gRemoteControl, "remote-listening");
- Services.obs.removeObserver(
- gSessionHistoryObserver,
- "browser:purge-session-history"
- );
- Services.obs.removeObserver(
- gStoragePressureObserver,
- "QuotaManager::StoragePressure"
- );
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
- Services.obs.removeObserver(
- gXPInstallObserver,
- "addon-install-fullscreen-blocked"
- );
- Services.obs.removeObserver(
- gXPInstallObserver,
- "addon-install-origin-blocked"
- );
- Services.obs.removeObserver(
- gXPInstallObserver,
- "addon-install-policy-blocked"
- );
- Services.obs.removeObserver(
- gXPInstallObserver,
- "addon-install-webapi-blocked"
- );
- Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
- Services.obs.removeObserver(
- gXPInstallObserver,
- "addon-install-confirmation"
- );
- Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
-
- MenuTouchModeObserver.uninit();
- BrowserOffline.uninit();
- CanvasPermissionPromptHelper.uninit();
- WebAuthnPromptHelper.uninit();
- PanelUI.uninit();
- }
-
- // Final window teardown, do this last.
- gBrowser.destroy();
- window.XULBrowserWindow = null;
- window.docShell.treeOwner
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIAppWindow).XULBrowserWindow = null;
- window.browserDOMWindow = null;
- },
-};
-
-ChromeUtils.defineLazyGetter(
- gBrowserInit,
- "_firstContentWindowPaintDeferred",
- () => Promise.withResolvers()
-);
-
-gBrowserInit.idleTasksFinishedPromise = new Promise(resolve => {
- gBrowserInit.idleTaskPromiseResolve = resolve;
-});
-
function HandleAppCommandEvent(evt) {
switch (evt.command) {
case "Back":
- BrowserBack();
+ BrowserCommands.back();
break;
case "Forward":
- BrowserForward();
+ BrowserCommands.forward();
break;
case "Reload":
- BrowserReloadSkipCache();
+ BrowserCommands.reloadSkipCache();
break;
case "Stop":
if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true") {
- BrowserStop();
+ BrowserCommands.stop();
}
break;
case "Search":
BrowserSearch.webSearch();
break;
case "Bookmarks":
- SidebarUI.toggle("viewBookmarksSidebar");
+ SidebarController.toggle("viewBookmarksSidebar");
break;
case "Home":
- BrowserHome();
+ BrowserCommands.home();
break;
case "New":
- BrowserOpenTab();
+ BrowserCommands.openTab();
break;
case "Close":
- BrowserCloseTabOrWindow();
+ BrowserCommands.closeTabOrWindow();
break;
case "Find":
gLazyFindCommand("onFindCommand");
@@ -2655,7 +1542,7 @@ function HandleAppCommandEvent(evt) {
openHelpLink("firefox-help");
break;
case "Open":
- BrowserOpenFileWindow();
+ BrowserCommands.openFileWindow();
break;
case "Print":
PrintUtils.startPrintWindow(gBrowser.selectedBrowser.browsingContext);
@@ -2673,203 +1560,6 @@ function HandleAppCommandEvent(evt) {
evt.preventDefault();
}
-function gotoHistoryIndex(aEvent) {
- aEvent = getRootEvent(aEvent);
-
- let index = aEvent.target.getAttribute("index");
- if (!index) {
- return false;
- }
-
- let where = whereToOpenLink(aEvent);
-
- if (where == "current") {
- // Normal click. Go there in the current tab and update session history.
-
- try {
- gBrowser.gotoIndex(index);
- } catch (ex) {
- return false;
- }
- return true;
- }
- // Modified click. Go there in a new tab/window.
-
- let historyindex = aEvent.target.getAttribute("historyindex");
- duplicateTabIn(gBrowser.selectedTab, where, Number(historyindex));
- return true;
-}
-
-function BrowserForward(aEvent) {
- let where = whereToOpenLink(aEvent, false, true);
-
- if (where == "current") {
- try {
- gBrowser.goForward();
- } catch (ex) {}
- } else {
- duplicateTabIn(gBrowser.selectedTab, where, 1);
- }
-}
-
-function BrowserBack(aEvent) {
- let where = whereToOpenLink(aEvent, false, true);
-
- if (where == "current") {
- try {
- gBrowser.goBack();
- } catch (ex) {}
- } else {
- duplicateTabIn(gBrowser.selectedTab, where, -1);
- }
-}
-
-function BrowserHandleBackspace() {
- switch (Services.prefs.getIntPref("browser.backspace_action")) {
- case 0:
- BrowserBack();
- break;
- case 1:
- goDoCommand("cmd_scrollPageUp");
- break;
- }
-}
-
-function BrowserHandleShiftBackspace() {
- switch (Services.prefs.getIntPref("browser.backspace_action")) {
- case 0:
- BrowserForward();
- break;
- case 1:
- goDoCommand("cmd_scrollPageDown");
- break;
- }
-}
-
-function BrowserStop() {
- gBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
-}
-
-function BrowserReloadOrDuplicate(aEvent) {
- aEvent = getRootEvent(aEvent);
- let accelKeyPressed =
- AppConstants.platform == "macosx" ? aEvent.metaKey : aEvent.ctrlKey;
- var backgroundTabModifier = aEvent.button == 1 || accelKeyPressed;
-
- if (aEvent.shiftKey && !backgroundTabModifier) {
- BrowserReloadSkipCache();
- return;
- }
-
- let where = whereToOpenLink(aEvent, false, true);
- if (where == "current") {
- BrowserReload();
- } else {
- duplicateTabIn(gBrowser.selectedTab, where);
- }
-}
-
-function BrowserReload() {
- if (gBrowser.currentURI.schemeIs("view-source")) {
- // Bug 1167797: For view source, we always skip the cache
- return BrowserReloadSkipCache();
- }
- const reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
- BrowserReloadWithFlags(reloadFlags);
-}
-
-const kSkipCacheFlags =
- Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY |
- Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
-function BrowserReloadSkipCache() {
- // Bypass proxy and cache.
- BrowserReloadWithFlags(kSkipCacheFlags);
-}
-
-function BrowserHome(aEvent) {
- if (aEvent && "button" in aEvent && aEvent.button == 2) {
- // right-click: do nothing
- return;
- }
-
- var homePage = HomePage.get(window);
- var where = whereToOpenLink(aEvent, false, true);
- var urls;
- var notifyObservers;
-
- // Don't load the home page in pinned or hidden tabs (e.g. Firefox View).
- if (
- where == "current" &&
- (gBrowser?.selectedTab.pinned || gBrowser?.selectedTab.hidden)
- ) {
- where = "tab";
- }
-
- // openTrustedLinkIn in utilityOverlay.js doesn't handle loading multiple pages
- switch (where) {
- case "current":
- // If we're going to load an initial page in the current tab as the
- // home page, we set initialPageLoadedFromURLBar so that the URL
- // bar is cleared properly (even during a remoteness flip).
- if (isInitialPage(homePage)) {
- gBrowser.selectedBrowser.initialPageLoadedFromUserAction = homePage;
- }
- loadOneOrMoreURIs(
- homePage,
- Services.scriptSecurityManager.getSystemPrincipal(),
- null
- );
- if (isBlankPageURL(homePage)) {
- gURLBar.select();
- } else {
- gBrowser.selectedBrowser.focus();
- }
- notifyObservers = true;
- aEvent?.preventDefault();
- break;
- case "tabshifted":
- case "tab":
- urls = homePage.split("|");
- var loadInBackground = Services.prefs.getBoolPref(
- "browser.tabs.loadBookmarksInBackground",
- false
- );
- // The homepage observer event should only be triggered when the homepage opens
- // in the foreground. This is mostly to support the homepage changed by extension
- // doorhanger which doesn't currently support background pages. This may change in
- // bug 1438396.
- notifyObservers = !loadInBackground;
- gBrowser.loadTabs(urls, {
- inBackground: loadInBackground,
- triggeringPrincipal:
- Services.scriptSecurityManager.getSystemPrincipal(),
- csp: null,
- });
- if (!loadInBackground) {
- if (isBlankPageURL(homePage)) {
- gURLBar.select();
- } else {
- gBrowser.selectedBrowser.focus();
- }
- }
- aEvent?.preventDefault();
- break;
- case "window":
- // OpenBrowserWindow will trigger the observer event, so no need to do so here.
- notifyObservers = false;
- OpenBrowserWindow();
- aEvent?.preventDefault();
- break;
- }
- if (notifyObservers) {
- // A notification for when a user has triggered their homepage. This is used
- // to display a doorhanger explaining that an extension has modified the
- // homepage, if necessary. Observers are only notified if the homepage
- // becomes the active page.
- Services.obs.notifyObservers(null, "browser-open-homepage-start");
- }
-}
-
function loadOneOrMoreURIs(aURIString, aTriggeringPrincipal, aCsp) {
// we're not a browser window, pass the URI string to a new browser window
if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
@@ -2918,62 +1608,6 @@ function openLocation(event) {
);
}
-function BrowserOpenTab({ event, url } = {}) {
- let werePassedURL = !!url;
- url ??= BROWSER_NEW_TAB_URL;
- let searchClipboard = gMiddleClickNewTabUsesPasteboard && event?.button == 1;
-
- let relatedToCurrent = false;
- let where = "tab";
-
- if (event) {
- where = whereToOpenLink(event, false, true);
-
- switch (where) {
- case "tab":
- case "tabshifted":
- // When accel-click or middle-click are used, open the new tab as
- // related to the current tab.
- relatedToCurrent = true;
- break;
- case "current":
- where = "tab";
- break;
- }
- }
-
- // A notification intended to be useful for modular peformance tracking
- // starting as close as is reasonably possible to the time when the user
- // expressed the intent to open a new tab. Since there are a lot of
- // entry points, this won't catch every single tab created, but most
- // initiated by the user should go through here.
- //
- // Note 1: This notification gets notified with a promise that resolves
- // with the linked browser when the tab gets created
- // Note 2: This is also used to notify a user that an extension has changed
- // the New Tab page.
- Services.obs.notifyObservers(
- {
- wrappedJSObject: new Promise(resolve => {
- let options = {
- relatedToCurrent,
- resolveOnNewTabCreated: resolve,
- };
- if (!werePassedURL && searchClipboard) {
- let clipboard = readFromClipboard();
- clipboard = UrlbarUtils.stripUnsafeProtocolOnPaste(clipboard).trim();
- if (clipboard) {
- url = clipboard;
- options.allowThirdPartyFixup = true;
- }
- }
- openTrustedLinkIn(url, where, options);
- }),
- },
- "browser-open-newtab-start"
- );
-}
-
var gLastOpenDirectory = {
_lastDir: null,
get path() {
@@ -3014,76 +1648,6 @@ var gLastOpenDirectory = {
},
};
-function BrowserOpenFileWindow() {
- // Get filepicker component.
- try {
- const nsIFilePicker = Ci.nsIFilePicker;
- let fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
- let fpCallback = function fpCallback_done(aResult) {
- if (aResult == nsIFilePicker.returnOK) {
- try {
- if (fp.file) {
- gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsIFile);
- }
- } catch (ex) {}
- openTrustedLinkIn(fp.fileURL.spec, "current");
- }
- };
-
- fp.init(
- window.browsingContext,
- gNavigatorBundle.getString("openFile"),
- nsIFilePicker.modeOpen
- );
- fp.appendFilters(
- nsIFilePicker.filterAll |
- nsIFilePicker.filterText |
- nsIFilePicker.filterImages |
- nsIFilePicker.filterXML |
- nsIFilePicker.filterHTML |
- nsIFilePicker.filterPDF
- );
- fp.displayDirectory = gLastOpenDirectory.path;
- fp.open(fpCallback);
- } catch (ex) {}
-}
-
-function BrowserCloseTabOrWindow(event) {
- // If we're not a browser window, just close the window.
- if (window.location.href != AppConstants.BROWSER_CHROME_URL) {
- closeWindow(true);
- return;
- }
-
- // In a multi-select context, close all selected tabs
- if (gBrowser.multiSelectedTabsCount) {
- gBrowser.removeMultiSelectedTabs();
- return;
- }
-
- // Keyboard shortcuts that would close a tab that is pinned select the first
- // unpinned tab instead.
- if (
- event &&
- (event.ctrlKey || event.metaKey || event.altKey) &&
- gBrowser.selectedTab.pinned
- ) {
- if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
- gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
- }
- return;
- }
-
- // If the current tab is the last one, this will close the window.
- gBrowser.removeCurrentTab({ animate: true });
-}
-
-function BrowserTryToCloseWindow(event) {
- if (WindowIsClosing(event)) {
- window.close();
- } // WindowIsClosing does all the necessary checks
-}
-
function getLoadContext() {
return window.docShell.QueryInterface(Ci.nsILoadContext);
}
@@ -3120,162 +1684,6 @@ function readFromClipboard() {
return url;
}
-/**
- * Open the View Source dialog.
- *
- * @param args
- * An object with the following properties:
- *
- * URL (required):
- * A string URL for the page we'd like to view the source of.
- * browser (optional):
- * The browser containing the document that we would like to view the
- * source of. This is required if outerWindowID is passed.
- * outerWindowID (optional):
- * The outerWindowID of the content window containing the document that
- * we want to view the source of. You only need to provide this if you
- * want to attempt to retrieve the document source from the network
- * cache.
- * lineNumber (optional):
- * The line number to focus on once the source is loaded.
- */
-async function BrowserViewSourceOfDocument(args) {
- // Check if external view source is enabled. If so, try it. If it fails,
- // fallback to internal view source.
- if (Services.prefs.getBoolPref("view_source.editor.external")) {
- try {
- await top.gViewSourceUtils.openInExternalEditor(args);
- return;
- } catch (data) {}
- }
-
- let tabBrowser = gBrowser;
- let preferredRemoteType;
- let initialBrowsingContextGroupId;
- if (args.browser) {
- preferredRemoteType = args.browser.remoteType;
- initialBrowsingContextGroupId = args.browser.browsingContext.group.id;
- } else {
- if (!tabBrowser) {
- throw new Error(
- "BrowserViewSourceOfDocument should be passed the " +
- "subject browser if called from a window without " +
- "gBrowser defined."
- );
- }
- // Some internal URLs (such as specific chrome: and about: URLs that are
- // not yet remote ready) cannot be loaded in a remote browser. View
- // source in tab expects the new view source browser's remoteness to match
- // that of the original URL, so disable remoteness if necessary for this
- // URL.
- var oa = E10SUtils.predictOriginAttributes({ window });
- preferredRemoteType = E10SUtils.getRemoteTypeForURI(
- args.URL,
- gMultiProcessBrowser,
- gFissionBrowser,
- E10SUtils.DEFAULT_REMOTE_TYPE,
- null,
- oa
- );
- }
-
- // In the case of popups, we need to find a non-popup browser window.
- if (!tabBrowser || !window.toolbar.visible) {
- // This returns only non-popup browser windows by default.
- let browserWindow = BrowserWindowTracker.getTopWindow();
- tabBrowser = browserWindow.gBrowser;
- }
-
- const inNewWindow = !Services.prefs.getBoolPref("view_source.tab");
-
- // `viewSourceInBrowser` will load the source content from the page
- // descriptor for the tab (when possible) or fallback to the network if
- // that fails. Either way, the view source module will manage the tab's
- // location, so use "about:blank" here to avoid unnecessary redundant
- // requests.
- let tab = tabBrowser.addTab("about:blank", {
- relatedToCurrent: true,
- inBackground: inNewWindow,
- skipAnimation: inNewWindow,
- preferredRemoteType,
- initialBrowsingContextGroupId,
- triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
- skipLoad: true,
- });
- args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab);
- top.gViewSourceUtils.viewSourceInBrowser(args);
-
- if (inNewWindow) {
- tabBrowser.hideTab(tab);
- tabBrowser.replaceTabWithWindow(tab);
- }
-}
-
-/**
- * Opens the View Source dialog for the source loaded in the root
- * top-level document of the browser. This is really just a
- * convenience wrapper around BrowserViewSourceOfDocument.
- *
- * @param browser
- * The browser that we want to load the source of.
- */
-function BrowserViewSource(browser) {
- BrowserViewSourceOfDocument({
- browser,
- outerWindowID: browser.outerWindowID,
- URL: browser.currentURI.spec,
- });
-}
-
-// documentURL - URL of the document to view, or null for this window's document
-// initialTab - name of the initial tab to display, or null for the first tab
-// imageElement - image to load in the Media Tab of the Page Info window; can be null/omitted
-// browsingContext - the browsingContext of the frame that we want to view information about; can be null/omitted
-// browser - the browser containing the document we're interested in inspecting; can be null/omitted
-function BrowserPageInfo(
- documentURL,
- initialTab,
- imageElement,
- browsingContext,
- browser
-) {
- let args = { initialTab, imageElement, browsingContext, browser };
-
- documentURL = documentURL || window.gBrowser.selectedBrowser.currentURI.spec;
-
- let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
-
- // Check for windows matching the url
- for (let currentWindow of Services.wm.getEnumerator("Browser:page-info")) {
- if (currentWindow.closed) {
- continue;
- }
- if (
- currentWindow.document.documentElement.getAttribute("relatedUrl") ==
- documentURL &&
- PrivateBrowsingUtils.isWindowPrivate(currentWindow) == isPrivate
- ) {
- currentWindow.focus();
- currentWindow.resetPageInfo(args);
- return currentWindow;
- }
- }
-
- // We didn't find a matching window, so open a new one.
- let options = "chrome,toolbar,dialog=no,resizable";
-
- // Ensure the window groups correctly in the Windows taskbar
- if (isPrivate) {
- options += ",private";
- }
- return openDialog(
- "chrome://browser/content/pageinfo/pageInfo.xhtml",
- "",
- options,
- args
- );
-}
-
function UpdateUrlbarSearchSplitterState() {
var splitter = document.getElementById("urlbar-search-splitter");
var urlbar = document.getElementById("urlbar-container");
@@ -3480,88 +1888,6 @@ function getDefaultHomePage() {
return url;
}
-function BrowserFullScreen() {
- window.fullScreen = !window.fullScreen || BrowserHandler.kiosk;
-}
-
-function BrowserReloadWithFlags(reloadFlags) {
- let unchangedRemoteness = [];
-
- for (let tab of gBrowser.selectedTabs) {
- let browser = tab.linkedBrowser;
- let url = browser.currentURI;
- let urlSpec = url.spec;
- // We need to cache the content principal here because the browser will be
- // reconstructed when the remoteness changes and the content prinicpal will
- // be cleared after reconstruction.
- let principal = tab.linkedBrowser.contentPrincipal;
- if (gBrowser.updateBrowserRemotenessByURL(browser, urlSpec)) {
- // If the remoteness has changed, the new browser doesn't have any
- // information of what was loaded before, so we need to load the previous
- // URL again.
- if (tab.linkedPanel) {
- loadBrowserURI(browser, url, principal);
- } else {
- // Shift to fully loaded browser and make
- // sure load handler is instantiated.
- tab.addEventListener(
- "SSTabRestoring",
- () => loadBrowserURI(browser, url, principal),
- { once: true }
- );
- gBrowser._insertBrowser(tab);
- }
- } else {
- unchangedRemoteness.push(tab);
- }
- }
-
- if (!unchangedRemoteness.length) {
- return;
- }
-
- // Reset temporary permissions on the remaining tabs to reload.
- // This is done here because we only want to reset
- // permissions on user reload.
- for (let tab of unchangedRemoteness) {
- SitePermissions.clearTemporaryBlockPermissions(tab.linkedBrowser);
- // Also reset DOS mitigations for the basic auth prompt on reload.
- delete tab.linkedBrowser.authPromptAbuseCounter;
- }
- gIdentityHandler.hidePopup();
- gPermissionPanel.hidePopup();
-
- let handlingUserInput = document.hasValidTransientUserGestureActivation;
-
- for (let tab of unchangedRemoteness) {
- if (tab.linkedPanel) {
- sendReloadMessage(tab);
- } else {
- // Shift to fully loaded browser and make
- // sure load handler is instantiated.
- tab.addEventListener("SSTabRestoring", () => sendReloadMessage(tab), {
- once: true,
- });
- gBrowser._insertBrowser(tab);
- }
- }
-
- function loadBrowserURI(browser, url, principal) {
- browser.loadURI(url, {
- flags: reloadFlags,
- triggeringPrincipal: principal,
- });
- }
-
- function sendReloadMessage(tab) {
- tab.linkedBrowser.sendMessageToActor(
- "Browser:Reload",
- { flags: reloadFlags, handlingUserInput },
- "BrowserTab"
- );
- }
-}
-
// TODO: can we pull getPEMString in from pippki.js instead of
// duplicating them here?
function getPEMString(cert) {
@@ -4053,7 +2379,7 @@ const BrowserSearch = {
win.BrowserSearch.webSearch();
} else {
// If there are no open browser windows, open a new one
- var observer = function (subject, topic, data) {
+ var observer = function (subject) {
if (subject == win) {
BrowserSearch.webSearch();
Services.obs.removeObserver(
@@ -4200,7 +2526,7 @@ const BrowserSearch = {
event
) {
event = getRootEvent(event);
- let where = whereToOpenLink(event);
+ let where = BrowserUtils.whereToOpenLink(event);
if (where == "current") {
// override: historically search opens in new tab
where = "tab";
@@ -4444,7 +2770,8 @@ function FillHistoryMenu(aParent) {
item.setAttribute("label", entry.title || uri);
item.setAttribute("index", j);
- // Cache this so that gotoHistoryIndex doesn't need the original index
+ // Cache this so that BrowserCommands.gotoHistoryIndex doesn't need the
+ // original index
item.setAttribute("historyindex", j - index);
if (j != index) {
@@ -4505,14 +2832,6 @@ function FillHistoryMenu(aParent) {
return true;
}
-function BrowserDownloadsUI() {
- if (PrivateBrowsingUtils.isWindowPrivate(window)) {
- openTrustedLinkIn("about:downloads", "tab");
- } else {
- PlacesCommandHook.showPlacesOrganizer("Downloads");
- }
-}
-
function toOpenWindowByType(inType, uri, features) {
var topWindow = Services.wm.getMostRecentWindow(inType);
@@ -5037,7 +3356,7 @@ var XULBrowserWindow = {
this.setOverLink("", { hideStatusPanelImmediately: true });
},
- showTooltip(xDevPix, yDevPix, tooltip, direction, browser) {
+ showTooltip(xDevPix, yDevPix, tooltip, direction, _browser) {
if (
Cc["@mozilla.org/widget/dragservice;1"]
.getService(Ci.nsIDragService)
@@ -5070,14 +3389,7 @@ var XULBrowserWindow = {
return gBrowser.tabs.length;
},
- onProgressChange(
- aWebProgress,
- aRequest,
- aCurSelfProgress,
- aMaxSelfProgress,
- aCurTotalProgress,
- aMaxTotalProgress
- ) {
+ onProgressChange() {
// Do nothing.
},
@@ -5420,7 +3732,7 @@ var XULBrowserWindow = {
}
}
- if (TranslationsParent.isRestrictedPage(gBrowser)) {
+ if (TranslationsParent.isFullPageTranslationsRestrictedForPage(gBrowser)) {
this._menuItemForTranslations.setAttribute("disabled", "true");
} else {
this._menuItemForTranslations.removeAttribute("disabled");
@@ -5576,7 +3888,7 @@ var XULBrowserWindow = {
// 2. Called by tabbrowser.xml when updating the current browser.
// 3. Called directly during this object's initializations.
// aRequest will be null always in case 2 and 3, and sometimes in case 1.
- onSecurityChange(aWebProgress, aRequest, aState, aIsSimulated) {
+ onSecurityChange(aWebProgress, aRequest, aState, _aIsSimulated) {
// Don't need to do anything if the data we use to update the UI hasn't
// changed
let uri = gBrowser.currentURI;
@@ -5619,7 +3931,7 @@ var XULBrowserWindow = {
aStateFlags,
aStatus,
aMessage,
- aTotalProgress
+ _aTotalProgress
) {
if (FullZoom.updateBackgroundTabs) {
FullZoom.onLocationChange(gBrowser.currentURI, true);
@@ -6087,7 +4399,7 @@ nsBrowserAccess.prototype = {
}
if (aIsExternal && (!aURI || aURI.spec == "about:blank")) {
- win.BrowserOpenTab(); // this also focuses the location bar
+ win.BrowserCommands.openTab(); // this also focuses the location bar
win.focus();
return win.gBrowser.selectedBrowser;
}
@@ -6228,7 +4540,7 @@ nsBrowserAccess.prototype = {
: PrivateBrowsingUtils.isWindowPrivate(window);
switch (aWhere) {
- case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW:
+ case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW: {
// FIXME: Bug 408379. So how come this doesn't send the
// referrer like the other loads do?
var url = aURI && aURI.spec;
@@ -6272,6 +4584,7 @@ nsBrowserAccess.prototype = {
console.error(ex);
}
break;
+ }
case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB:
case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB_BACKGROUND: {
// If we have an opener, that means that the caller is expecting access
@@ -6682,7 +4995,7 @@ function setToolbarVisibility(
document.documentElement.toggleAttribute(overlapAttr, false);
break;
case "newtab":
- default:
+ default: {
let currentURI = gBrowser?.currentURI;
if (!gBrowserInit.domContentLoaded) {
let uriToLoad = gBrowserInit.uriToLoadPromise;
@@ -6699,6 +5012,7 @@ function setToolbarVisibility(
isVisible = BookmarkingUI.isOnNewTabPage(currentURI);
document.documentElement.toggleAttribute(overlapAttr, isVisible);
break;
+ }
}
}
@@ -6801,7 +5115,7 @@ var gTabletModePageCounter = {
};
function displaySecurityInfo() {
- BrowserPageInfo(null, "securityTab");
+ BrowserCommands.pageInfo(null, "securityTab");
}
// Updates the UI density (for touch and compact mode) based on the uidensity pref.
@@ -6855,9 +5169,10 @@ var gUIDensity = {
}
let docs = [document.documentElement];
- let shouldUpdateSidebar = SidebarUI.initialized && SidebarUI.isOpen;
+ let shouldUpdateSidebar =
+ SidebarController.initialized && SidebarController.isOpen;
if (shouldUpdateSidebar) {
- docs.push(SidebarUI.browser.contentDocument.documentElement);
+ docs.push(SidebarController.browser.contentDocument.documentElement);
}
for (let doc of docs) {
switch (mode) {
@@ -6873,7 +5188,7 @@ var gUIDensity = {
}
}
if (shouldUpdateSidebar) {
- let tree = SidebarUI.browser.contentDocument.querySelector(
+ let tree = SidebarController.browser.contentDocument.querySelector(
".sidebar-placesTree"
);
if (tree) {
@@ -7110,7 +5425,7 @@ function handleLinkClick(event, href, linkNode) {
return false;
}
- var where = whereToOpenLink(event);
+ var where = BrowserUtils.whereToOpenLink(event);
if (where == "current") {
return false;
}
@@ -7183,7 +5498,7 @@ function middleMousePaste(event) {
// if it's not the current tab, we don't need to do anything because the
// browser doesn't exist.
- let where = whereToOpenLink(event, true, false);
+ let where = BrowserUtils.whereToOpenLink(event, true, false);
let lastLocationChange;
if (where == "current") {
lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
@@ -7297,11 +5612,6 @@ function handleDroppedLink(
}
}
-function BrowserForceEncodingDetection() {
- gBrowser.selectedBrowser.forceEncodingDetection();
- BrowserReloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
-}
-
var ToolbarContextMenu = {
updateDownloadsAutoHide(popup) {
let checkbox = document.getElementById(
@@ -7467,7 +5777,7 @@ var BrowserOffline = {
},
// nsIObserver
- observe(aSubject, aTopic, aState) {
+ observe(aSubject, aTopic) {
if (aTopic != "network:offline-status-changed") {
return;
}
@@ -7695,8 +6005,8 @@ var WebAuthnPromptHelper = {
if (data.prompt.type == "presence") {
this.presence_required(mgr, data);
- } else if (data.prompt.type == "register-direct") {
- this.registerDirect(mgr, data);
+ } else if (data.prompt.type == "attestation-consent") {
+ this.attestation_consent(mgr, data);
} else if (data.prompt.type == "pin-required") {
this.pin_required(mgr, false, data);
} else if (data.prompt.type == "pin-invalid") {
@@ -7815,7 +6125,7 @@ var WebAuthnPromptHelper = {
secondaryActions.push({
label,
accessKey: i.toString(),
- callback(aState) {
+ callback() {
mgr.selectionCallback(tid, i);
},
});
@@ -7859,9 +6169,23 @@ var WebAuthnPromptHelper = {
);
},
- registerDirect(mgr, { origin, tid }) {
- let mainAction = this.buildProceedAction(mgr, tid);
- let secondaryActions = [this.buildCancelAction(mgr, tid)];
+ attestation_consent(mgr, { origin, tid }) {
+ let mainAction = {
+ label: gNavigatorBundle.getString("webauthn.allow"),
+ accessKey: gNavigatorBundle.getString("webauthn.allow.accesskey"),
+ callback(_state) {
+ mgr.setHasAttestationConsent(tid, true);
+ },
+ };
+ let secondaryActions = [
+ {
+ label: gNavigatorBundle.getString("webauthn.block"),
+ accessKey: gNavigatorBundle.getString("webauthn.block.accesskey"),
+ callback(_state) {
+ mgr.setHasAttestationConsent(tid, false);
+ },
+ },
+ ];
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") +
@@ -7869,9 +6193,6 @@ var WebAuthnPromptHelper = {
let options = {
learnMoreURL,
- checkbox: {
- label: gNavigatorBundle.getString("webauthn.anonymize"),
- },
hintText: "webauthn.registerDirectPromptHint",
};
this.show(
@@ -7994,16 +6315,6 @@ var WebAuthnPromptHelper = {
}
},
- buildProceedAction(mgr, tid) {
- return {
- label: gNavigatorBundle.getString("webauthn.proceed"),
- accessKey: gNavigatorBundle.getString("webauthn.proceed.accesskey"),
- callback(state) {
- mgr.resumeMakeCredential(tid, state.checkboxChecked);
- },
- };
- },
-
buildCancelAction(mgr, tid) {
return {
label: gNavigatorBundle.getString("webauthn.cancel"),
@@ -8195,84 +6506,6 @@ var MailIntegration = {
},
};
-/**
- * Open about:addons page by given view id.
- * @param {String} aView
- * View id of page that will open.
- * e.g. "addons://discover/"
- * @param {Object} options
- * {
- * selectTabByViewId: If true, if there is the tab opening page having
- * same view id, select the tab. Else if the current
- * page is blank, load on it. Otherwise, open a new
- * tab, then load on it.
- * If false, if there is the tab opening
- * about:addoons page, select the tab and load page
- * for view id on it. Otherwise, leave the loading
- * behavior to switchToTabHavingURI().
- * If no options, handles as false.
- * }
- * @returns {Promise} When the Promise resolves, returns window object loaded the
- * view id.
- */
-function BrowserOpenAddonsMgr(aView, { selectTabByViewId = false } = {}) {
- return new Promise(resolve => {
- let emWindow;
- let browserWindow;
-
- var receivePong = function (aSubject, aTopic, aData) {
- let browserWin = aSubject.browsingContext.topChromeWindow;
- if (!emWindow || browserWin == window /* favor the current window */) {
- if (
- selectTabByViewId &&
- aSubject.gViewController.currentViewId !== aView
- ) {
- return;
- }
-
- emWindow = aSubject;
- browserWindow = browserWin;
- }
- };
- Services.obs.addObserver(receivePong, "EM-pong");
- Services.obs.notifyObservers(null, "EM-ping");
- Services.obs.removeObserver(receivePong, "EM-pong");
-
- if (emWindow) {
- if (aView && !selectTabByViewId) {
- emWindow.loadView(aView);
- }
- let tab = browserWindow.gBrowser.getTabForBrowser(
- emWindow.docShell.chromeEventHandler
- );
- browserWindow.gBrowser.selectedTab = tab;
- emWindow.focus();
- resolve(emWindow);
- return;
- }
-
- if (selectTabByViewId) {
- const target = isBlankPageURL(gBrowser.currentURI.spec)
- ? "current"
- : "tab";
- openTrustedLinkIn("about:addons", target);
- } else {
- // This must be a new load, else the ping/pong would have
- // found the window above.
- switchToTabHavingURI("about:addons", true);
- }
-
- Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
- Services.obs.removeObserver(observer, aTopic);
- if (aView) {
- aSubject.loadView(aView);
- }
- aSubject.focus();
- resolve(aSubject);
- }, "EM-loaded");
- });
-}
-
function AddKeywordForSearchField() {
if (!gContextMenu) {
throw new Error("Context menu doesn't seem to be open.");
@@ -8449,7 +6682,7 @@ function ReportSiteIssue() {
* and when the "remote-listening" system notification fires.
*/
const gRemoteControl = {
- observe(subject, topic, data) {
+ observe() {
gRemoteControl.updateVisualCue();
},
@@ -8658,7 +6891,7 @@ function switchToTabHavingURI(
ignoreQueryString || replaceQueryString,
ignoreFragmentWhenComparing
);
- let browserUserContextId = browser.getAttribute("usercontextid");
+ let browserUserContextId = browser.getAttribute("usercontextid") || "";
if (aUserContextId != null && aUserContextId != browserUserContextId) {
continue;
}
@@ -8823,7 +7056,7 @@ function safeModeRestart() {
*/
function duplicateTabIn(aTab, where, delta) {
switch (where) {
- case "window":
+ case "window": {
let otherWin = OpenBrowserWindow({
private: PrivateBrowsingUtils.isBrowserPrivate(aTab.linkedBrowser),
});
@@ -8845,6 +7078,7 @@ function duplicateTabIn(aTab, where, delta) {
"browser-delayed-startup-finished"
);
break;
+ }
case "tabshifted":
SessionStore.duplicateTab(window, aTab, delta);
// A background tab has been opened, nothing else to do here.
@@ -9447,221 +7681,6 @@ TabDialogBox.prototype.QueryInterface = ChromeUtils.generateQI([
"nsISupportsWeakReference",
]);
-function TabModalPromptBox(browser) {
- this._weakBrowserRef = Cu.getWeakReference(browser);
- /*
- * These WeakMaps holds the TabModalPrompt instances, key to the <tabmodalprompt> prompt
- * in the DOM. We don't want to hold the instances directly to avoid leaking.
- *
- * WeakMap also prevents us from reading back its insertion order.
- * Order of the elements in the DOM should be the only order to consider.
- */
- this._contentPrompts = new WeakMap();
- this._tabPrompts = new WeakMap();
-}
-
-TabModalPromptBox.prototype = {
- _promptCloseCallback(
- onCloseCallback,
- principalToAllowFocusFor,
- allowFocusCheckbox,
- ...args
- ) {
- if (
- principalToAllowFocusFor &&
- allowFocusCheckbox &&
- allowFocusCheckbox.checked
- ) {
- Services.perms.addFromPrincipal(
- principalToAllowFocusFor,
- "focus-tab-by-prompt",
- Services.perms.ALLOW_ACTION
- );
- }
- onCloseCallback.apply(this, args);
- },
-
- getPrompt(promptEl) {
- if (promptEl.classList.contains("tab-prompt")) {
- return this._tabPrompts.get(promptEl);
- }
- return this._contentPrompts.get(promptEl);
- },
-
- appendPrompt(args, onCloseCallback) {
- let browser = this.browser;
- let newPrompt = new TabModalPrompt(browser.ownerGlobal);
-
- if (args.modalType === Ci.nsIPrompt.MODAL_TYPE_TAB) {
- newPrompt.element.classList.add("tab-prompt");
- this._tabPrompts.set(newPrompt.element, newPrompt);
- } else {
- newPrompt.element.classList.add("content-prompt");
- this._contentPrompts.set(newPrompt.element, newPrompt);
- }
-
- browser.parentNode.insertBefore(
- newPrompt.element,
- browser.nextElementSibling
- );
- browser.setAttribute("tabmodalPromptShowing", true);
-
- // Indicate if a tab modal chrome prompt is being shown so that
- // PopupNotifications are suppressed.
- if (
- args.modalType === Ci.nsIPrompt.MODAL_TYPE_TAB &&
- !browser.hasAttribute("tabmodalChromePromptShowing")
- ) {
- browser.setAttribute("tabmodalChromePromptShowing", true);
- // Notify popup notifications of the UI change so they hide their
- // notification panels.
- UpdatePopupNotificationsVisibility();
- }
-
- let prompts = this.listPrompts(args.modalType);
- if (prompts.length > 1) {
- // Let's hide ourself behind the current prompt.
- newPrompt.element.hidden = true;
- }
-
- let principalToAllowFocusFor = this._allowTabFocusByPromptPrincipal;
- delete this._allowTabFocusByPromptPrincipal;
-
- let allowFocusCheckbox; // Define outside the if block so we can bind it into the callback.
- let hostForAllowFocusCheckbox = "";
- try {
- hostForAllowFocusCheckbox = principalToAllowFocusFor.URI.host;
- } catch (ex) {
- /* Ignore exceptions for host-less URIs */
- }
- if (hostForAllowFocusCheckbox) {
- let allowFocusRow = document.createElement("div");
-
- let spacer = document.createElement("div");
- allowFocusRow.appendChild(spacer);
-
- allowFocusCheckbox = document.createXULElement("checkbox");
- document.l10n.setAttributes(
- allowFocusCheckbox,
- "tabbrowser-allow-dialogs-to-get-focus",
- { domain: hostForAllowFocusCheckbox }
- );
- allowFocusRow.appendChild(allowFocusCheckbox);
-
- newPrompt.ui.rows.append(allowFocusRow);
- }
-
- let tab = gBrowser.getTabForBrowser(browser);
- let closeCB = this._promptCloseCallback.bind(
- null,
- onCloseCallback,
- principalToAllowFocusFor,
- allowFocusCheckbox
- );
- newPrompt.init(args, tab, closeCB);
- return newPrompt;
- },
-
- removePrompt(aPrompt) {
- let { modalType } = aPrompt.args;
- if (modalType === Ci.nsIPrompt.MODAL_TYPE_TAB) {
- this._tabPrompts.delete(aPrompt.element);
- } else {
- this._contentPrompts.delete(aPrompt.element);
- }
-
- let browser = this.browser;
- aPrompt.element.remove();
-
- let prompts = this.listPrompts(modalType);
- if (prompts.length) {
- let prompt = prompts[prompts.length - 1];
- prompt.element.hidden = false;
- // Because we were hidden before, this won't have been possible, so do it now:
- prompt.Dialog.setDefaultFocus();
- } else if (modalType === Ci.nsIPrompt.MODAL_TYPE_TAB) {
- // If we remove the last tab chrome prompt, also remove the browser
- // attribute.
- browser.removeAttribute("tabmodalChromePromptShowing");
- // Notify popup notifications of the UI change so they show notification
- // panels again.
- UpdatePopupNotificationsVisibility();
- }
- // Check if all prompts are closed
- if (!this._hasPrompts()) {
- browser.removeAttribute("tabmodalPromptShowing");
- browser.focus();
- }
- },
-
- /**
- * Checks if the prompt box has prompt elements.
- * @returns {Boolean} - true if there are prompt elements.
- */
- _hasPrompts() {
- return !!this._getPromptElements().length;
- },
-
- /**
- * Get list of current prompt elements.
- * @param {Number} [aModalType] - Optionally filter by
- * Ci.nsIPrompt.MODAL_TYPE_.
- * @returns {NodeList} - A list of tabmodalprompt elements.
- */
- _getPromptElements(aModalType = null) {
- let selector = "tabmodalprompt";
-
- if (aModalType != null) {
- if (aModalType === Ci.nsIPrompt.MODAL_TYPE_TAB) {
- selector += ".tab-prompt";
- } else {
- selector += ".content-prompt";
- }
- }
- return this.browser.parentNode.querySelectorAll(selector);
- },
-
- /**
- * Get a list of all TabModalPrompt objects associated with the prompt box.
- * @param {Number} [aModalType] - Optionally filter by
- * Ci.nsIPrompt.MODAL_TYPE_.
- * @returns {TabModalPrompt[]} - An array of TabModalPrompt objects.
- */
- listPrompts(aModalType = null) {
- // Get the nodelist, then return the TabModalPrompt instances as an array
- let promptMap;
-
- if (aModalType) {
- if (aModalType === Ci.nsIPrompt.MODAL_TYPE_TAB) {
- promptMap = this._tabPrompts;
- } else {
- promptMap = this._contentPrompts;
- }
- }
-
- let elements = this._getPromptElements(aModalType);
-
- if (promptMap) {
- return [...elements].map(el => promptMap.get(el));
- }
- return [...elements].map(
- el => this._contentPrompts.get(el) || this._tabPrompts.get(el)
- );
- },
-
- onNextPromptShowAllowFocusCheckboxFor(principal) {
- this._allowTabFocusByPromptPrincipal = principal;
- },
-
- get browser() {
- let browser = this._weakBrowserRef.get();
- if (!browser) {
- throw new Error("Stale promptbox! The associated browser is gone.");
- }
- return browser;
- },
-};
-
// Handle window-modal prompts that we want to display with the same style as
// tab-modal prompts.
var gDialogBox = {
@@ -9907,15 +7926,14 @@ var ConfirmationHint = {
* - event (DOM event): The event that triggered the feedback
* - descriptionId (string): message ID of the description text
* - position (string): position of the panel relative to the anchor.
- *
+ * - l10nArgs (object): l10n arguments for the messageId.
*/
show(anchor, messageId, options = {}) {
this._reset();
MozXULElement.insertFTLIfNeeded("toolkit/branding/brandings.ftl");
MozXULElement.insertFTLIfNeeded("browser/confirmationHints.ftl");
- document.l10n.setAttributes(this._message, messageId);
-
+ document.l10n.setAttributes(this._message, messageId, options.l10nArgs);
if (options.descriptionId) {
document.l10n.setAttributes(this._description, options.descriptionId);
this._description.hidden = false;
@@ -10018,11 +8036,9 @@ var FirefoxViewHandler = {
ChromeUtils.defineESModuleGetters(this, {
SyncedTabs: "resource://services-sync/SyncedTabs.sys.mjs",
});
- Services.obs.addObserver(this, "firefoxview-notification-dot-update");
},
uninit() {
CustomizableUI.removeListener(this);
- Services.obs.removeObserver(this, "firefoxview-notification-dot-update");
},
onWidgetRemoved(aWidgetId) {
if (aWidgetId == this.BUTTON_ID && this.tab) {
@@ -10075,7 +8091,7 @@ var FirefoxViewHandler = {
},
handleEvent(e) {
switch (e.type) {
- case "TabSelect":
+ case "TabSelect": {
const selected = e.target == this.tab;
this.button?.toggleAttribute("open", selected);
this.button?.setAttribute("aria-pressed", selected);
@@ -10086,6 +8102,7 @@ var FirefoxViewHandler = {
gBrowser.visibleTabs[0].style.MozUserFocus =
e.target == this.tab ? "normal" : "";
break;
+ }
case "TabClose":
this.tab = null;
gBrowser.tabContainer.removeEventListener("TabSelect", this);
@@ -10096,14 +8113,6 @@ var FirefoxViewHandler = {
break;
}
},
- observe(sub, topic, data) {
- switch (topic) {
- case "firefoxview-notification-dot-update":
- let shouldShow = data === "true";
- this._toggleNotificationDot(shouldShow);
- break;
- }
- },
_closeDeviceConnectedTab() {
if (!TabsSetupFlowManager.didFxaTabOpen) {
return;
@@ -10134,11 +8143,6 @@ var FirefoxViewHandler = {
_onTabForegrounded() {
if (this.tab?.selected) {
this.SyncedTabs.syncTabs();
- Services.obs.notifyObservers(
- null,
- "firefoxview-notification-dot-update",
- "false"
- );
}
},
_recordViewIfTabSelected() {
@@ -10162,7 +8166,4 @@ var FirefoxViewHandler = {
}
}
},
- _toggleNotificationDot(shouldShow) {
- this.button?.toggleAttribute("attention", shouldShow);
- },
};
diff --git a/browser/base/content/browser.js.globals b/browser/base/content/browser.js.globals
index c767bb5beb..910e0b5ca9 100644
--- a/browser/base/content/browser.js.globals
+++ b/browser/base/content/browser.js.globals
@@ -28,41 +28,20 @@
"gPopupBlockerObserver",
"gKeywordURIFixup",
"_createNullPrincipalFromTabUserContextId",
- "_resolveDelayedStartup",
- "delayedStartupPromise",
- "gBrowserInit",
"HandleAppCommandEvent",
- "gotoHistoryIndex",
- "BrowserForward",
- "BrowserBack",
- "BrowserHandleBackspace",
- "BrowserHandleShiftBackspace",
- "BrowserStop",
- "BrowserReloadOrDuplicate",
- "BrowserReload",
+ "BrowserCommands",
"kSkipCacheFlags",
- "BrowserReloadSkipCache",
- "BrowserHome",
"loadOneOrMoreURIs",
"openLocation",
- "BrowserOpenTab",
"gLastOpenDirectory",
- "BrowserOpenFileWindow",
- "BrowserCloseTabOrWindow",
- "BrowserTryToCloseWindow",
"getLoadContext",
"readFromClipboard",
- "BrowserViewSourceOfDocument",
- "BrowserViewSource",
- "BrowserPageInfo",
"UpdateUrlbarSearchSplitterState",
"UpdatePopupNotificationsVisibility",
"PageProxyClickHandler",
"BrowserOnClick",
"getMeOutOfHere",
"getDefaultHomePage",
- "BrowserFullScreen",
- "BrowserReloadWithFlags",
"getPEMString",
"browserDragAndDrop",
"homeButtonObserver",
@@ -72,7 +51,6 @@
"BrowserSearch",
"CreateContainerTabMenu",
"FillHistoryMenu",
- "BrowserDownloadsUI",
"toOpenWindowByType",
"OpenBrowserWindow",
"updateEditUIVisibility",
@@ -103,7 +81,6 @@
"handleLinkClick",
"middleMousePaste",
"handleDroppedLink",
- "BrowserForceEncodingDetection",
"ToolbarContextMenu",
"BrowserOffline",
"CanvasPermissionPromptHelper",
@@ -112,7 +89,6 @@
"WindowIsClosing",
"warnAboutClosingWindow",
"MailIntegration",
- "BrowserOpenAddonsMgr",
"AddKeywordForSearchField",
"restoreLastClosedTabOrWindowOrSession",
"undoCloseTab",
@@ -131,7 +107,6 @@
"PanicButtonNotifier",
"SafeBrowsingNotificationBox",
"TabDialogBox",
- "TabModalPromptBox",
"gDialogBox",
"ConfirmationHint",
"FirefoxViewHandler",
@@ -154,7 +129,6 @@
"DownloadsCommon",
"E10SUtils",
"ExtensionsUI",
- "FirefoxViewNotificationManager",
"HomePage",
"isProductURL",
"LightweightThemeConsumer",
@@ -196,7 +170,6 @@
"SubDialog",
"SubDialogManager",
"TabCrashHandler",
- "TabModalPrompt",
"TabsSetupFlowManager",
"TelemetryEnvironment",
"TranslationsParent",
diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml
index 1dcdd02cd1..aec0983a67 100644
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -38,11 +38,7 @@
both "content" and "skin" packages, which bug 1385444 will unify later. -->
<link rel="stylesheet" href="chrome://global/skin/global.css" />
- <link rel="stylesheet" href="chrome://global/content/tabprompts.css" />
- <link rel="stylesheet" href="chrome://global/skin/tabprompts.css" />
-
<link rel="stylesheet" href="chrome://browser/content/browser.css" />
- <link rel="stylesheet" href="chrome://browser/content/tabbrowser.css" />
<link
rel="stylesheet"
href="chrome://browser/content/downloads/downloads.css"
@@ -87,7 +83,6 @@
<link rel="localization" href="browser/translations.ftl" />
<link rel="localization" href="browser/unifiedExtensions.ftl"/>
<link rel="localization" href="browser/webrtcIndicator.ftl"/>
- <link rel="localization" href="toolkit/branding/accounts.ftl"/>
<link rel="localization" href="toolkit/branding/brandings.ftl"/>
<link rel="localization" href="toolkit/global/contextual-identity.ftl"/>
<link rel="localization" href="toolkit/global/textActions.ftl"/>
@@ -95,9 +90,9 @@
<!-- Untranslated FTL files -->
<link rel="localization" href="preview/enUS-searchFeatures.ftl" />
<link rel="localization" href="preview/interventions.ftl" />
- <link rel="localization" href="preview/select-translations.ftl"/>
<link rel="localization" href="browser/shopping.ftl"/>
<link rel="localization" href="preview/shopping.ftl"/>
+ <link rel="localization" href="preview/sidebar.ftl"/>
<link rel="localization" href="preview/profiles.ftl"/>
<link rel="localization" href="preview/onboarding.ftl"/>
@@ -110,6 +105,7 @@
<script>
/* eslint-env mozilla/browser-window */
+ Services.scriptloader.loadSubScript("chrome://browser/content/browser-init.js", this);
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/browser-captivePortal.js", this);
if (AppConstants.MOZ_DATA_REPORTING) {
@@ -119,7 +115,7 @@
Services.scriptloader.loadSubScript("chrome://browser/content/browser-development-helpers.js", this);
}
Services.scriptloader.loadSubScript("chrome://browser/content/browser-pageActions.js", this);
- Services.scriptloader.loadSubScript("chrome://browser/content/browser-sidebar.js", this);
+ Services.scriptloader.loadSubScript("chrome://browser/content/sidebar/browser-sidebar.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/browser-tabsintitlebar.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/browser-unified-extensions.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser.js", this);
diff --git a/browser/base/content/contentTheme.js b/browser/base/content/contentTheme.js
index 3c46b80bec..2eb339d69b 100644
--- a/browser/base/content/contentTheme.js
+++ b/browser/base/content/contentTheme.js
@@ -43,8 +43,8 @@
let browserStyle =
element.ownerGlobal?.docShell?.chromeEventHandler.style;
+ element.toggleAttribute("lwt-newtab", !!rgbaChannels);
if (!rgbaChannels) {
- element.removeAttribute("lwt-newtab");
element.toggleAttribute(
"lwt-newtab-brighttext",
prefersDarkQuery.matches
@@ -55,7 +55,6 @@
return null;
}
- element.setAttribute("lwt-newtab", "true");
const { r, g, b, a } = rgbaChannels;
let darkMode = !_isTextColorDark(r, g, b);
element.toggleAttribute("lwt-newtab-brighttext", darkMode);
@@ -159,15 +158,10 @@
* @param {Object} event object containing the theme or query update.
*/
handleEvent(event) {
- const root = document.documentElement;
-
if (event.type == "LightweightTheme:Set") {
- let { data } = event.detail;
- if (!data) {
- data = {};
- }
- this._setProperties(root, data);
+ this._setProperties(event.detail.data || {});
} else if (event.type == "change") {
+ const root = document.documentElement;
// If a lightweight theme doesn't apply, update lwt-newtab-brighttext to
// reflect prefers-color-scheme.
if (!root.hasAttribute("lwt-newtab")) {
@@ -192,22 +186,23 @@
/**
* Apply theme data to an element
- * @param {Element} root The element where the properties should be applied.
* @param {Object} themeData The theme data.
*/
- _setProperties(elem, themeData) {
+ _setProperties(themeData) {
+ const root = document.documentElement;
+ root.toggleAttribute("lwtheme", themeData.hasTheme);
for (let [cssVarName, definition] of inContentVariableMap) {
const { lwtProperty, processColor } = definition;
let value = themeData[lwtProperty];
if (processColor) {
- value = processColor(value, elem);
+ value = processColor(value, root);
} else if (value) {
const { r, g, b, a } = value;
value = `rgba(${r}, ${g}, ${b}, ${a})`;
}
- this._setProperty(elem, cssVarName, value);
+ this._setProperty(root, cssVarName, value);
}
},
};
diff --git a/browser/base/content/macWindow.inc.xhtml b/browser/base/content/macWindow.inc.xhtml
index b9ca44c7eb..b5afa5f644 100644
--- a/browser/base/content/macWindow.inc.xhtml
+++ b/browser/base/content/macWindow.inc.xhtml
@@ -16,7 +16,6 @@
<html:link rel="localization" href="browser/menubar.ftl"/>
<html:link rel="localization" href="browser/reportBrokenSite.ftl"/>
<html:link rel="localization" href="browser/screenshots.ftl"/>
- <html:link rel="localization" href="toolkit/branding/accounts.ftl"/>
<html:link rel="localization" href="toolkit/branding/brandings.ftl"/>
<html:link rel="localization" href="toolkit/global/textActions.ftl"/>
</linkset>
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
index bff8d98b27..ef8245938e 100644
--- a/browser/base/content/main-popupset.inc.xhtml
+++ b/browser/base/content/main-popupset.inc.xhtml
@@ -77,13 +77,16 @@
data-lazy-l10n-id="tab-context-close-n-tabs"
data-l10n-args='{"tabCount": 1}'
oncommand="TabContextMenu.closeContextTabs();"/>
+ <menuitem id="context_closeDuplicateTabs"
+ data-lazy-l10n-id="tab-context-close-duplicate-tabs"
+ oncommand="gBrowser.removeDuplicateTabs(TabContextMenu.contextTab);"/>
<menu id="context_closeTabOptions"
data-lazy-l10n-id="tab-context-close-multiple-tabs">
<menupopup id="closeTabOptions">
<menuitem id="context_closeTabsToTheStart" data-lazy-l10n-id="close-tabs-to-the-start"
- oncommand="gBrowser.removeTabsToTheStartFrom(TabContextMenu.contextTab, {animate: true});"/>
+ oncommand="gBrowser.removeTabsToTheStartFrom(TabContextMenu.contextTab);"/>
<menuitem id="context_closeTabsToTheEnd" data-lazy-l10n-id="close-tabs-to-the-end"
- oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab, {animate: true});"/>
+ oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab);"/>
<menuitem id="context_closeOtherTabs" data-lazy-l10n-id="close-other-tabs"
oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
</menupopup>
@@ -100,7 +103,7 @@
oncommand="FullScreen.setAutohide();"/>
<menuitem contexttype="fullscreen"
data-lazy-l10n-id="full-screen-exit"
- oncommand="BrowserFullScreen();"/>
+ oncommand="BrowserCommands.fullScreen();"/>
</menupopup>
<!-- bug 415444/582485: event.stopPropagation is here for the cloned version
@@ -109,7 +112,7 @@
-->
<menupopup id="backForwardMenu"
onpopupshowing="return FillHistoryMenu(event.target);"
- oncommand="gotoHistoryIndex(event); event.stopPropagation();"/>
+ oncommand="BrowserCommands.gotoHistoryIndex(event); event.stopPropagation();"/>
<tooltip id="aHTMLTooltip" page="true"/>
<tooltip id="remoteBrowserTooltip"/>
@@ -253,23 +256,26 @@
<menuitem id="sidebar-switcher-bookmarks"
data-l10n-id="sidebar-menu-bookmarks"
key="viewBookmarksSidebarKb"
- oncommand="SidebarUI.show('viewBookmarksSidebar');"/>
+ oncommand="SidebarController.show('viewBookmarksSidebar');"/>
<menuitem id="sidebar-switcher-history"
data-l10n-id="sidebar-menu-history"
key="key_gotoHistory"
- oncommand="SidebarUI.show('viewHistorySidebar');"/>
+ oncommand="SidebarController.show('viewHistorySidebar');"/>
<menuitem id="sidebar-switcher-tabs"
data-l10n-id="sidebar-menu-synced-tabs"
class="sync-ui-item"
- oncommand="SidebarUI.show('viewTabsSidebar');"/>
+ oncommand="SidebarController.show('viewTabsSidebar');"/>
+ <menuitem id="sidebar-switcher-megalist"
+ data-l10n-id="sidebar-menu-megalist"
+ oncommand="SidebarController.show('viewMegalistSidebar');"/>
<menuseparator/>
<!-- Extension toolbarbuttons go here. -->
<menuseparator id="sidebar-extensions-separator"/>
<menuitem id="sidebar-reverse-position"
- oncommand="SidebarUI.reversePosition()"/>
+ oncommand="SidebarController.reversePosition()"/>
<menuseparator/>
<menuitem data-l10n-id="sidebar-menu-close"
- oncommand="SidebarUI.hide()"/>
+ oncommand="SidebarController.hide()"/>
</menupopup>
<menupopup id="toolbar-context-menu"
@@ -360,7 +366,7 @@
oncommand="FullScreen.setAutohide();"/>
<menuitem contexttype="fullscreen"
data-lazy-l10n-id="full-screen-exit"
- oncommand="BrowserFullScreen();"/>
+ oncommand="BrowserCommands.fullScreen();"/>
</menupopup>
<menupopup id="blockedPopupOptions"
@@ -412,7 +418,24 @@
<hbox id="ctrlTab-showAll-container" pack="center"/>
</panel>
- <html:tab-preview id="tabbrowser-tab-preview" hidden="true" />
+ <!-- TODO: create lazily? -->
+ <panel id="tab-preview-panel"
+ type="arrow"
+ orient="vertical"
+ noautofocus="true"
+ norolluponanchor="true"
+ rolluponmousewheel="true"
+ consumeoutsideclicks="false">
+ <html:div class="tab-preview-text-container">
+ <html:div class="tab-preview-title"></html:div>
+ <html:div class="tab-preview-uri"></html:div>
+ <html:div class="tab-preview-pid-activeness">
+ <html:div class="tab-preview-pid"></html:div>
+ <html:div class="tab-preview-activeness"></html:div>
+ </html:div>
+ </html:div>
+ <html:div class="tab-preview-thumbnail-container"></html:div>
+ </panel>
<html:template id="pageActionPanelTemplate">
<panel id="pageActionPanel"
@@ -624,7 +647,7 @@
oncommand="gUnifiedExtensions.reportExtension(this.parentElement)" />
</menupopup>
- <menupopup id="translations-panel-settings-menupopup"
+ <menupopup id="full-page-translations-panel-settings-menupopup"
onpopupshown="FullPageTranslationsPanel.handleSettingsPopupShownEvent()"
onpopuphidden="FullPageTranslationsPanel.handleSettingsPopupHiddenEvent()">
<menuitem class="always-offer-translations-menuitem"
@@ -659,4 +682,14 @@
<menuitem data-l10n-id="translations-panel-settings-about2"
oncommand="FullPageTranslationsPanel.onAboutTranslations()"/>
</menupopup>
+
+ <menupopup id="select-translations-panel-settings-menupopup">
+ <menuitem id="select-translations-panel-open-settings-page-menuitem"
+ class="manage-languages-menuitem"
+ data-l10n-id="select-translations-panel-open-translations-settings-menuitem"
+ oncommand="SelectTranslationsPanel.openTranslationsSettingsPage()"/>
+ <menuitem id="select-translations-panel-about-translations-menuitem"
+ data-l10n-id="translations-panel-settings-about2"
+ oncommand="SelectTranslationsPanel.onAboutTranslations()"/>
+ </menupopup>
</popupset>
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
index fc19910726..0a67afa81f 100644
--- a/browser/base/content/navigator-toolbox.inc.xhtml
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
@@ -100,6 +100,9 @@
<image class="private-browsing-indicator-icon"/>
<label data-l10n-id="private-browsing-indicator-label"></label>
</hbox>
+ <toolbarbutton id="content-analysis-indicator"
+ oncommand="ContentAnalysis.showPanel(this, PanelUI);"
+ class="toolbarbutton-1 content-analysis-indicator-icon"/>
#include titlebar-items.inc.xhtml
@@ -491,13 +494,6 @@
tooltiptext="Ion"
onmousedown="switchToTabHavingURI('about:ion', true);"
onkeypress="switchToTabHavingURI('about:ion', true);"/>
- <toolbarbutton id="whats-new-menu-button"
- class="toolbarbutton-1"
- delegatesanchor="true"
- hidden="true"
- badged="true"
- onmousedown="PanelUI.showSubView('PanelUI-whatsNew', this, event);"
- onkeypress="PanelUI.showSubView('PanelUI-whatsNew', this, event);"/>
<toolbarbutton id="PanelUI-menu-button"
class="toolbarbutton-1"
delegatesanchor="true"
@@ -516,12 +512,12 @@
customizable="true">
<toolbartabstop skipintoolbarset="true"/>
- <hbox id="personal-toolbar-empty" skipintoolbarset="true" removable="false" hidden="true">
+ <hbox id="personal-toolbar-empty" skipintoolbarset="true" removable="false" hidden="true" role="alert">
<description id="personal-toolbar-empty-description"
data-l10n-id="bookmarks-toolbar-empty-message"
onclick="BookmarkingUI.openLibraryIfLinkClicked(event);"
onkeydown="BookmarkingUI.openLibraryIfLinkClicked(event);">
- <html:a data-l10n-name="manage-bookmarks" class="text-link" tabindex="0"/>
+ <html:a data-l10n-name="manage-bookmarks" class="text-link" tabindex="0" role="link"/>
</description>
</hbox>
@@ -625,7 +621,7 @@
<menuitem id="BMB_viewBookmarksSidebar"
data-l10n-id="bookmarks-tools-sidebar-visibility"
data-l10n-args='{ "isVisible": false }'
- oncommand="SidebarUI.toggle('viewBookmarksSidebar');"
+ oncommand="SidebarController.toggle('viewBookmarksSidebar');"
key="viewBookmarksSidebarKb"/>
<menuitem id="BMB_searchBookmarks"
data-l10n-id="bookmarks-search"
@@ -708,7 +704,7 @@
ondragenter="homeButtonObserver.onDragOver(event)"
ondrop="homeButtonObserver.onDrop(event)"
key="goHome"
- onclick="BrowserHome(event);"
+ onclick="BrowserCommands.home(event);"
cui-areatype="toolbar"/>
<toolbarbutton id="library-button" class="toolbarbutton-1 chromeclass-toolbar-additional subviewbutton-nav"
diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js
index 031a32dddf..1811dfcaca 100644
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1347,8 +1347,6 @@ class nsContextMenu {
!this.onTextInput &&
!this.onLink &&
!this.onPlainTextLink &&
- !this.onImage &&
- !this.onVideo &&
!this.onAudio &&
!this.onEditable &&
!this.onPassword;
@@ -1619,7 +1617,7 @@ class nsContextMenu {
// Open new "view source" window with the frame's URL.
viewFrameSource() {
- BrowserViewSourceOfDocument({
+ BrowserCommands.viewSourceOfDocument({
browser: this.browser,
URL: this.contentData.docLocation,
outerWindowID: this.frameOuterWindowID,
@@ -1627,7 +1625,7 @@ class nsContextMenu {
}
viewInfo() {
- BrowserPageInfo(
+ BrowserCommands.pageInfo(
this.contentData.docLocation,
null,
null,
@@ -1637,7 +1635,7 @@ class nsContextMenu {
}
viewImageInfo() {
- BrowserPageInfo(
+ BrowserCommands.pageInfo(
this.contentData.docLocation,
"mediaTab",
this.imageInfo,
@@ -1661,7 +1659,7 @@ class nsContextMenu {
}
viewFrameInfo() {
- BrowserPageInfo(
+ BrowserCommands.pageInfo(
this.contentData.docLocation,
null,
null,
@@ -1685,7 +1683,7 @@ class nsContextMenu {
// Change current window to the URL of the image, video, or audio.
viewMedia(e) {
- let where = whereToOpenLink(e, false, false);
+ let where = BrowserUtils.whereToOpenLink(e, false, false);
if (where == "current") {
where = "tab";
}
@@ -1982,7 +1980,7 @@ class nsContextMenu {
// we give up waiting for the filename.
function timerCallback() {}
timerCallback.prototype = {
- notify: function sLA_timer_notify(aTimer) {
+ notify: function sLA_timer_notify() {
channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
},
};
@@ -2175,7 +2173,10 @@ class nsContextMenu {
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
- clipboard.copyString(addresses);
+ clipboard.copyString(
+ addresses,
+ this.actor.manager.browsingContext.currentWindowGlobal
+ );
}
// Extract phone and put it on clipboard
@@ -2195,7 +2196,10 @@ class nsContextMenu {
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
- clipboard.copyString(phone);
+ clipboard.copyString(
+ phone,
+ this.actor.manager.browsingContext.currentWindowGlobal
+ );
}
copyLink() {
@@ -2204,7 +2208,10 @@ class nsContextMenu {
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
- clipboard.copyString(linkURL);
+ clipboard.copyString(
+ linkURL,
+ this.actor.manager.browsingContext.currentWindowGlobal
+ );
}
/**
@@ -2220,7 +2227,10 @@ class nsContextMenu {
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
- clipboard.copyString(strippedLinkURL);
+ clipboard.copyString(
+ strippedLinkURL,
+ this.actor.manager.browsingContext.currentWindowGlobal
+ );
}
}
@@ -2324,8 +2334,8 @@ class nsContextMenu {
try {
strippedLinkURI = QueryStringStripper.stripForCopyOrShare(this.linkURI);
} catch (e) {
- console.warn(`isLinkURIStrippable: ${e.message}`);
- return null;
+ console.warn(`stripForCopyOrShare: ${e.message}`);
+ return this.linkURI;
}
// If nothing can be stripped, we return the original URI
@@ -2458,7 +2468,10 @@ class nsContextMenu {
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
- clipboard.copyString(this.originalMediaURL);
+ clipboard.copyString(
+ this.originalMediaURL,
+ this.actor.manager.browsingContext.currentWindowGlobal
+ );
}
getImageText() {
@@ -2484,7 +2497,7 @@ class nsContextMenu {
let drmInfoURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") +
"drm-content";
- let dest = whereToOpenLink(aEvent);
+ let dest = BrowserUtils.whereToOpenLink(aEvent);
// Don't ever want this to open in the same tab as it'll unload the
// DRM'd video, which is going to be a bad idea in most cases.
if (dest == "current") {
@@ -2494,23 +2507,6 @@ class nsContextMenu {
}
/**
- * Retrieves an instance of the TranslationsParent actor.
- * @returns {TranslationsParent} - The TranslationsParent actor.
- * @throws Throws if an instance of the actor cannot be retrieved.
- */
- static #getTranslationsActor() {
- const actor =
- gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor(
- "Translations"
- );
-
- if (!actor) {
- throw new Error("Unable to get the TranslationsParent");
- }
- return actor;
- }
-
- /**
* Determines if Full Page Translations is currently active on this page.
*
* @returns {boolean}
@@ -2518,7 +2514,9 @@ class nsContextMenu {
static #isFullPageTranslationsActive() {
try {
const { requestedTranslationPair } =
- this.#getTranslationsActor().languageState;
+ TranslationsParent.getTranslationsActor(
+ gBrowser.selectedBrowser
+ ).languageState;
return requestedTranslationPair !== null;
} catch {
// Failed to retrieve the Full Page Translations actor, do nothing.
@@ -2532,7 +2530,16 @@ class nsContextMenu {
* @param {Event} event - The triggering event for opening the panel.
*/
openSelectTranslationsPanel(event) {
- SelectTranslationsPanel.open(event, this.#translationsLangPairPromise);
+ const context = this.contentData.context;
+ let screenX = context.screenXDevPx / window.devicePixelRatio;
+ let screenY = context.screenYDevPx / window.devicePixelRatio;
+ SelectTranslationsPanel.open(
+ event,
+ screenX,
+ screenY,
+ this.#getTextToTranslate(),
+ this.#translationsLangPairPromise
+ ).catch(console.error);
}
/**
@@ -2583,6 +2590,17 @@ class nsContextMenu {
}
/**
+ * Fetches text for translation, prioritizing selected text over link text.
+ *
+ * @returns {string} The text to translate.
+ */
+ #getTextToTranslate() {
+ return this.isTextSelected
+ ? this.selectionInfo.fullText.trim()
+ : this.linkTextStr.trim();
+ }
+
+ /**
* Displays or hides the translate-selection item in the context menu.
*/
showTranslateSelectionItem() {
@@ -2596,14 +2614,13 @@ class nsContextMenu {
"browser.translations.select.enable"
);
- // Selected text takes precedence over link text.
- const textToTranslate = this.isTextSelected
- ? this.selectedText.trim()
- : this.linkTextStr.trim();
+ const textToTranslate = this.#getTextToTranslate();
translateSelectionItem.hidden =
// Only show the item if the feature is enabled.
!(translationsEnabled && selectTranslationsEnabled) ||
+ // Only show the item if Translations is supported on this hardware.
+ !TranslationsParent.getIsTranslationsEngineSupported() ||
// If there is no text to translate, we have nothing to do.
textToTranslate.length === 0 ||
// We do not allow translating selections on top of Full Page Translations.
diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js
index f3999a7cc5..c186e9572d 100644
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -47,7 +47,7 @@ pageInfoTreeView.prototype = {
return this.data[row][column.index] || "";
},
- setCellValue(row, column, value) {},
+ setCellValue() {},
setCellText(row, column, value) {
this.data[row][column.index] = value;
@@ -112,52 +112,52 @@ pageInfoTreeView.prototype = {
this.sortcol = treecol.index;
},
- getRowProperties(row) {
+ getRowProperties() {
return "";
},
- getCellProperties(row, column) {
+ getCellProperties() {
return "";
},
- getColumnProperties(column) {
+ getColumnProperties() {
return "";
},
- isContainer(index) {
+ isContainer() {
return false;
},
- isContainerOpen(index) {
+ isContainerOpen() {
return false;
},
- isSeparator(index) {
+ isSeparator() {
return false;
},
isSorted() {
return this.sortcol > -1;
},
- canDrop(index, orientation) {
+ canDrop() {
return false;
},
- drop(row, orientation) {
+ drop() {
return false;
},
- getParentIndex(index) {
+ getParentIndex() {
return 0;
},
- hasNextSibling(index, after) {
+ hasNextSibling() {
return false;
},
- getLevel(index) {
+ getLevel() {
return 0;
},
- getImageSrc(row, column) {},
+ getImageSrc() {},
getCellValue(row, column) {
let col = column != null ? column : this.copycol;
return row < 0 || col < 0 ? "" : this.data[row][col] || "";
},
- toggleOpenState(index) {},
- cycleHeader(col) {},
+ toggleOpenState() {},
+ cycleHeader() {},
selectionChanged() {},
- cycleCell(row, column) {},
- isEditable(row, column) {
+ cycleCell() {},
+ isEditable() {
return false;
},
};
@@ -475,10 +475,10 @@ async function loadTab(args) {
function openCacheEntry(key, cb) {
var checkCacheListener = {
- onCacheEntryCheck(entry) {
+ onCacheEntryCheck() {
return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
},
- onCacheEntryAvailable(entry, isNew, status) {
+ onCacheEntryAvailable(entry) {
cb(entry);
},
};
@@ -1085,7 +1085,7 @@ let treeController = {
return command == "cmd_copy" || command == "cmd_selectAll";
},
- isCommandEnabled(command) {
+ isCommandEnabled() {
return true; // not worth checking for this
},
diff --git a/browser/base/content/pageinfo/pageInfo.xhtml b/browser/base/content/pageinfo/pageInfo.xhtml
index baa017702f..cca293c534 100644
--- a/browser/base/content/pageinfo/pageInfo.xhtml
+++ b/browser/base/content/pageinfo/pageInfo.xhtml
@@ -10,6 +10,10 @@
data-l10n-id="page-info-window"
data-l10n-attrs="style"
windowtype="Browser:page-info"
+#ifdef XP_MACOSX
+ drawtitle="true"
+ chromemargin="0,0,0,0"
+#endif
onload="onLoadPageInfo()"
align="stretch"
screenX="10" screenY="10"
diff --git a/browser/base/content/pageinfo/permissions.js b/browser/base/content/pageinfo/permissions.js
index 7834e27c98..7803cbafe5 100644
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -28,7 +28,7 @@ let gPermissions = SitePermissions.listPermissions()
});
var permissionObserver = {
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (aTopic == "perm-changed") {
var permission = aSubject.QueryInterface(Ci.nsIPermission);
if (
diff --git a/browser/base/content/pageinfo/security.js b/browser/base/content/pageinfo/security.js
index 3acd3cc452..9f9fb17bea 100644
--- a/browser/base/content/pageinfo/security.js
+++ b/browser/base/content/pageinfo/security.js
@@ -399,7 +399,7 @@ function realmHasPasswords(uri) {
*
* @param host - the domain name to look for in history
*/
-function previousVisitCount(host, endTimeReference) {
+function previousVisitCount(host) {
if (!host) {
return 0;
}
diff --git a/browser/base/content/popup-notifications.inc b/browser/base/content/popup-notifications.inc
index daee34e6fe..3d57f4808c 100644
--- a/browser/base/content/popup-notifications.inc
+++ b/browser/base/content/popup-notifications.inc
@@ -35,7 +35,7 @@
<description id="webRTC-all-windows-shared" hidden="true" data-l10n-id="popup-all-windows-shared"></description>
</popupnotificationcontent>
- <popupnotificationcontent id="webRTC-preview" hidden="true">
+ <popupnotificationcontent id="webRTC-preview" orient="vertical" hidden="true">
<html:video id="webRTC-previewVideo" tabindex="-1"/>
<vbox id="webRTC-previewWarningBox">
<description id="webRTC-previewWarning"/>
diff --git a/browser/base/content/sanitizeDialog.js b/browser/base/content/sanitizeDialog.js
index 09a7d927df..1d9ea978b9 100644
--- a/browser/base/content/sanitizeDialog.js
+++ b/browser/base/content/sanitizeDialog.js
@@ -218,7 +218,7 @@ var gSanitizePromptDialog = {
acceptButton.disabled = noneChecked;
},
- selectByTimespan() {
+ async selectByTimespan() {
// This method is the onselect handler for the duration dropdown. As a
// result it's called a couple of times before onload calls init().
if (!this._inited) {
@@ -247,7 +247,7 @@ var gSanitizePromptDialog = {
}
// make sure the sizes are updated in the new dialog
else {
- this.updateDataSizesInUI();
+ await this.updateDataSizesInUI();
}
return;
}
@@ -267,7 +267,7 @@ var gSanitizePromptDialog = {
if (!lazy.USE_OLD_DIALOG) {
// We only update data sizes to display on the new dialog
- this.updateDataSizesInUI();
+ await this.updateDataSizesInUI();
}
},
@@ -399,7 +399,7 @@ var gSanitizePromptDialog = {
this.cacheSize = lazy.DownloadUtils.convertByteUnits(cacheSize);
this._dataSizesUpdated = true;
- this.updateDataSizesInUI();
+ await this.updateDataSizesInUI();
},
/**
@@ -473,7 +473,7 @@ var gSanitizePromptDialog = {
/**
* Updates data sizes displayed based on new selected timespan
*/
- updateDataSizesInUI() {
+ async updateDataSizesInUI() {
if (!this._dataSizesUpdated) {
return;
}
@@ -491,6 +491,7 @@ var gSanitizePromptDialog = {
let timeSpanSelected = TIMESPAN_SELECTION_MAP[index];
let [amount, unit] = this.siteDataSizes[timeSpanSelected];
+ document.l10n.pauseObserving();
document.l10n.setAttributes(
this._cookiesAndSiteDataCheckbox,
"item-cookies-site-data-with-size",
@@ -503,6 +504,18 @@ var gSanitizePromptDialog = {
"item-cached-content-with-size",
{ amount, unit }
);
+
+ // make sure l10n updates are completed
+ await document.l10n.translateElements([
+ this._cookiesAndSiteDataCheckbox,
+ this._cacheCheckbox,
+ ]);
+
+ document.l10n.resumeObserving();
+
+ // the data sizes may have led to wrapping, resize dialog to make sure the buttons
+ // don't move out of view
+ await window.resizeDialog();
},
/**
diff --git a/browser/base/content/spotlight.html b/browser/base/content/spotlight.html
index a948f8dbf4..216f290efd 100644
--- a/browser/base/content/spotlight.html
+++ b/browser/base/content/spotlight.html
@@ -19,6 +19,7 @@
<link rel="localization" href="branding/brand.ftl" />
<link rel="localization" href="toolkit/branding/brandings.ftl" />
<link rel="localization" href="browser/newtab/asrouter.ftl" />
+ <link rel="localization" href="preview/onboarding.ftl" />
<link rel="localization" href="browser/newtab/onboarding.ftl" />
<link rel="localization" href="browser/spotlight.ftl" />
<link rel="localization" href="browser/migrationWizard.ftl" />
diff --git a/browser/base/content/tabbrowser-tab.js b/browser/base/content/tabbrowser-tab.js
index ed3d4bb727..807a7d93fd 100644
--- a/browser/base/content/tabbrowser-tab.js
+++ b/browser/base/content/tabbrowser-tab.js
@@ -259,6 +259,14 @@
return this._lastAccessed == Infinity ? Date.now() : this._lastAccessed;
}
+ /**
+ * Returns a timestamp which attempts to represent the last time the user saw this tab.
+ * If the tab has not been active in this session, any lastAccessed is used. We
+ * differentiate between selected and explicitly visible; a selected tab in a hidden
+ * window is last seen when that window and tab were last visible.
+ * We use the application start time as a fallback value when no other suitable value
+ * is available.
+ */
get lastSeenActive() {
const isForegroundWindow =
this.ownerGlobal ==
@@ -270,8 +278,16 @@
if (this._lastSeenActive) {
return this._lastSeenActive;
}
- // Use the application start time as the fallback value
- return Services.startup.getStartupInfo().start.getTime();
+
+ const appStartTime = Services.startup.getStartupInfo().start.getTime();
+ if (!this._lastAccessed || this._lastAccessed >= appStartTime) {
+ // When the tab was created this session but hasn't been seen by the user,
+ // default to the application start time.
+ return appStartTime;
+ }
+ // The tab was restored from a previous session but never seen.
+ // Use the lastAccessed as the best proxy for when the user might have seen it.
+ return this._lastAccessed;
}
get _overPlayingIcon() {
@@ -457,7 +473,7 @@
}
}
- on_mouseup(event) {
+ on_mouseup() {
// Make sure that clear-selection is released.
// Otherwise selection using Shift key may be broken.
gBrowser.unlockClearMultiSelection();
@@ -706,11 +722,11 @@
this.setAttribute("aria-describedby", "tabbrowser-tab-a11y-desc");
}
- on_focus(event) {
+ on_focus() {
this.updateA11yDescription();
}
- on_AriaFocus(event) {
+ on_AriaFocus() {
this.updateA11yDescription();
}
}
diff --git a/browser/base/content/tabbrowser-tabs.js b/browser/base/content/tabbrowser-tabs.js
index 36b6aeb390..9b30584077 100644
--- a/browser/base/content/tabbrowser-tabs.js
+++ b/browser/base/content/tabbrowser-tabs.js
@@ -34,6 +34,7 @@
this.addEventListener("drop", this);
this.addEventListener("dragend", this);
this.addEventListener("dragleave", this);
+ this.addEventListener("mouseleave", this);
}
init() {
@@ -61,6 +62,7 @@
this._hiddenSoundPlayingTabs = new Set();
this._allTabs = null;
this._visibleTabs = null;
+ this._previewPanel = null;
var tab = this.allTabs[0];
tab.label = this.emptyTabTitle;
@@ -123,26 +125,17 @@
this.tabbox.tabpanels.setAttribute("async", "true");
}
- this.configureTooltip = () => {
- // fall back to original tooltip behavior if pref is not set
- this.tooltip = this._showCardPreviews ? null : "tabbrowser-tab-tooltip";
-
- // activate new tooltip behavior if pref is set
- document
- .getElementById("tabbrowser-tab-preview")
- .toggleAttribute("hidden", !this._showCardPreviews);
- };
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_showCardPreviews",
TAB_PREVIEW_PREF,
- false,
- () => this.configureTooltip()
+ false
);
- this.configureTooltip();
+ this.tooltip = "tabbrowser-tab-tooltip";
+ this._previewPanel = null;
}
- on_TabSelect(event) {
+ on_TabSelect() {
this._handleTabSelect();
}
@@ -188,23 +181,23 @@
}
on_TabHoverStart(event) {
- if (this._showCardPreviews) {
- const previewContainer = document.getElementById(
- "tabbrowser-tab-preview"
+ if (!this._showCardPreviews) {
+ return;
+ }
+ if (!this._previewPanel) {
+ // load the tab preview component
+ const TabPreviewPanel = ChromeUtils.importESModule(
+ "chrome://browser/content/tabpreview/tab-preview-panel.mjs"
+ ).default;
+ this._previewPanel = new TabPreviewPanel(
+ document.getElementById("tab-preview-panel")
);
- previewContainer.tab = event.target;
}
+ this._previewPanel.activate(event.target);
}
on_TabHoverEnd(event) {
- if (this._showCardPreviews) {
- const previewContainer = document.getElementById(
- "tabbrowser-tab-preview"
- );
- if (previewContainer.tab === event.target) {
- previewContainer.tab = null;
- }
- }
+ this._previewPanel?.deactivate(event.target);
}
on_transitionend(event) {
@@ -241,7 +234,7 @@
}
if (!this._blockDblClick) {
- BrowserOpenTab();
+ BrowserCommands.openTab();
}
event.preventDefault();
@@ -333,7 +326,7 @@
(!RTL_UI && event.clientX > endOfTab) ||
(RTL_UI && event.clientX < endOfTab)
) {
- BrowserOpenTab();
+ BrowserCommands.openTab();
}
} else {
return;
@@ -450,6 +443,7 @@
return;
}
+ this._previewPanel?.deactivate();
this.startTabDrag(event, tab);
}
@@ -1092,6 +1086,10 @@
return children;
}
+ get previewPanel() {
+ return this._previewPanel;
+ }
+
_getVisibleTabs() {
if (!this._visibleTabs) {
this._visibleTabs = Array.prototype.filter.call(
@@ -1205,7 +1203,7 @@
};
}
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
switch (aTopic) {
case "nsPref:changed":
// This is has to deal with changes in
@@ -1851,6 +1849,9 @@
this._unlockTabSizing();
}
break;
+ case "mouseleave":
+ this._previewPanel?.deactivate();
+ break;
default:
let methodName = `on_${aEvent.type}`;
if (methodName in this) {
diff --git a/browser/base/content/tabbrowser.css b/browser/base/content/tabbrowser.css
deleted file mode 100644
index 120203141c..0000000000
--- a/browser/base/content/tabbrowser.css
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 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/. */
-
-.tab-close-button[pinned],
-#tabbrowser-tabs[closebuttons="activetab"] > #tabbrowser-arrowscrollbox > .tabbrowser-tab > .tab-stack > .tab-content > .tab-close-button:not([selected]),
-.tab-icon-pending:not([pendingicon]),
-.tab-icon-pending[busy],
-.tab-icon-pending[pinned],
-.tab-icon-image:not([src], [pinned], [crashed], [pictureinpicture])[selected],
-.tab-icon-image:not([src], [pinned], [crashed], [sharing], [pictureinpicture]),
-.tab-icon-image[busy],
-.tab-throbber:not([busy]),
-.tab-sharing-icon-overlay,
-.tab-icon-overlay {
- display: none;
-}
-
-:root[uidensity=compact] .tab-secondary-label,
-.tab-secondary-label:not([soundplaying], [muted], [activemedia-blocked], [pictureinpicture]),
-.tab-secondary-label:not([activemedia-blocked]) > .tab-icon-sound-blocked-label,
-.tab-secondary-label[muted][activemedia-blocked] > .tab-icon-sound-blocked-label,
-.tab-secondary-label[activemedia-blocked] > .tab-icon-sound-playing-label,
-.tab-secondary-label[muted] > .tab-icon-sound-playing-label,
-.tab-secondary-label[pictureinpicture] > .tab-icon-sound-playing-label,
-.tab-secondary-label[pictureinpicture] > .tab-icon-sound-muted-label,
-.tab-secondary-label:not([pictureinpicture]) > .tab-icon-sound-pip-label,
-.tab-secondary-label:not([muted]) > .tab-icon-sound-muted-label,
-.tab-secondary-label:not([showtooltip]) > .tab-icon-sound-tooltip-label,
-.tab-secondary-label[showtooltip] > .tab-icon-sound-label:not(.tab-icon-sound-tooltip-label) {
- display: none;
-}
-
-.tab-sharing-icon-overlay[sharing]:not([selected]),
-.tab-icon-overlay:is([soundplaying], [muted], [activemedia-blocked], [crashed]) {
- display: revert;
-}
-
-.tabbrowser-tab {
- --tab-label-mask-size: 2em;
-}
-
-.tab-label {
- white-space: nowrap;
- line-height: 1.7; /* override 'normal' in case of fallback math fonts with huge metrics */
-}
-
-.tab-secondary-label {
- margin: -.3em 0 .3em; /* adjust margins to compensate for line-height of .tab-label */
-}
-
-.tab-label-container {
- overflow: hidden;
-}
-
-.tab-label-container[pinned] {
- width: 0;
-}
-
-.tab-label-container[textoverflow][labeldirection=ltr]:not([pinned]),
-.tab-label-container[textoverflow]:not([labeldirection], [pinned]):-moz-locale-dir(ltr) {
- direction: ltr;
- mask-image: linear-gradient(to left, transparent, black var(--tab-label-mask-size));
-}
-
-.tab-label-container[textoverflow][labeldirection=rtl]:not([pinned]),
-.tab-label-container[textoverflow]:not([labeldirection], [pinned]):-moz-locale-dir(rtl) {
- direction: rtl;
- mask-image: linear-gradient(to right, transparent, black var(--tab-label-mask-size));
-}
-
-tabpanels {
- background-color: transparent;
-}
-
-/* Apply crisp rendering for favicons at exactly 2dppx resolution */
-@media (resolution: 2dppx) {
- .tab-icon-image {
- image-rendering: -moz-crisp-edges;
- }
-}
-
-.closing-tabs-spacer {
- pointer-events: none;
-}
-
-#tabbrowser-arrowscrollbox:not(:hover) > #tabbrowser-arrowscrollbox-periphery > .closing-tabs-spacer {
- transition: width .15s ease-out;
-}
-
-browser[blank],
-browser[pendingpaint] {
- opacity: 0;
-}
-
-#tabbrowser-tabpanels[pendingpaint] {
- background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
- background-repeat: no-repeat;
- background-position: center center;
- background-size: 30px;
-}
diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js
index 54a801939a..f319fd5d46 100644
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -67,7 +67,7 @@
replaceContainerClass("color", hbox, identity.color);
let label = ContextualIdentityService.getUserContextLabel(userContextId);
- document.getElementById("userContext-label").setAttribute("value", label);
+ document.getElementById("userContext-label").textContent = label;
// Also set the container label as the tooltip so we can only show the icon
// in small windows.
hbox.setAttribute("tooltiptext", label);
@@ -110,6 +110,12 @@
"privacy.exposeContentTitleInWindow.pbm",
true
);
+ XPCOMUtils.defineLazyPreferenceGetter(
+ this,
+ "_showTabCardPreview",
+ "browser.tabs.cardPreview.enabled",
+ true
+ );
if (AppConstants.MOZ_CRASHREPORTER) {
ChromeUtils.defineESModuleGetters(this, {
@@ -161,6 +167,8 @@
TO_START: 2,
TO_END: 3,
MULTI_SELECTED: 4,
+ DUPLICATES: 6,
+ ALL_DUPLICATES: 7,
},
_lastRelatedTabMap: new WeakMap(),
@@ -348,6 +356,90 @@
return this.tabContainer._getVisibleTabs();
},
+ getDuplicateTabsToClose(aTab) {
+ // One would think that a set is better, but it would need to copy all
+ // the strings instead of just keeping references to the nsIURI objects,
+ // and the array is presumed to be small anyways.
+ let keys = [];
+ let keyForTab = tab => {
+ let uri = tab.linkedBrowser?.currentURI;
+ if (!uri) {
+ return null;
+ }
+ return {
+ uri,
+ userContextId: tab.userContextId,
+ };
+ };
+ let keyEquals = (a, b) => {
+ return a.userContextId == b.userContextId && a.uri.equals(b.uri);
+ };
+ if (aTab.multiselected) {
+ for (let tab of this.selectedTabs) {
+ let key = keyForTab(tab);
+ if (key) {
+ keys.push(key);
+ }
+ }
+ } else {
+ let key = keyForTab(aTab);
+ if (key) {
+ keys.push(key);
+ }
+ }
+
+ if (!keys.length) {
+ return [];
+ }
+
+ let duplicateTabs = [];
+ for (let tab of this.tabs) {
+ if (tab == aTab || tab.pinned) {
+ continue;
+ }
+ if (aTab.multiselected && tab.multiselected) {
+ continue;
+ }
+ let key = keyForTab(tab);
+ if (key && keys.some(k => keyEquals(k, key))) {
+ duplicateTabs.push(tab);
+ }
+ }
+
+ return duplicateTabs;
+ },
+
+ getAllDuplicateTabsToClose() {
+ let lastSeenTabs = this.tabs.toSorted(
+ (a, b) => b.lastSeenActive - a.lastSeenActive
+ );
+ let duplicateTabs = [];
+ let keys = [];
+ for (let tab of lastSeenTabs) {
+ const uri = tab.linkedBrowser?.currentURI;
+ if (!uri) {
+ // Can't tell if it's a duplicate without a URI.
+ // Safest to leave it be.
+ continue;
+ }
+
+ const key = {
+ uri,
+ userContextId: tab.userContextId,
+ };
+ if (
+ !tab.pinned &&
+ keys.some(
+ k => k.userContextId == key.userContextId && k.uri.equals(key.uri)
+ )
+ ) {
+ duplicateTabs.push(tab);
+ }
+ keys.push(key);
+ }
+ return duplicateTabs;
+ },
+
get _numPinnedTabs() {
for (var i = 0; i < this.tabs.length; i++) {
if (!this.tabs[i].pinned) {
@@ -893,14 +985,6 @@
: "";
},
- getTabModalPromptBox(aBrowser) {
- let browser = aBrowser || this.selectedBrowser;
- if (!browser.tabModalPromptBox) {
- browser.tabModalPromptBox = new TabModalPromptBox(browser);
- }
- return browser.tabModalPromptBox;
- },
-
getTabDialogBox(aBrowser) {
if (!aBrowser) {
throw new Error("aBrowser is required");
@@ -1116,6 +1200,11 @@
return;
}
+ let oldBrowser = this.selectedBrowser;
+ // Once the async switcher starts, it's unpredictable when it will touch
+ // the address bar, thus we store its state immediately.
+ gURLBar?.saveSelectionStateForBrowser(oldBrowser);
+
let newTab = this.getTabForBrowser(newBrowser);
if (!aForceUpdate) {
@@ -1145,8 +1234,6 @@
}
this._lastRelatedTabMap = new WeakMap();
- let oldBrowser = this.selectedBrowser;
-
if (!gMultiProcessBrowser) {
oldBrowser.removeAttribute("primary");
oldBrowser.docShellIsActive = false;
@@ -1154,11 +1241,6 @@
newBrowser.docShellIsActive = !document.hidden;
}
- if (gURLBar) {
- oldBrowser._urlbarSelectionStart = gURLBar.selectionStart;
- oldBrowser._urlbarSelectionEnd = gURLBar.selectionEnd;
- }
-
this._selectedBrowser = newBrowser;
this._selectedTab = newTab;
this.showTab(newTab);
@@ -1320,31 +1402,6 @@
this.addToMultiSelectedTabs(oldTab);
}
- if (oldBrowser != newBrowser && oldBrowser.getInPermitUnload) {
- oldBrowser.getInPermitUnload(inPermitUnload => {
- if (!inPermitUnload) {
- return;
- }
- // Since the user is switching away from a tab that has
- // a beforeunload prompt active, we remove the prompt.
- // This prevents confusing user flows like the following:
- // 1. User attempts to close Firefox
- // 2. User switches tabs (ingoring a beforeunload prompt)
- // 3. User returns to tab, presses "Leave page"
- let promptBox = this.getTabModalPromptBox(oldBrowser);
- let prompts = promptBox.listPrompts();
- // There might not be any prompts here if the tab was closed
- // while in an onbeforeunload prompt, which will have
- // destroyed aforementioned prompt already, so check there's
- // something to remove, first:
- if (prompts.length) {
- // NB: This code assumes that the beforeunload prompt
- // is the top-most prompt on the tab.
- prompts[prompts.length - 1].abortPrompt();
- }
- });
- }
-
if (!gMultiProcessBrowser) {
this._adjustFocusBeforeTabSwitch(oldTab, newTab);
this._adjustFocusAfterTabSwitch(newTab);
@@ -1439,19 +1496,6 @@
newBrowser.tabDialogBox.focus();
return;
}
- if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
- // If there's a tabmodal prompt showing, focus it.
- let prompts = newBrowser.tabModalPromptBox.listPrompts();
- let prompt = prompts[prompts.length - 1];
- // @tabmodalPromptShowing is also set for other tab modal prompts
- // (e.g. the Payment Request dialog) so there may not be a <tabmodalprompt>.
- // Bug 1492814 will implement this for the Payment Request dialog.
- if (prompt) {
- prompt.Dialog.setDefaultFocus();
- return;
- }
- }
-
// Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible
// if the tab is a blank one.
@@ -1491,19 +1535,12 @@
if (currentActiveElement != document.activeElement) {
return;
}
-
- gURLBar.setSelectionRange(
- newBrowser._urlbarSelectionStart,
- newBrowser._urlbarSelectionEnd
- );
+ gURLBar.restoreSelectionStateForBrowser(newBrowser);
},
{ once: true }
);
} else {
- gURLBar.setSelectionRange(
- newBrowser._urlbarSelectionStart,
- newBrowser._urlbarSelectionEnd
- );
+ gURLBar.restoreSelectionStateForBrowser(newBrowser);
}
};
@@ -1656,6 +1693,22 @@
_dataURLRegEx: /^data:[^,]+;base64,/i,
+ // Regex to test if a string (potential tab label) consists of only non-
+ // printable characters. We consider Unicode categories Separator
+ // (spaces & line-breaks) and Other (control chars, private use, non-
+ // character codepoints) to be unprintable, along with a few specific
+ // characters whose expected rendering is blank:
+ // U+2800 BRAILLE PATTERN BLANK (category So)
+ // U+115F HANGUL CHOSEONG FILLER (category Lo)
+ // U+1160 HANGUL JUNGSEONG FILLER (category Lo)
+ // U+3164 HANGUL FILLER (category Lo)
+ // U+FFA0 HALFWIDTH HANGUL FILLER (category Lo)
+ // We also ignore combining marks, as in the absence of a printable base
+ // character they are unlikely to be usefully rendered, and may well be
+ // clipped away entirely.
+ _nonPrintingRegEx:
+ /^[\p{Z}\p{C}\p{M}\u{115f}\u{1160}\u{2800}\u{3164}\u{ffa0}]*$/u,
+
setTabTitle(aTab) {
var browser = this.getBrowserForTab(aTab);
var title = browser.contentTitle;
@@ -1676,6 +1729,16 @@
}
let isURL = false;
+
+ // Trim leading and trailing whitespace from the title.
+ title = title.trim();
+
+ // If the title contains only non-printing characters (or only combining
+ // marks, but no base character for them), we won't use it.
+ if (this._nonPrintingRegEx.test(title)) {
+ title = "";
+ }
+
let isContentTitle = !!title;
if (!title) {
// See if we can use the URI as the title.
@@ -2097,18 +2160,6 @@
// doesn't keep the window alive.
b.permanentKey = new (Cu.getGlobalForObject(Services).Object)();
- // Ensure that SessionStore has flushed any session history state from the
- // content process before we this browser's remoteness.
- if (!Services.appinfo.sessionHistoryInParent) {
- b.prepareToChangeRemoteness = () =>
- SessionStore.prepareToChangeRemoteness(b);
- b.afterChangeRemoteness = switchId => {
- let tab = this.getTabForBrowser(b);
- SessionStore.finishTabRemotenessChange(tab, switchId);
- return true;
- };
- }
-
const defaultBrowserAttributes = {
contextmenu: "contentAreaContextMenu",
message: "true",
@@ -2176,16 +2227,12 @@
b.setAttribute("name", name);
}
- let notificationbox = document.createXULElement("notificationbox");
- notificationbox.setAttribute("notificationside", "top");
-
let stack = document.createXULElement("stack");
stack.className = "browserStack";
stack.appendChild(b);
let browserContainer = document.createXULElement("vbox");
browserContainer.className = "browserContainer";
- browserContainer.appendChild(notificationbox);
browserContainer.appendChild(stack);
let browserSidebarContainer = document.createXULElement("hbox");
@@ -2682,8 +2729,6 @@
animate,
userContextId,
openerTab,
- createLazyBrowser,
- skipAnimation,
pinned,
noInitialLabel,
skipBackgroundNotify,
@@ -2849,8 +2894,6 @@
uriString,
userContextId,
openerTab,
- createLazyBrowser,
- skipAnimation,
pinned,
noInitialLabel,
skipBackgroundNotify,
@@ -3306,6 +3349,24 @@
return true;
}
+ const shownDupeDialogPref =
+ "browser.tabs.haveShownCloseAllDuplicateTabsWarning";
+ if (
+ aCloseTabs == this.closingTabsEnum.ALL_DUPLICATES &&
+ !Services.prefs.getBoolPref(shownDupeDialogPref, false)
+ ) {
+ // The first time a user closes all duplicate tabs, tell them what will
+ // happen and give them a chance to back away.
+ Services.prefs.setBoolPref(shownDupeDialogPref, true);
+
+ window.focus();
+ const [title, text] = this.tabLocalization.formatValuesSync([
+ { id: "tabbrowser-confirm-close-duplicate-tabs-title" },
+ { id: "tabbrowser-confirm-close-duplicate-tabs-text" },
+ ]);
+ return Services.prompt.confirm(window, title, text);
+ }
+
const pref =
aCloseTabs == this.closingTabsEnum.ALL
? "browser.tabs.warnOnClose"
@@ -3367,7 +3428,7 @@
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
let closeTabEnumKey =
Object.entries(this.closingTabsEnum)
- .find(([k, v]) => v == aCloseTabs)?.[0]
+ .find(([, v]) => v == aCloseTabs)?.[0]
?.toLowerCase() || "some";
let warnCheckbox = warnOnClose.value ? "checked" : "unchecked";
@@ -3545,6 +3606,42 @@
return tabsToEnd;
},
+ removeDuplicateTabs(aTab) {
+ this._removeDuplicateTabs(
+ aTab,
+ this.getDuplicateTabsToClose(aTab),
+ this.closingTabsEnum.DUPLICATES
+ );
+ },
+
+ _removeDuplicateTabs(aConfirmationAnchor, tabs, aCloseTabs) {
+ if (!tabs.length) {
+ return;
+ }
+
+ if (!this.warnAboutClosingTabs(tabs.length, aCloseTabs)) {
+ return;
+ }
+
+ this.removeTabs(tabs);
+ ConfirmationHint.show(
+ aConfirmationAnchor,
+ "confirmation-hint-duplicate-tabs-closed",
+ { l10nArgs: { tabCount: tabs.length } }
+ );
+ },
+
+ removeAllDuplicateTabs() {
+ // I would like to have the caller provide this target,
+ // but the caller lives in a different document.
+ let alltabsButton = document.getElementById("alltabs-button");
+ this._removeDuplicateTabs(
+ alltabsButton,
+ this.getAllDuplicateTabsToClose(),
+ this.closingTabsEnum.ALL_DUPLICATES
+ );
+ },
+
/**
* In a multi-select context, the tabs (except pinned tabs) that are located to the
* left of the leftmost selected tab will be removed.
@@ -3674,6 +3771,8 @@
tabs,
{
animate,
+ // See bug 1883051
+ // eslint-disable-next-line no-unused-vars
suppressWarnAboutClosingWindow,
skipPermitUnload,
skipRemoves,
@@ -4390,6 +4489,56 @@
);
}
},
+ /**
+ * Closes tabs within the browser that match a given list of nsURIs. Returns
+ * any nsURIs that could not be closed successfully. This does not close any
+ * tabs that have a beforeUnload prompt
+ *
+ * @param {nsURI[]} urisToClose
+ * The set of uris to remove.
+ * @returns {nsURI[]}
+ * the nsURIs that weren't found in this browser
+ */
+ async closeTabsByURI(urisToClose) {
+ let remainingURIsToClose = [...urisToClose];
+ let tabsToRemove = [];
+ for (let tab of this.tabs) {
+ let currentURI = tab.linkedBrowser.currentURI;
+ // Find any URI that matches the current tab's URI
+ const matchedIndex = remainingURIsToClose.findIndex(uriToClose =>
+ uriToClose.equals(currentURI)
+ );
+
+ if (matchedIndex > -1) {
+ tabsToRemove.push(tab);
+ remainingURIsToClose.splice(matchedIndex, 1); // Remove the matched URI
+ }
+ }
+
+ if (tabsToRemove.length) {
+ const { beforeUnloadComplete, lastToClose } = this._startRemoveTabs(
+ tabsToRemove,
+ {
+ animate: false,
+ suppressWarnAboutClosingWindow: true,
+ skipPermitUnload: false,
+ skipRemoves: false,
+ skipSessionStore: false,
+ }
+ );
+
+ // Wait for the beforeUnload handlers to complete.
+ await beforeUnloadComplete;
+
+ // _startRemoveTabs doesn't close the last tab in the window
+ // for this use case, we simply close it
+ if (lastToClose) {
+ this.removeTab(lastToClose);
+ }
+ }
+ // If we still have uris, that means we couldn't find them in this window instance
+ return remainingURIsToClose;
+ },
/**
* Handles opening a new tab with mouse middleclick.
@@ -4406,7 +4555,7 @@
} // Do nothing
if (event.button == 1) {
- BrowserOpenTab({ event });
+ BrowserCommands.openTab({ event });
// Stop the propagation of the click event, to prevent the event from being
// handled more than once.
// E.g. see https://bugzilla.mozilla.org/show_bug.cgi?id=1657992#c4
@@ -5719,6 +5868,20 @@
}
},
+ getTabPids(tab) {
+ if (!tab.linkedBrowser) {
+ return [];
+ }
+
+ // Get the PIDs of the content process and remote subframe processes
+ let [contentPid, ...framePids] = E10SUtils.getBrowserPids(
+ tab.linkedBrowser,
+ gFissionBrowser
+ );
+ let pids = contentPid ? [contentPid] : [];
+ return pids.concat(framePids.sort());
+ },
+
getTabTooltip(tab, includeLabel = true) {
let labelArray = [];
if (includeLabel) {
@@ -5730,24 +5893,14 @@
false
)
) {
- if (tab.linkedBrowser) {
- // Show the PIDs of the content process and remote subframe processes.
- let [contentPid, ...framePids] = E10SUtils.getBrowserPids(
- tab.linkedBrowser,
- gFissionBrowser
- );
- if (contentPid) {
- if (framePids && framePids.length) {
- labelArray.push(
- `(pids ${contentPid}, ${framePids.sort().join(", ")})`
- );
- } else {
- labelArray.push(`(pid ${contentPid})`);
- }
- }
- if (tab.linkedBrowser.docShellIsActive) {
- labelArray.push("[A]");
- }
+ const pids = this.getTabPids(tab);
+ if (pids.length) {
+ let pidLabel = pids.length > 1 ? "pids" : "pid";
+ labelArray.push(`(${pidLabel} ${pids.join(", ")})`);
+ }
+
+ if (tab.linkedBrowser.docShellIsActive) {
+ labelArray.push("[A]");
}
}
@@ -5810,6 +5963,13 @@
tooltip.label = "";
document.l10n.setAttributes(tooltip, l10nId, l10nArgs);
} else {
+ // Prevent the tooltip from appearing if card preview is enabled, but
+ // only if the user is not hovering over the media play icon or the
+ // close button
+ if (this._showTabCardPreview) {
+ event.preventDefault();
+ return;
+ }
tooltip.label = this.getTabTooltip(tab, true);
}
},
@@ -5849,7 +6009,7 @@
}
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
switch (aTopic) {
case "contextual-identity-updated": {
let identity = aSubject.wrappedJSObject;
@@ -6105,12 +6265,7 @@
);
if (permission != Services.perms.ALLOW_ACTION) {
// Tell the prompt box we want to show the user a checkbox:
- let tabPrompt = Services.prefs.getBoolPref(
- "prompts.contentPromptSubDialog"
- )
- ? this.getTabDialogBox(tabForEvent.linkedBrowser)
- : this.getTabModalPromptBox(tabForEvent.linkedBrowser);
-
+ let tabPrompt = this.getTabDialogBox(tabForEvent.linkedBrowser);
tabPrompt.onNextPromptShowAllowFocusCheckboxFor(
promptPrincipal
);
@@ -6352,7 +6507,7 @@
let oldUserTypedValue = browser.userTypedValue;
let hadStartedLoad = browser.didStartLoadSinceLastUserTyping();
- let didChange = didChangeEvent => {
+ let didChange = () => {
browser.userTypedValue = oldUserTypedValue;
if (hadStartedLoad) {
browser.urlbarChangeTracker.startedLoad();
@@ -7461,7 +7616,7 @@ var TabBarVisibility = {
toolbar.collapsed = collapse;
let navbar = document.getElementById("nav-bar");
- navbar.setAttribute("tabs-hidden", collapse);
+ navbar.toggleAttribute("tabs-hidden", collapse);
document.getElementById("menu_closeWindow").hidden = collapse;
document.l10n.setAttributes(
@@ -7593,9 +7748,8 @@ var TabContextMenu = {
tabsToMove[0] == visibleTabs[gBrowser._numPinnedTabs];
contextMoveTabToStart.disabled = isFirstTab && allSelectedTabsAdjacent;
- if (this.contextTab.hasAttribute("customizemode")) {
- document.getElementById("context_openTabInWindow").disabled = true;
- }
+ document.getElementById("context_openTabInWindow").disabled =
+ this.contextTab.hasAttribute("customizemode");
// Only one of "Duplicate Tab"/"Duplicate Tabs" should be visible.
document.getElementById("context_duplicateTab").hidden =
@@ -7629,6 +7783,17 @@ var TabContextMenu = {
.getElementById("context_closeTab")
.setAttribute("data-l10n-args", tabCountInfo);
+ let closeDuplicateEnabled = Services.prefs.getBoolPref(
+ "browser.tabs.context.close-duplicate.enabled"
+ );
+ let closeDuplicateTabsItem = document.getElementById(
+ "context_closeDuplicateTabs"
+ );
+ closeDuplicateTabsItem.hidden = !closeDuplicateEnabled;
+ closeDuplicateTabsItem.disabled =
+ !closeDuplicateEnabled ||
+ !gBrowser.getDuplicateTabsToClose(this.contextTab).length;
+
// Disable "Close Multiple Tabs" if all sub menuitems are disabled
document.getElementById("context_closeTabOptions").disabled =
closeTabsToTheStartItem.disabled &&
@@ -7785,7 +7950,7 @@ var TabContextMenu = {
}
},
- closeContextTabs(event) {
+ closeContextTabs() {
if (this.contextTab.multiselected) {
gBrowser.removeMultiSelectedTabs();
} else {
diff --git a/browser/base/content/test/about/browser.toml b/browser/base/content/test/about/browser.toml
index 98961200a0..2c6dafb4dd 100644
--- a/browser/base/content/test/about/browser.toml
+++ b/browser/base/content/test/about/browser.toml
@@ -66,7 +66,6 @@ support-files = [
["browser_aboutNewTab_bookmarksToolbar.js"]
["browser_aboutNewTab_bookmarksToolbarEmpty.js"]
-fail-if = ["a11y_checks"] # Bug 1854233 text-link may not be focusable
skip-if = ["tsan"] # Bug 1676326, highly frequent on TSan
["browser_aboutNewTab_bookmarksToolbarNewWindow.js"]
diff --git a/browser/base/content/test/about/browser_aboutCertError.js b/browser/base/content/test/about/browser_aboutCertError.js
index 9af82b807f..5939b026bd 100644
--- a/browser/base/content/test/about/browser_aboutCertError.js
+++ b/browser/base/content/test/about/browser_aboutCertError.js
@@ -121,7 +121,7 @@ add_task(async function checkReturnToPreviousPage() {
"pageshow",
true
);
- await SpecialPowers.spawn(bc, [useFrame], async function (subFrame) {
+ await SpecialPowers.spawn(bc, [useFrame], async function () {
let returnButton = content.document.getElementById("returnButton");
returnButton.click();
});
@@ -544,7 +544,7 @@ add_task(async function checkViewSource() {
certOverrideService.clearValidityOverride("expired.example.com", -1, {});
loaded = BrowserTestUtils.waitForErrorPage(browser);
- BrowserReloadSkipCache();
+ BrowserCommands.reloadSkipCache();
await loaded;
BrowserTestUtils.removeTab(gBrowser.selectedTab);
diff --git a/browser/base/content/test/about/browser_aboutNetError_csp_iframe.js b/browser/base/content/test/about/browser_aboutNetError_csp_iframe.js
index c8028a4cf4..d245d0cd3c 100644
--- a/browser/base/content/test/about/browser_aboutNetError_csp_iframe.js
+++ b/browser/base/content/test/about/browser_aboutNetError_csp_iframe.js
@@ -8,6 +8,10 @@ const BLOCKED_PAGE =
"http://example.org:8000/browser/browser/base/content/test/about/csp_iframe.sjs";
add_task(async function test_csp() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["security.xfocsp.hideOpenInNewWindow", false]],
+ });
+
let { iframePageTab, blockedPageTab } = await setupPage(
"iframe_page_csp.html",
BLOCKED_PAGE
diff --git a/browser/base/content/test/about/browser_aboutNetError_xfo_iframe.js b/browser/base/content/test/about/browser_aboutNetError_xfo_iframe.js
index f5fd240643..2373bd8b50 100644
--- a/browser/base/content/test/about/browser_aboutNetError_xfo_iframe.js
+++ b/browser/base/content/test/about/browser_aboutNetError_xfo_iframe.js
@@ -8,6 +8,10 @@ const BLOCKED_PAGE =
"http://example.org:8000/browser/browser/base/content/test/about/xfo_iframe.sjs";
add_task(async function test_xfo_iframe() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["security.xfocsp.hideOpenInNewWindow", false]],
+ });
+
let { iframePageTab, blockedPageTab } = await setupPage(
"iframe_page_xfo.html",
BLOCKED_PAGE
diff --git a/browser/base/content/test/alerts/browser.toml b/browser/base/content/test/alerts/browser.toml
index d0d56f7392..aaca2ba7dc 100644
--- a/browser/base/content/test/alerts/browser.toml
+++ b/browser/base/content/test/alerts/browser.toml
@@ -19,10 +19,6 @@ skip-if = ["os == 'win'"] # Bug 1411118
https_first_disabled = true
skip-if = ["os == 'win'"] # Bug 1411118
-["browser_notification_replace.js"]
-https_first_disabled = true
-skip-if = ["os == 'win'"] # Bug 1422928
-
["browser_notification_tab_switching.js"]
https_first_disabled = true
skip-if = ["os == 'win'"] # Bug 1243263
diff --git a/browser/base/content/test/alerts/browser_notification_close.js b/browser/base/content/test/alerts/browser_notification_close.js
index 7568f1cc2d..3fd50bed5b 100644
--- a/browser/base/content/test/alerts/browser_notification_close.js
+++ b/browser/base/content/test/alerts/browser_notification_close.js
@@ -21,17 +21,16 @@ add_task(async function test_notificationClose() {
Services.prefs.setBoolPref("alerts.showFavicons", true);
await PlacesTestUtils.addVisits(notificationURI);
- let faviconURI = await new Promise(resolve => {
- let uri = makeURI(
- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC"
- );
- PlacesUtils.favicons.setAndFetchFaviconForPage(
+ let dataURL = makeURI(
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC"
+ );
+ await new Promise(resolve => {
+ PlacesUtils.favicons.setFaviconForPage(
notificationURI,
- uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- uriResult => resolve(uriResult),
- Services.scriptSecurityManager.getSystemPrincipal()
+ dataURL,
+ dataURL,
+ null,
+ resolve
);
});
@@ -67,11 +66,7 @@ add_task(async function test_notificationClose() {
"Body text of notification should be present"
);
let alertIcon = alertWindow.document.getElementById("alertIcon");
- is(
- alertIcon.src,
- faviconURI.spec,
- "Icon of notification should be present"
- );
+ is(alertIcon.src, dataURL.spec, "Icon of notification should be present");
let alertCloseButton = alertWindow.document.querySelector(".close-icon");
is(alertCloseButton.localName, "toolbarbutton", "close button found");
diff --git a/browser/base/content/test/alerts/browser_notification_open_settings.js b/browser/base/content/test/alerts/browser_notification_open_settings.js
index ed51cd782b..e7f1c28251 100644
--- a/browser/base/content/test/alerts/browser_notification_open_settings.js
+++ b/browser/base/content/test/alerts/browser_notification_open_settings.js
@@ -14,7 +14,7 @@ add_task(async function test_settingsOpen_observer() {
gBrowser,
url: "about:robots",
},
- async function dummyTabTask(aBrowser) {
+ async function dummyTabTask() {
// Ensure preferences is loaded before removing the tab.
let syncPaneLoadedPromise = TestUtils.topicObserved(
"sync-pane-loaded",
diff --git a/browser/base/content/test/alerts/browser_notification_replace.js b/browser/base/content/test/alerts/browser_notification_replace.js
deleted file mode 100644
index 9c72e90ab1..0000000000
--- a/browser/base/content/test/alerts/browser_notification_replace.js
+++ /dev/null
@@ -1,66 +0,0 @@
-"use strict";
-
-let notificationURL =
- // eslint-disable-next-line @microsoft/sdl/no-insecure-url
- "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
-
-add_task(async function test_notificationReplace() {
- await addNotificationPermission(notificationURL);
-
- await BrowserTestUtils.withNewTab(
- {
- gBrowser,
- url: notificationURL,
- },
- async function dummyTabTask(aBrowser) {
- await SpecialPowers.spawn(aBrowser, [], async function () {
- let win = content.window.wrappedJSObject;
- let notification = win.showNotification1();
- let promiseCloseEvent = ContentTaskUtils.waitForEvent(
- notification,
- "close"
- );
-
- let showEvent = await ContentTaskUtils.waitForEvent(
- notification,
- "show"
- );
- Assert.equal(
- showEvent.target.body,
- "Test body 1",
- "Showed tagged notification"
- );
-
- let newNotification = win.showNotification2();
- let newShowEvent = await ContentTaskUtils.waitForEvent(
- newNotification,
- "show"
- );
- Assert.equal(
- newShowEvent.target.body,
- "Test body 2",
- "Showed new notification with same tag"
- );
-
- let closeEvent = await promiseCloseEvent;
- Assert.equal(
- closeEvent.target.body,
- "Test body 1",
- "Closed previous tagged notification"
- );
-
- let promiseNewCloseEvent = ContentTaskUtils.waitForEvent(
- newNotification,
- "close"
- );
- newNotification.close();
- let newCloseEvent = await promiseNewCloseEvent;
- Assert.equal(
- newCloseEvent.target.body,
- "Test body 2",
- "Closed new notification"
- );
- });
- }
- );
-});
diff --git a/browser/base/content/test/alerts/head.js b/browser/base/content/test/alerts/head.js
index 4be18f6c41..eaf3a2bb74 100644
--- a/browser/base/content/test/alerts/head.js
+++ b/browser/base/content/test/alerts/head.js
@@ -20,7 +20,7 @@ async function addNotificationPermission(originString) {
*/
function promiseWindowClosed(window) {
return new Promise(function (resolve) {
- Services.ww.registerNotification(function observer(subject, topic, data) {
+ Services.ww.registerNotification(function observer(subject, topic) {
if (topic == "domwindowclosed" && subject == window) {
Services.ww.unregisterNotification(observer);
resolve();
diff --git a/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js b/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
index 6389338a6f..b65a419884 100644
--- a/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
+++ b/browser/base/content/test/captivePortal/browser_captivePortal_certErrorUI.js
@@ -117,7 +117,7 @@ add_task(async function testCaptivePortalAdvancedPanel() {
await BrowserTestUtils.waitForLocationChange(gBrowser, BAD_CERT_PAGE);
info("(waitForLocationChange resolved)");
})();
- await SpecialPowers.spawn(browser, [BAD_CERT_PAGE], async expectedURL => {
+ await SpecialPowers.spawn(browser, [BAD_CERT_PAGE], async () => {
const doc = content.document;
let advancedButton = doc.getElementById("advancedButton");
await ContentTaskUtils.waitForCondition(
diff --git a/browser/base/content/test/contextMenu/browser.toml b/browser/base/content/test/contextMenu/browser.toml
index 3eb6a1d606..c7af1bc437 100644
--- a/browser/base/content/test/contextMenu/browser.toml
+++ b/browser/base/content/test/contextMenu/browser.toml
@@ -8,7 +8,6 @@ support-files = [
"subtst_contextmenu_xul.xhtml",
"ctxmenu-image.png",
"../general/head.js",
- "../general/video.ogg",
"../general/audio.ogg",
"../../../../../toolkit/components/pdfjs/test/file_pdfjs_test.pdf",
"contextmenu_common.js",
@@ -19,6 +18,7 @@ support-files = [
["browser_bug1798178.js"]
["browser_contextmenu.js"]
+support-files = [ "../general/video.webm" ]
tags = "fullscreen"
skip-if = [
"os == 'linux'",
@@ -86,6 +86,8 @@ skip-if = ["os == 'linux' && socketprocess_networking"]
["browser_strip_on_share_link.js"]
+["browser_strip_on_share_nested_link.js"]
+
["browser_utilityOverlay.js"]
https_first_disabled = true
skip-if = ["os == 'linux' && socketprocess_networking"]
@@ -99,3 +101,5 @@ support-files = [
"test_view_image_inline_svg.html",
]
skip-if = ["os == 'linux' && socketprocess_networking"]
+
+["browser_contextmenu_cross_boundary_selection.js"]
diff --git a/browser/base/content/test/contextMenu/browser_contextmenu.js b/browser/base/content/test/contextMenu/browser_contextmenu.js
index ebeb4bdb04..d8dc0ab5e0 100644
--- a/browser/base/content/test/contextMenu/browser_contextmenu.js
+++ b/browser/base/content/test/contextMenu/browser_contextmenu.js
@@ -41,6 +41,10 @@ let hasContainers =
Services.prefs.getBoolPref("privacy.userContext.enabled") &&
ContextualIdentityService.getPublicIdentities().length;
+const hasSelectTranslations =
+ Services.prefs.getBoolPref("browser.translations.enable") &&
+ Services.prefs.getBoolPref("browser.translations.select.enable");
+
const example_base =
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
"http://example.com/browser/browser/base/content/test/contextMenu/";
@@ -112,6 +116,7 @@ add_task(async function test_xul_text_link_label() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
// Clean up so won't affect HTML element test cases.
@@ -137,7 +142,7 @@ add_task(async function test_setup_html() {
audio.loop = true;
audio.src = "audio.ogg";
video.loop = true;
- video.src = "video.ogg";
+ video.src = "video.webm";
let awaitPause = ContentTaskUtils.waitForEvent(audio, "pause");
await ContentTaskUtils.waitForCondition(
@@ -204,6 +209,7 @@ const kLinkItems = [
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
];
add_task(async function test_link() {
@@ -234,6 +240,7 @@ add_task(async function test_mailto() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
});
@@ -247,6 +254,7 @@ add_task(async function test_tel() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
});
@@ -273,6 +281,10 @@ add_task(async function test_image() {
null,
"context-setDesktopBackground",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
],
{
onContextMenuShown() {
@@ -356,6 +368,10 @@ add_task(async function test_video_ok() {
true,
"context-sendvideo",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -404,6 +420,10 @@ add_task(async function test_video_ok() {
true,
"context-sendvideo",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -490,6 +510,10 @@ add_task(async function test_video_bad() {
true,
"context-sendvideo",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -538,6 +562,10 @@ add_task(async function test_video_bad() {
true,
"context-sendvideo",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -588,6 +616,10 @@ add_task(async function test_video_bad2() {
false,
"context-sendvideo",
false,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -636,6 +668,10 @@ add_task(async function test_video_bad2() {
false,
"context-sendvideo",
false,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
await SpecialPowers.popPrefEnv();
@@ -767,6 +803,10 @@ add_task(async function test_video_in_iframe() {
true,
"---",
null,
+ "context-take-frame-screenshot",
+ true,
+ "---",
+ null,
"context-viewframeinfo",
true,
]),
@@ -846,6 +886,10 @@ add_task(async function test_video_in_iframe() {
true,
"---",
null,
+ "context-take-frame-screenshot",
+ true,
+ "---",
+ null,
"context-viewframeinfo",
true,
]),
@@ -967,6 +1011,10 @@ add_task(async function test_image_in_iframe() {
true,
"---",
null,
+ "context-take-frame-screenshot",
+ true,
+ "---",
+ null,
"context-viewframeinfo",
true,
]),
@@ -1336,6 +1384,7 @@ add_task(async function test_select_text() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
"---",
null,
"context-viewpartialsource-selection",
@@ -1369,6 +1418,9 @@ add_task(async function test_select_text_search_service_not_initialized() {
null,
"context-take-screenshot",
true,
+ ...(hasSelectTranslations
+ ? ["---", null, "context-translate-selection", true]
+ : []),
"---",
null,
"context-viewpartialsource-selection",
@@ -1423,6 +1475,7 @@ add_task(async function test_select_text_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
"---",
null,
"context-viewpartialsource-selection",
@@ -1490,6 +1543,9 @@ add_task(async function test_imagelink() {
null,
"context-setDesktopBackground",
true,
+ ...(hasSelectTranslations
+ ? ["---", null, "context-translate-selection", true]
+ : []),
]);
});
@@ -1591,6 +1647,10 @@ add_task(async function test_longdesc() {
null,
"context-setDesktopBackground",
true,
+ "---",
+ null,
+ "context-take-screenshot",
+ true,
]);
});
@@ -1682,6 +1742,7 @@ add_task(async function test_svg_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
await test_contextmenu("#svg-with-link2 > a", [
@@ -1711,6 +1772,7 @@ add_task(async function test_svg_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
await test_contextmenu("#svg-with-link3 > a", [
@@ -1740,6 +1802,7 @@ add_task(async function test_svg_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
});
@@ -1771,6 +1834,7 @@ add_task(async function test_svg_relative_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
await test_contextmenu("#svg-with-relative-link2 > a", [
@@ -1800,6 +1864,7 @@ add_task(async function test_svg_relative_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
await test_contextmenu("#svg-with-relative-link3 > a", [
@@ -1829,6 +1894,7 @@ add_task(async function test_svg_relative_link() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
});
@@ -1898,6 +1964,7 @@ add_task(async function test_background_image() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
// Don't show image related context menu commands when there is a selection
@@ -1921,6 +1988,7 @@ add_task(async function test_background_image() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
"---",
null,
"context-viewpartialsource-selection",
@@ -1989,6 +2057,7 @@ add_task(async function test_strip_on_share_on_secure_about_page() {
true,
"context-searchselect-private",
true,
+ ...(hasSelectTranslations ? ["context-translate-selection", true] : []),
]);
// Clean up
diff --git a/browser/base/content/test/contextMenu/browser_contextmenu_badiframe.js b/browser/base/content/test/contextMenu/browser_contextmenu_badiframe.js
index 991a55af70..57d9808f5d 100644
--- a/browser/base/content/test/contextMenu/browser_contextmenu_badiframe.js
+++ b/browser/base/content/test/contextMenu/browser_contextmenu_badiframe.js
@@ -30,7 +30,7 @@ async function openTestPage() {
let pageAndIframesLoaded = BrowserTestUtils.browserLoaded(
browser,
true /* includeSubFrames */,
- url => {
+ () => {
expectedLoads--;
return !expectedLoads;
},
diff --git a/browser/base/content/test/contextMenu/browser_contextmenu_cross_boundary_selection.js b/browser/base/content/test/contextMenu/browser_contextmenu_cross_boundary_selection.js
new file mode 100644
index 0000000000..3137a1e136
--- /dev/null
+++ b/browser/base/content/test/contextMenu/browser_contextmenu_cross_boundary_selection.js
@@ -0,0 +1,73 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const PAGE = `
+ data:text/html,
+ <div>OuterText<div>
+ <div id="host">
+ <template shadowrootmode="open">
+ <span id="innerText">InnerText</span>
+ </template>
+ </div>
+ `;
+/**
+ * Tests that right click on a cross boundary selection shows the context menu
+ */
+add_task(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.shadowdom.selection_across_boundary.enabled", true]],
+ });
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: PAGE,
+ },
+ async function (browser) {
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ let awaitPopupShown = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popupshown"
+ );
+
+ let awaitPopupHidden = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popuphidden"
+ );
+
+ await SpecialPowers.spawn(browser, [], () => {
+ let host = content.document.getElementById("host");
+ content.getSelection().setBaseAndExtent(
+ content.document.body,
+ 0,
+ host.shadowRoot.getElementById("innerText").firstChild,
+ 3 // Only select the first three characters of the inner text
+ );
+ });
+
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "div", // Click on the div for OuterText
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ browser
+ );
+
+ await awaitPopupShown;
+
+ const allVisibleMenuItems = Array.from(contextMenu.children)
+ .filter(elem => {
+ return !elem.hidden;
+ })
+ .map(elem => elem.id);
+
+ ok(
+ allVisibleMenuItems.includes("context-copy"),
+ "copy button should exist"
+ );
+
+ contextMenu.hidePopup();
+ await awaitPopupHidden;
+ }
+ );
+});
diff --git a/browser/base/content/test/contextMenu/browser_contextmenu_save_blocked.js b/browser/base/content/test/contextMenu/browser_contextmenu_save_blocked.js
index 062fbeac08..7e6b71e8e4 100644
--- a/browser/base/content/test/contextMenu/browser_contextmenu_save_blocked.js
+++ b/browser/base/content/test/contextMenu/browser_contextmenu_save_blocked.js
@@ -64,7 +64,7 @@ add_task(async function test_save_link_blocked_by_extension() {
setTimeout(resolve, 0);
};
- MockFilePicker.showCallback = function (fp) {
+ MockFilePicker.showCallback = function () {
ok(false, "filepicker should never been shown");
setTimeout(resolve, 0);
return Ci.nsIFilePicker.returnCancel;
diff --git a/browser/base/content/test/contextMenu/browser_strip_on_share_link.js b/browser/base/content/test/contextMenu/browser_strip_on_share_link.js
index 435b1aa0ff..144076cfb2 100644
--- a/browser/base/content/test/contextMenu/browser_strip_on_share_link.js
+++ b/browser/base/content/test/contextMenu/browser_strip_on_share_link.js
@@ -97,6 +97,18 @@ add_task(async function testQueryParamIsNotStrippedForWrongSiteSpecific() {
});
});
+// Ensuring clean copy works with magnet links. We don't strip anything but copying the original URI should still work.
+add_task(async function testMagneticLinks() {
+ let originalUrl = "magnet:?xt=urn:btih:somesha1hash";
+ let shortenedUrl = "magnet:?xt=urn:btih:somesha1hash";
+ await testStripOnShare({
+ selectWholeUrl: true,
+ validUrl: originalUrl,
+ strippedUrl: shortenedUrl,
+ useTestList: true,
+ });
+});
+
/**
* Opens a new tab, opens the context menu and checks that the strip-on-share menu item is visible.
* Checks that the stripped version of the url is copied to the clipboard.
diff --git a/browser/base/content/test/contextMenu/browser_strip_on_share_nested_link.js b/browser/base/content/test/contextMenu/browser_strip_on_share_nested_link.js
new file mode 100644
index 0000000000..d11649e648
--- /dev/null
+++ b/browser/base/content/test/contextMenu/browser_strip_on_share_nested_link.js
@@ -0,0 +1,162 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let listService;
+
+const TEST_URL =
+ "https://example.com/browser/browser/base/content/test/general/dummy_page.html";
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [["privacy.query_stripping.strip_list", "stripParam"]],
+ });
+
+ // Get the list service so we can wait for it to be fully initialized before running tests.
+ listService = Cc["@mozilla.org/query-stripping-list-service;1"].getService(
+ Ci.nsIURLQueryStrippingListService
+ );
+
+ await listService.testWaitForInit();
+});
+
+/*
+Tests the strip-on-share feature for in-content links with nested urls
+*/
+
+// Testing nested stripping with global params
+add_task(async function testNestedStrippingGlobalParam() {
+ let validUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.net%2F%3Futm_ad%3D1234";
+ let shortenedUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.net%2F";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+// Testing nested stripping with site specific params
+add_task(async function testNestedStrippingSiteSpecific() {
+ let validUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.net%2F%3Ftest_3%3D1234";
+ let shortenedUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.net%2F";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+// Testing nested stripping with incorrect site specific params
+add_task(async function testNoStrippedNestedParam() {
+ let validUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.com%2F%3Ftest_3%3D1234";
+ let shortenedUrl =
+ "https://www.example.com/?test=https%3A%2F%2Fwww.example.com%2F%3Ftest_3%3D1234";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+// Testing order of stripping for nested stripping
+add_task(async function testOrderOfStripping() {
+ let validUrl =
+ "https://www.example.com/?test_1=https%3A%2F%2Fwww.example.net%2F%3Ftest_3%3D1234";
+ let shortenedUrl = "https://www.example.com/";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+// Testing correct scoping of site specific params for nested stripping
+add_task(async function testMultipleQueryParamsWithNestedStripping() {
+ let validUrl =
+ "https://www.example.com/?test_3=1234&test=https%3A%2F%2Fwww.example.net%2F%3Ftest_3%3D1234";
+ let shortenedUrl =
+ "https://www.example.com/?test_3=1234&test=https%3A%2F%2Fwww.example.net%2F";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+// Testing functionality with no https pages
+add_task(async function testNonHTTPsPages() {
+ let validUrl = "https://www.example.com/?test_2=1234&test=about%3A%3Aconfig";
+ let shortenedUrl = "https://www.example.com/?test=about%3A%3Aconfig";
+ await testStripOnShare({
+ originalURI: validUrl,
+ strippedURI: shortenedUrl,
+ });
+});
+
+/**
+ * Opens a new tab, opens the context menu and checks that the strip-on-share menu item is visible.
+ * Checks that the stripped version of the url is copied to the clipboard.
+ *
+ * @param {string} originalURI - The orginal url before the stripping occurs
+ * @param {string} strippedURI - The expected url after stripping occurs
+ */
+async function testStripOnShare({ originalURI, strippedURI }) {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.query_stripping.strip_on_share.enabled", true],
+ ["privacy.query_stripping.strip_on_share.enableTestMode", true],
+ ],
+ });
+
+ let testJson = {
+ global: {
+ queryParams: ["utm_ad"],
+ topLevelSites: ["*"],
+ },
+ example: {
+ queryParams: ["test_2", "test_1"],
+ topLevelSites: ["www.example.com"],
+ },
+ exampleNet: {
+ queryParams: ["test_3", "test_4"],
+ topLevelSites: ["www.example.net"],
+ },
+ };
+
+ await listService.testSetList(testJson);
+
+ await BrowserTestUtils.withNewTab(TEST_URL, async function (browser) {
+ // Prepare a link
+ await SpecialPowers.spawn(browser, [originalURI], function (startingURI) {
+ let link = content.document.createElement("a");
+ link.href = startingURI;
+ link.textContent = "link with query param";
+ link.id = "link";
+ content.document.body.appendChild(link);
+ });
+ let contextMenu = document.getElementById("contentAreaContextMenu");
+ // Open the context menu
+ let awaitPopupShown = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popupshown"
+ );
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#link",
+ { type: "contextmenu", button: 2 },
+ browser
+ );
+ await awaitPopupShown;
+ let awaitPopupHidden = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popuphidden"
+ );
+ let stripOnShare = contextMenu.querySelector("#context-stripOnShareLink");
+ Assert.ok(BrowserTestUtils.isVisible(stripOnShare), "Menu item is visible");
+ // Make sure the stripped link will be copied to the clipboard
+ await SimpleTest.promiseClipboardChange(strippedURI, () => {
+ contextMenu.activateItem(stripOnShare);
+ });
+ await awaitPopupHidden;
+ });
+}
diff --git a/browser/base/content/test/contextMenu/contextmenu_common.js b/browser/base/content/test/contextMenu/contextmenu_common.js
index ac61aa2a3a..2c9a1967f6 100644
--- a/browser/base/content/test/contextMenu/contextmenu_common.js
+++ b/browser/base/content/test/contextMenu/contextmenu_common.js
@@ -39,7 +39,7 @@ function closeContextMenu() {
contextMenu.hidePopup();
}
-function getVisibleMenuItems(aMenu, aData) {
+function getVisibleMenuItems(aMenu) {
var items = [];
var accessKeys = {};
for (var i = 0; i < aMenu.children.length; i++) {
@@ -65,7 +65,7 @@ function getVisibleMenuItems(aMenu, aData) {
var label = item.getAttribute("label");
ok(label.length, "menuitem " + item.id + " has a label");
if (isGenerated) {
- is(key, "", "Generated items shouldn't have an access key");
+ is(key, null, "Generated items shouldn't have an access key");
items.push("*" + label);
} else if (
item.id.indexOf("spell-check-dictionary-") != 0 &&
diff --git a/browser/base/content/test/contextMenu/subtst_contextmenu.html b/browser/base/content/test/contextMenu/subtst_contextmenu.html
index 2c263fbce4..2facd9fecc 100644
--- a/browser/base/content/test/contextMenu/subtst_contextmenu.html
+++ b/browser/base/content/test/contextMenu/subtst_contextmenu.html
@@ -26,14 +26,14 @@ document.getElementById("shadow-host-in-link").attachShadow({ mode: "closed" }).
<image id="test-svg-image" href="ctxmenu-image.png"/>
</svg>
<canvas id="test-canvas" width="100" height="100" style="background-color: blue"></canvas>
-<video controls id="test-video-ok" src="video.ogg" width="100" height="100" style="background-color: green"></video>
+<video controls id="test-video-ok" src="video.webm" width="100" height="100" style="background-color: green"></video>
<video id="test-audio-in-video" src="audio.ogg" width="100" height="100" style="background-color: red"></video>
<video controls id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
<video controls id="test-video-bad2" width="100" height="100" style="background-color: yellow">
<source src="bogus.duh" type="video/durrrr;">
</video>
<iframe id="test-iframe" width="98" height="98" style="border: 1px solid black"></iframe>
-<iframe id="test-video-in-iframe" src="video.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
+<iframe id="test-video-in-iframe" src="video.webm" width="98" height="98" style="border: 1px solid black"></iframe>
<iframe id="test-audio-in-iframe" src="audio.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
<iframe id="test-image-in-iframe" src="ctxmenu-image.png" width="98" height="98" style="border: 1px solid black"></iframe>
<iframe id="test-pdf-viewer-in-frame" src="file_pdfjs_test.pdf" width="100" height="100" style="border: 1px solid black"></iframe>
diff --git a/browser/base/content/test/contextMenu/subtst_contextmenu_webext.html b/browser/base/content/test/contextMenu/subtst_contextmenu_webext.html
index ac3b5415dd..be45c2ddd0 100644
--- a/browser/base/content/test/contextMenu/subtst_contextmenu_webext.html
+++ b/browser/base/content/test/contextMenu/subtst_contextmenu_webext.html
@@ -7,6 +7,6 @@
<body>
Browser context menu subtest.
<a href="moz-extension://foo-bar/tab.html" id="link">Link to an extension resource</a>
- <video src="moz-extension://foo-bar/video.ogg" id="video"></video>
+ <video src="moz-extension://foo-bar/video.webm" id="video"></video>
</body>
</html>
diff --git a/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js b/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js
index b8215dcc3e..85240aaa95 100644
--- a/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js
+++ b/browser/base/content/test/favicons/browser_favicon_change_not_in_document.js
@@ -36,8 +36,8 @@ add_task(async function () {
));
let domLinkAddedFired = 0;
let domLinkChangedFired = 0;
- const linkAddedHandler = event => domLinkAddedFired++;
- const linkChangedhandler = event => domLinkChangedFired++;
+ const linkAddedHandler = () => domLinkAddedFired++;
+ const linkChangedhandler = () => domLinkChangedFired++;
BrowserTestUtils.addContentEventListener(
gBrowser.selectedBrowser,
"DOMLinkAdded",
@@ -80,8 +80,8 @@ add_task(async function () {
let domLinkAddedFired = 0;
let domLinkChangedFired = 0;
- const linkAddedHandler = event => domLinkAddedFired++;
- const linkChangedhandler = event => domLinkChangedFired++;
+ const linkAddedHandler = () => domLinkAddedFired++;
+ const linkChangedhandler = () => domLinkChangedFired++;
BrowserTestUtils.addContentEventListener(
browser,
"DOMLinkAdded",
diff --git a/browser/base/content/test/favicons/browser_favicon_load.js b/browser/base/content/test/favicons/browser_favicon_load.js
index 10c2b8f24e..7b78ae494f 100644
--- a/browser/base/content/test/favicons/browser_favicon_load.js
+++ b/browser/base/content/test/favicons/browser_favicon_load.js
@@ -50,7 +50,7 @@ function FaviconObserver(aPageURI, aFaviconURL, aTailingEnabled) {
}
FaviconObserver.prototype = {
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
// Make sure that the topic is 'http-on-modify-request'.
if (aTopic === "http-on-modify-request") {
let httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
diff --git a/browser/base/content/test/favicons/browser_favicon_nostore.js b/browser/base/content/test/favicons/browser_favicon_nostore.js
index 3fec666bbe..c12c7a87cd 100644
--- a/browser/base/content/test/favicons/browser_favicon_nostore.js
+++ b/browser/base/content/test/favicons/browser_favicon_nostore.js
@@ -140,20 +140,17 @@ add_task(async function root_icon_stored() {
response.write("<html>A page without icon</html>");
});
- let noStorePromise = TestUtils.topicObserved(
- "http-on-stop-request",
- (s, t, d) => {
- let chan = s.QueryInterface(Ci.nsIHttpChannel);
- return chan?.URI.spec == "http://www.nostore.com/favicon.ico";
- }
- ).then(([chan]) => chan.isNoStoreResponse());
+ let noStorePromise = TestUtils.topicObserved("http-on-stop-request", s => {
+ let chan = s.QueryInterface(Ci.nsIHttpChannel);
+ return chan?.URI.spec == "http://www.nostore.com/favicon.ico";
+ }).then(([chan]) => chan.isNoStoreResponse());
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: "http://www.nostore.com/page",
},
- async function (browser) {
+ async function () {
await TestUtils.waitForCondition(async () => {
let uri = await new Promise(resolve =>
PlacesUtils.favicons.getFaviconURLForPage(
diff --git a/browser/base/content/test/favicons/browser_favicon_referer.js b/browser/base/content/test/favicons/browser_favicon_referer.js
index ed332e7413..9fee9771b0 100644
--- a/browser/base/content/test/favicons/browser_favicon_referer.js
+++ b/browser/base/content/test/favicons/browser_favicon_referer.js
@@ -14,7 +14,7 @@ add_task(async function test_check_referrer_for_discovered_favicon() {
async browser => {
let referrerPromise = TestUtils.topicObserved(
"http-on-modify-request",
- (s, t, d) => {
+ s => {
let chan = s.QueryInterface(Ci.nsIHttpChannel);
return chan.URI.spec == "http://mochi.test:8888/favicon.ico";
}
@@ -42,7 +42,7 @@ add_task(
async browser => {
let referrerPromise = TestUtils.topicObserved(
"http-on-modify-request",
- (s, t, d) => {
+ s => {
let chan = s.QueryInterface(Ci.nsIHttpChannel);
return chan.URI.spec == `${FOLDER}file_favicon.png`;
}
diff --git a/browser/base/content/test/favicons/browser_missing_favicon.js b/browser/base/content/test/favicons/browser_missing_favicon.js
index f619425909..fd60d362b4 100644
--- a/browser/base/content/test/favicons/browser_missing_favicon.js
+++ b/browser/base/content/test/favicons/browser_missing_favicon.js
@@ -28,7 +28,7 @@ add_task(async () => {
is(browser.mIconURL, null, "Should have blanked the icon.");
is(
gBrowser.getTabForBrowser(browser).getAttribute("image"),
- "",
+ null,
"Should have blanked the tab icon."
);
}
diff --git a/browser/base/content/test/forms/browser.toml b/browser/base/content/test/forms/browser.toml
index 95b666369e..c7cabfa1b0 100644
--- a/browser/base/content/test/forms/browser.toml
+++ b/browser/base/content/test/forms/browser.toml
@@ -14,6 +14,8 @@ skip-if = ["os == 'linux'"] # Bug 1329991 - test fails intermittently on Linux b
["browser_selectpopup_dir.js"]
+["browser_selectpopup_focus.js"]
+
["browser_selectpopup_hr.js"]
["browser_selectpopup_large.js"]
diff --git a/browser/base/content/test/forms/browser_selectpopup.js b/browser/base/content/test/forms/browser_selectpopup.js
index abcdee486f..72112974c2 100644
--- a/browser/base/content/test/forms/browser_selectpopup.js
+++ b/browser/base/content/test/forms/browser_selectpopup.js
@@ -186,7 +186,7 @@ async function doSelectTests(contentType, content) {
);
// Backspace should not go back
- let handleKeyPress = function (event) {
+ let handleKeyPress = function () {
ok(false, "Should not get keypress event");
};
window.addEventListener("keypress", handleKeyPress);
@@ -708,7 +708,7 @@ add_task(async function test_mousemove_correcttarget() {
window,
"sizemodechange"
);
- BrowserFullScreen();
+ BrowserCommands.fullScreen();
await sizeModeChanged;
await popupHiddenPromise;
}
diff --git a/browser/base/content/test/forms/browser_selectpopup_colors.js b/browser/base/content/test/forms/browser_selectpopup_colors.js
index 63cece0ce5..f4b3e8a516 100644
--- a/browser/base/content/test/forms/browser_selectpopup_colors.js
+++ b/browser/base/content/test/forms/browser_selectpopup_colors.js
@@ -255,7 +255,7 @@ function rgbaToString(parsedColor) {
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
-function testOptionColors(test, index, item, menulist) {
+function testOptionColors(test, index, item) {
// The label contains a JSON string of the expected colors for
// `color` and `background-color`.
let expected = JSON.parse(item.label);
diff --git a/browser/base/content/test/forms/browser_selectpopup_dir.js b/browser/base/content/test/forms/browser_selectpopup_dir.js
index aaf4a61fc2..a0ad90d909 100644
--- a/browser/base/content/test/forms/browser_selectpopup_dir.js
+++ b/browser/base/content/test/forms/browser_selectpopup_dir.js
@@ -13,7 +13,7 @@ add_task(async function () {
gBrowser,
url,
},
- async function (browser) {
+ async function () {
let popup = await openSelectPopup("click");
is(popup.style.direction, "rtl", "Should be the right dir");
}
diff --git a/browser/base/content/test/forms/browser_selectpopup_focus.js b/browser/base/content/test/forms/browser_selectpopup_focus.js
new file mode 100644
index 0000000000..24ff947c50
--- /dev/null
+++ b/browser/base/content/test/forms/browser_selectpopup_focus.js
@@ -0,0 +1,38 @@
+// Empty select to make sure that we click on the menulist button.
+const PAGE = `
+<!doctype html>
+<select style="padding: 0">
+ <option></option>
+</select>
+`;
+
+function tick() {
+ return new Promise(r =>
+ requestAnimationFrame(() => requestAnimationFrame(r))
+ );
+}
+
+add_task(async function () {
+ const url = "data:text/html," + encodeURI(PAGE);
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url,
+ },
+ async function (browser) {
+ await openSelectPopup("click");
+ await SpecialPowers.spawn(browser, [], () => {
+ is(
+ content.document.activeElement,
+ content.document.querySelector("select"),
+ "Select is the active element"
+ );
+ ok(
+ content.document.querySelector("select").matches(":focus"),
+ "Select matches :focus"
+ );
+ });
+ await hideSelectPopup();
+ }
+ );
+});
diff --git a/browser/base/content/test/forms/browser_selectpopup_large.js b/browser/base/content/test/forms/browser_selectpopup_large.js
index 722e0d9588..40f6d1b160 100644
--- a/browser/base/content/test/forms/browser_selectpopup_large.js
+++ b/browser/base/content/test/forms/browser_selectpopup_large.js
@@ -297,7 +297,7 @@ add_task(async function test_large_popup_in_small_window() {
newWin,
"resize",
false,
- e => {
+ () => {
info(`Got resize event (innerHeight: ${newWin.innerHeight})`);
return newWin.innerHeight <= 450;
}
diff --git a/browser/base/content/test/forms/browser_selectpopup_minFontSize.js b/browser/base/content/test/forms/browser_selectpopup_minFontSize.js
index d240c2d2d0..522ed1ffcf 100644
--- a/browser/base/content/test/forms/browser_selectpopup_minFontSize.js
+++ b/browser/base/content/test/forms/browser_selectpopup_minFontSize.js
@@ -20,7 +20,7 @@ add_task(async function () {
gBrowser,
url,
},
- async function (browser) {
+ async function () {
let popup = await openSelectPopup("click");
let menuitems = popup.querySelectorAll("menuitem");
is(
diff --git a/browser/base/content/test/forms/browser_selectpopup_text_transform.js b/browser/base/content/test/forms/browser_selectpopup_text_transform.js
index 671f39e2a6..04da532ddc 100644
--- a/browser/base/content/test/forms/browser_selectpopup_text_transform.js
+++ b/browser/base/content/test/forms/browser_selectpopup_text_transform.js
@@ -16,7 +16,7 @@ add_task(async function () {
gBrowser,
url,
},
- async function (browser) {
+ async function () {
let popup = await openSelectPopup("click");
let menuitems = popup.querySelectorAll("menuitem");
is(menuitems[0].textContent, "abc", "Option text should be lowercase");
diff --git a/browser/base/content/test/forms/browser_selectpopup_user_input.js b/browser/base/content/test/forms/browser_selectpopup_user_input.js
index b3cdeaf7e6..028ceadf9a 100644
--- a/browser/base/content/test/forms/browser_selectpopup_user_input.js
+++ b/browser/base/content/test/forms/browser_selectpopup_user_input.js
@@ -71,7 +71,7 @@ async function testHandlingUserInputOnChange(aTriggerFn) {
// This test checks if the change/click event is considered as user input event.
add_task(async function test_handling_user_input_key() {
- return testHandlingUserInputOnChange(async function (popup) {
+ return testHandlingUserInputOnChange(async function () {
EventUtils.synthesizeKey("KEY_ArrowDown");
await hideSelectPopup();
});
diff --git a/browser/base/content/test/forms/browser_selectpopup_width.js b/browser/base/content/test/forms/browser_selectpopup_width.js
index d8f748fb18..0df0fd24ee 100644
--- a/browser/base/content/test/forms/browser_selectpopup_width.js
+++ b/browser/base/content/test/forms/browser_selectpopup_width.js
@@ -19,7 +19,7 @@ add_task(async function () {
gBrowser,
url,
},
- async function (browser) {
+ async function () {
let popup = await openSelectPopup("click");
let arrowSB = popup.shadowRoot.querySelector(".menupopup-arrowscrollbox");
is(
diff --git a/browser/base/content/test/forms/browser_selectpopup_xhtml.js b/browser/base/content/test/forms/browser_selectpopup_xhtml.js
index 091649be89..27597eb5ac 100644
--- a/browser/base/content/test/forms/browser_selectpopup_xhtml.js
+++ b/browser/base/content/test/forms/browser_selectpopup_xhtml.js
@@ -21,7 +21,7 @@ add_task(async function () {
gBrowser,
url,
},
- async function (browser) {
+ async function () {
let popup = await openSelectPopup("click");
let menuitems = popup.querySelectorAll("menuitem");
is(menuitems.length, 2, "Should've properly detected two menu items");
diff --git a/browser/base/content/test/fullscreen/browser_fullscreen_context_menu.js b/browser/base/content/test/fullscreen/browser_fullscreen_context_menu.js
index 9d9891acd2..3bca1a205d 100644
--- a/browser/base/content/test/fullscreen/browser_fullscreen_context_menu.js
+++ b/browser/base/content/test/fullscreen/browser_fullscreen_context_menu.js
@@ -51,7 +51,7 @@ async function testContextMenu() {
window,
"sizemodechange",
false,
- e => window.fullScreen
+ () => window.fullScreen
),
BrowserTestUtils.waitForPopupEvent(contextMenu, "hidden"),
]);
@@ -96,7 +96,7 @@ async function testContextMenu() {
window,
"sizemodechange",
false,
- e => !window.fullScreen
+ () => !window.fullScreen
),
BrowserTestUtils.waitForPopupEvent(contextMenu2, "hidden"),
]);
diff --git a/browser/base/content/test/fullscreen/browser_fullscreen_window_focus.js b/browser/base/content/test/fullscreen/browser_fullscreen_window_focus.js
index 5dd71e1a92..6e471e8124 100644
--- a/browser/base/content/test/fullscreen/browser_fullscreen_window_focus.js
+++ b/browser/base/content/test/fullscreen/browser_fullscreen_window_focus.js
@@ -74,7 +74,7 @@ async function testWindowElementFocus(isPopup) {
false,
async () => {
info("Calling element.focus() on popup");
- await ContentTask.spawn(tab.linkedBrowser, {}, async args => {
+ await ContentTask.spawn(tab.linkedBrowser, {}, async () => {
await content.wrappedJSObject.sendMessage(
content.wrappedJSObject.openedWindow,
"elementfocus"
diff --git a/browser/base/content/test/fullscreen/head.js b/browser/base/content/test/fullscreen/head.js
index 4d5543461e..0d56c5a7c9 100644
--- a/browser/base/content/test/fullscreen/head.js
+++ b/browser/base/content/test/fullscreen/head.js
@@ -5,7 +5,7 @@ function waitForFullScreenState(browser, state, actionAfterFSEvent) {
return new Promise(resolve => {
let eventReceived = false;
- let observe = (subject, topic, data) => {
+ let observe = () => {
if (!eventReceived) {
return;
}
diff --git a/browser/base/content/test/general/browser.toml b/browser/base/content/test/general/browser.toml
index 6928ba2d4b..31d519d550 100644
--- a/browser/base/content/test/general/browser.toml
+++ b/browser/base/content/test/general/browser.toml
@@ -37,10 +37,6 @@ support-files = [
"title_test.svg",
"unknownContentType_file.pif",
"unknownContentType_file.pif^headers^",
- "video.ogg",
- "web_video.html",
- "web_video1.ogv",
- "web_video1.ogv^headers^",
"!/image/test/mochitest/blue.png",
"!/toolkit/content/tests/browser/common/mockTransfer.js",
]
@@ -211,6 +207,7 @@ support-files = [
"dummy.ics",
"dummy.ics^headers^",
"redirect_download.sjs",
+ "video.webm",
]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
@@ -435,9 +432,19 @@ skip-if = [
"os == 'win' && debug",
"os =='linux'", #Bug 1212419
]
+support-files = [
+ "web_video.html",
+ "web_video1.webm",
+ "web_video1.webm^headers^",
+]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_save_video_frame.js"]
+support-files = [
+ "web_video.html",
+ "web_video1.webm",
+ "web_video1.webm^headers^",
+]
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
["browser_selectTabAtIndex.js"]
diff --git a/browser/base/content/test/general/browser_accesskeys.js b/browser/base/content/test/general/browser_accesskeys.js
index 0809553404..965da8d9df 100644
--- a/browser/base/content/test/general/browser_accesskeys.js
+++ b/browser/base/content/test/general/browser_accesskeys.js
@@ -122,7 +122,7 @@ add_task(async function () {
function performAccessKey(browser, key) {
return new Promise(resolve => {
let removeFocus, removeKeyDown, removeKeyUp;
- function callback(eventName, result) {
+ function callback() {
removeFocus();
removeKeyUp();
removeKeyDown();
@@ -190,7 +190,7 @@ function performAccessKey(browser, key) {
}
// This version is used when a chrome element is expected to be found for an accesskey.
-async function performAccessKeyForChrome(key, inChild) {
+async function performAccessKeyForChrome(key) {
let waitFocusChangePromise = BrowserTestUtils.waitForEvent(
document,
"focus",
diff --git a/browser/base/content/test/general/browser_alltabslistener.js b/browser/base/content/test/general/browser_alltabslistener.js
index c7829d16fe..fc950d6ce5 100644
--- a/browser/base/content/test/general/browser_alltabslistener.js
+++ b/browser/base/content/test/general/browser_alltabslistener.js
@@ -7,16 +7,9 @@ function getOriginalURL(request) {
}
var gFrontProgressListener = {
- onProgressChange(
- aWebProgress,
- aRequest,
- aCurSelfProgress,
- aMaxSelfProgress,
- aCurTotalProgress,
- aMaxTotalProgress
- ) {},
+ onProgressChange() {},
- onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
+ onStateChange(aWebProgress, aRequest, aStateFlags) {
var url = getOriginalURL(aRequest);
if (url == "about:blank") {
return;
@@ -28,7 +21,7 @@ var gFrontProgressListener = {
assertCorrectBrowserAndEventOrderForFront(state);
},
- onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
+ onLocationChange(aWebProgress, aRequest, aLocationURI) {
var url = getOriginalURL(aRequest);
if (url == "about:blank") {
return;
@@ -64,7 +57,7 @@ function assertCorrectBrowserAndEventOrderForFront(aEventName) {
}
var gAllProgressListener = {
- onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
+ onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags) {
var url = getOriginalURL(aRequest);
if (url == "about:blank") {
// ignore initial about blank
diff --git a/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js b/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
index 8eb07a863a..81ed5a1040 100644
--- a/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
+++ b/browser/base/content/test/general/browser_beforeunload_duplicate_dialogs.js
@@ -57,7 +57,7 @@ add_task(async function closeWindowWithMultipleTabsIncludingOneBeforeUnload() {
);
let windowClosedPromise = BrowserTestUtils.domWindowClosed(newWin);
expectingDialog = true;
- newWin.BrowserTryToCloseWindow();
+ newWin.BrowserCommands.tryToCloseWindow();
await windowClosedPromise;
ok(!expectingDialog, "There should have been a dialog.");
ok(newWin.closed, "Window should be closed.");
@@ -71,7 +71,7 @@ add_task(async function closeWindoWithSingleTabTwice() {
let windowClosedPromise = BrowserTestUtils.domWindowClosed(newWin);
expectingDialog = true;
wantToClose = false;
- let firstDialogShownPromise = new Promise((resolve, reject) => {
+ let firstDialogShownPromise = new Promise(resolve => {
resolveDialogPromise = resolve;
});
firstTab.closeButton.click();
diff --git a/browser/base/content/test/general/browser_bug356571.js b/browser/base/content/test/general/browser_bug356571.js
index aa3569c93d..69b45e040d 100644
--- a/browser/base/content/test/general/browser_bug356571.js
+++ b/browser/base/content/test/general/browser_bug356571.js
@@ -45,7 +45,7 @@ const kURIs = ["bad://www.mozilla.org/", kDummyPage, kDummyPage];
var gProgressListener = {
_runCount: 0,
- onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
+ onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags) {
if ((aStateFlags & kCompleteState) == kCompleteState) {
if (++this._runCount != kURIs.length) {
return;
diff --git a/browser/base/content/test/general/browser_bug417483.js b/browser/base/content/test/general/browser_bug417483.js
index 68e2e99511..28da91eea1 100644
--- a/browser/base/content/test/general/browser_bug417483.js
+++ b/browser/base/content/test/general/browser_bug417483.js
@@ -8,7 +8,7 @@ add_task(async function () {
BrowserTestUtils.startLoadingURIString(gBrowser, htmlContent);
await loadedPromise;
- await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function (arg) {
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
let frame = content.frames[0];
let sel = frame.getSelection();
let range = frame.document.createRange();
diff --git a/browser/base/content/test/general/browser_bug537013.js b/browser/base/content/test/general/browser_bug537013.js
index 5c871a759c..58bcec9754 100644
--- a/browser/base/content/test/general/browser_bug537013.js
+++ b/browser/base/content/test/general/browser_bug537013.js
@@ -15,7 +15,7 @@ var HasFindClipboard = Services.clipboard.isClipboardTypeSupported(
Services.clipboard.kFindClipboard
);
-function addTabWithText(aText, aCallback) {
+function addTabWithText(aText) {
let newTab = BrowserTestUtils.addTab(
gBrowser,
"data:text/html;charset=utf-8,<h1 id='h1'>" + aText + "</h1>"
diff --git a/browser/base/content/test/general/browser_bug565575.js b/browser/base/content/test/general/browser_bug565575.js
index 6176c537e3..b974b17205 100644
--- a/browser/base/content/test/general/browser_bug565575.js
+++ b/browser/base/content/test/general/browser_bug565575.js
@@ -3,7 +3,7 @@ add_task(async function () {
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
- () => BrowserOpenTab(),
+ () => BrowserCommands.openTab(),
false
);
ok(gURLBar.focused, "location bar is focused for a new tab");
diff --git a/browser/base/content/test/general/browser_bug567306.js b/browser/base/content/test/general/browser_bug567306.js
index 3d3e47e17d..24280371d8 100644
--- a/browser/base/content/test/general/browser_bug567306.js
+++ b/browser/base/content/test/general/browser_bug567306.js
@@ -10,7 +10,7 @@ add_task(async function () {
let newwindow = await BrowserTestUtils.openNewBrowserWindow();
let selectedBrowser = newwindow.gBrowser.selectedBrowser;
- await new Promise((resolve, reject) => {
+ await new Promise(resolve => {
BrowserTestUtils.waitForContentEvent(
selectedBrowser,
"pageshow",
diff --git a/browser/base/content/test/general/browser_bug609700.js b/browser/base/content/test/general/browser_bug609700.js
index 8195eba4ec..615b63c3d8 100644
--- a/browser/base/content/test/general/browser_bug609700.js
+++ b/browser/base/content/test/general/browser_bug609700.js
@@ -1,11 +1,7 @@
function test() {
waitForExplicitFinish();
- Services.ww.registerNotification(function notification(
- aSubject,
- aTopic,
- aData
- ) {
+ Services.ww.registerNotification(function notification(aSubject, aTopic) {
if (aTopic == "domwindowopened") {
Services.ww.unregisterNotification(notification);
diff --git a/browser/base/content/test/general/browser_bug623893.js b/browser/base/content/test/general/browser_bug623893.js
index 79cd10c591..0f742a8e8e 100644
--- a/browser/base/content/test/general/browser_bug623893.js
+++ b/browser/base/content/test/general/browser_bug623893.js
@@ -38,7 +38,7 @@ async function promiseGetIndex(browser) {
return shistory.index;
}
-let duplicate = async function (delta, msg, cb) {
+let duplicate = async function (delta, msg) {
var startIndex = await promiseGetIndex(gBrowser.selectedBrowser);
duplicateTabIn(gBrowser.selectedTab, "tab", delta);
diff --git a/browser/base/content/test/general/browser_bug676619.js b/browser/base/content/test/general/browser_bug676619.js
index 80bbce8cb0..90dd8f4f7c 100644
--- a/browser/base/content/test/general/browser_bug676619.js
+++ b/browser/base/content/test/general/browser_bug676619.js
@@ -22,7 +22,7 @@ function waitForNewWindow() {
var domwindow = aXULWindow.docShell.domWindow;
domwindow.addEventListener("load", downloadOnLoad, true);
},
- onCloseWindow: aXULWindow => {},
+ onCloseWindow: () => {},
};
Services.wm.addListener(listener);
@@ -97,7 +97,7 @@ async function testLink(link, name) {
}
// Cross-origin URL does not trigger a download
-async function testLocation(link, url) {
+async function testLocation(link) {
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => {
@@ -116,8 +116,8 @@ async function runTest(url) {
await BrowserTestUtils.browserLoaded(browser);
await testLink("link1", "test.txt");
- await testLink("link2", "video.ogg");
- await testLink("link3", "just some video.ogg");
+ await testLink("link2", "video.webm");
+ await testLink("link3", "just some video.webm");
await testLink("link4", "with-target.txt");
await testLink("link5", "javascript.html");
await testLink("link6", "test.blob");
@@ -132,8 +132,8 @@ async function runTest(url) {
// Check that we enforce the correct extension if the website's
// is bogus or missing. These extensions can differ slightly (ogx vs ogg,
// htm vs html) on different OSes.
- let oggExtension = getMIMEInfoForType("application/ogg").primaryExtension;
- await testLink("link13", "no file extension." + oggExtension);
+ let webmExtension = getMIMEInfoForType("video/webm").primaryExtension;
+ await testLink("link13", "no file extension." + webmExtension);
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1690051#c8
if (AppConstants.platform != "win") {
diff --git a/browser/base/content/test/general/browser_bug734076.js b/browser/base/content/test/general/browser_bug734076.js
index bd86f8e2b3..e9bec6834e 100644
--- a/browser/base/content/test/general/browser_bug734076.js
+++ b/browser/base/content/test/general/browser_bug734076.js
@@ -36,7 +36,7 @@ add_task(async function () {
);
},
verify(browser) {
- return SpecialPowers.spawn(browser, [], async function (arg) {
+ return SpecialPowers.spawn(browser, [], async function () {
Assert.equal(
content.document.body.textContent,
"",
@@ -67,7 +67,7 @@ add_task(async function () {
);
},
verify(browser) {
- return SpecialPowers.spawn(browser, [], async function (arg) {
+ return SpecialPowers.spawn(browser, [], async function () {
Assert.equal(
content.document.body.textContent,
"",
@@ -105,7 +105,7 @@ add_task(async function () {
);
},
verify(browser) {
- return SpecialPowers.spawn(browser, [], async function (arg) {
+ return SpecialPowers.spawn(browser, [], async function () {
Assert.equal(
content.document.body.textContent,
"",
diff --git a/browser/base/content/test/general/browser_bug763468_perwindowpb.js b/browser/base/content/test/general/browser_bug763468_perwindowpb.js
index bed03561ca..05a7f90550 100644
--- a/browser/base/content/test/general/browser_bug763468_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug763468_perwindowpb.js
@@ -44,7 +44,7 @@ add_task(async function testPBNewTab() {
async function openNewTab(aWindow, aExpectedURL) {
// Open a new tab
- aWindow.BrowserOpenTab();
+ aWindow.BrowserCommands.openTab();
let browser = aWindow.gBrowser.selectedBrowser;
// We're already loaded.
diff --git a/browser/base/content/test/general/browser_bug767836_perwindowpb.js b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
index 7fcc6ad565..e237f1216d 100644
--- a/browser/base/content/test/general/browser_bug767836_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
@@ -59,7 +59,7 @@ add_task(async function test_newTabService() {
async function openNewTab(aWindow, aExpectedURL) {
// Open a new tab
- aWindow.BrowserOpenTab();
+ aWindow.BrowserCommands.openTab();
let browser = aWindow.gBrowser.selectedBrowser;
// We're already loaded.
diff --git a/browser/base/content/test/general/browser_bug817947.js b/browser/base/content/test/general/browser_bug817947.js
index ea3c39222e..f83e07a9af 100644
--- a/browser/base/content/test/general/browser_bug817947.js
+++ b/browser/base/content/test/general/browser_bug817947.js
@@ -32,7 +32,7 @@ add_task(async () => {
win.close();
});
-async function preparePendingTab(aCallback) {
+async function preparePendingTab() {
let tab = BrowserTestUtils.addTab(gBrowser, URL);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
diff --git a/browser/base/content/test/general/browser_clipboard.js b/browser/base/content/test/general/browser_clipboard.js
index a4c823969f..7820c4ec89 100644
--- a/browser/base/content/test/general/browser_clipboard.js
+++ b/browser/base/content/test/general/browser_clipboard.js
@@ -68,7 +68,7 @@ add_task(async function () {
let selection = content.document.getSelection();
selection.modify("move", "right", "line");
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
content.addEventListener(
"paste",
event => {
@@ -130,7 +130,7 @@ add_task(async function () {
selection.modify("extend", "left", "word");
selection.modify("extend", "left", "character");
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
content.addEventListener(
"cut",
event => {
@@ -157,7 +157,7 @@ add_task(async function () {
let selection = content.document.getSelection();
selection.modify("move", "left", "line");
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
content.addEventListener(
"paste",
event => {
diff --git a/browser/base/content/test/general/browser_clipboard_pastefile.js b/browser/base/content/test/general/browser_clipboard_pastefile.js
index f034883ef2..6ef3edf30e 100644
--- a/browser/base/content/test/general/browser_clipboard_pastefile.js
+++ b/browser/base/content/test/general/browser_clipboard_pastefile.js
@@ -50,7 +50,7 @@ add_task(async function () {
);
let browser = tab.linkedBrowser;
- let resultPromise = SpecialPowers.spawn(browser, [], function (arg) {
+ let resultPromise = SpecialPowers.spawn(browser, [], function () {
return new Promise(resolve => {
content.document.addEventListener("testresult", event => {
resolve(event.detail.result);
@@ -73,7 +73,7 @@ add_task(async function () {
document.documentElement.appendChild(input);
input.focus();
- await new Promise((resolve, reject) => {
+ await new Promise(resolve => {
input.addEventListener(
"paste",
function (event) {
diff --git a/browser/base/content/test/general/browser_documentnavigation.js b/browser/base/content/test/general/browser_documentnavigation.js
index 880db6110f..b68e6ec3f0 100644
--- a/browser/base/content/test/general/browser_documentnavigation.js
+++ b/browser/base/content/test/general/browser_documentnavigation.js
@@ -229,7 +229,7 @@ add_task(async function () {
let sidebar = document.getElementById("sidebar");
let loadPromise = BrowserTestUtils.waitForEvent(sidebar, "load", true);
- SidebarUI.toggle("viewBookmarksSidebar");
+ SidebarController.toggle("viewBookmarksSidebar");
await loadPromise;
gURLBar.focus();
@@ -278,7 +278,7 @@ add_task(async function () {
"back focus with sidebar urlbar"
);
- SidebarUI.toggle("viewBookmarksSidebar");
+ SidebarController.toggle("viewBookmarksSidebar");
});
// Navigate when the downloads panel is open
diff --git a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js
index c96fa6cf7b..f44620c29e 100644
--- a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js
+++ b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js
@@ -149,7 +149,7 @@ add_task(async function () {
gBrowser.selectedBrowser,
FS_CHANGE_SIZE
);
- executeSoon(() => BrowserFullScreen());
+ executeSoon(() => BrowserCommands.fullScreen());
await fullscreenPromise;
}
});
@@ -195,7 +195,7 @@ add_task(async function () {
// dispatched synchronously, which would cause the event listener
// miss that event and wait infinitely.
fullscreenPromise = waitForFullscreenChanges(browser, FS_CHANGE_SIZE);
- executeSoon(() => BrowserFullScreen());
+ executeSoon(() => BrowserCommands.fullScreen());
contentStates = await fullscreenPromise;
checkState({ inDOMFullscreen: false, inFullscreen: true }, contentStates);
@@ -228,7 +228,7 @@ add_task(async function () {
if (window.fullScreen) {
info("> Cleanup");
fullscreenPromise = waitForFullscreenChanges(browser, FS_CHANGE_SIZE);
- executeSoon(() => BrowserFullScreen());
+ executeSoon(() => BrowserCommands.fullScreen());
await fullscreenPromise;
}
}
diff --git a/browser/base/content/test/general/browser_double_close_tab.js b/browser/base/content/test/general/browser_double_close_tab.js
index f5f2f1b6c7..6beea0f42b 100644
--- a/browser/base/content/test/general/browser_double_close_tab.js
+++ b/browser/base/content/test/general/browser_double_close_tab.js
@@ -18,7 +18,7 @@ function waitForDialog(callback) {
function waitForDialogDestroyed(node, callback) {
// Now listen for the dialog going away again...
- let observer = new MutationObserver(function (muts) {
+ let observer = new MutationObserver(function () {
if (!node.parentNode) {
ok(true, "Dialog is gone");
done();
diff --git a/browser/base/content/test/general/browser_focusonkeydown.js b/browser/base/content/test/general/browser_focusonkeydown.js
index 9cf1f113f5..53919bc1b3 100644
--- a/browser/base/content/test/general/browser_focusonkeydown.js
+++ b/browser/base/content/test/general/browser_focusonkeydown.js
@@ -20,7 +20,7 @@ add_task(async function () {
gURLBar.addEventListener(
"keydown",
- function (event) {
+ function () {
gBrowser.selectedBrowser.focus();
},
{ capture: true, once: true }
diff --git a/browser/base/content/test/general/browser_fullscreen-window-open.js b/browser/base/content/test/general/browser_fullscreen-window-open.js
index 2b21e34e92..be1d2ca3a3 100644
--- a/browser/base/content/test/general/browser_fullscreen-window-open.js
+++ b/browser/base/content/test/general/browser_fullscreen-window-open.js
@@ -26,14 +26,14 @@ async function test() {
await promiseTabLoadEvent(newBrowser.selectedTab, gHttpTestRoot + TEST_FILE);
// Enter browser fullscreen mode.
- newWin.BrowserFullScreen();
+ newWin.BrowserCommands.fullScreen();
runNextTest();
}
registerCleanupFunction(async function () {
// Exit browser fullscreen mode.
- newWin.BrowserFullScreen();
+ newWin.BrowserCommands.fullScreen();
await BrowserTestUtils.closeWindow(newWin);
@@ -336,7 +336,7 @@ WindowListener.prototype = {
Services.wm.removeListener(this);
let domwindow = aXULWindow.docShell.domWindow;
- let onLoad = aEvent => {
+ let onLoad = () => {
is(
domwindow.document.location.href,
this.test_url,
@@ -361,6 +361,6 @@ WindowListener.prototype = {
};
domwindow.addEventListener("load", onLoad, true);
},
- onCloseWindow(aXULWindow) {},
+ onCloseWindow() {},
QueryInterface: ChromeUtils.generateQI(["nsIWindowMediatorListener"]),
};
diff --git a/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js b/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js
index 1624a1514d..fae1130685 100644
--- a/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js
+++ b/browser/base/content/test/general/browser_invalid_uri_back_forward_manipulation.js
@@ -33,7 +33,7 @@ add_task(async function checkBackFromInvalidURI() {
false,
// Be paranoid we *are* actually seeing this other page load, not some kind of race
// for if/when we do start firing pageshow for the error page...
- function (e) {
+ function () {
return gBrowser.currentURI.spec == "about:robots";
}
);
diff --git a/browser/base/content/test/general/browser_newWindowDrop.js b/browser/base/content/test/general/browser_newWindowDrop.js
index 3e41b0d6ac..445999befd 100644
--- a/browser/base/content/test/general/browser_newWindowDrop.js
+++ b/browser/base/content/test/general/browser_newWindowDrop.js
@@ -184,7 +184,7 @@ function dropText(text, expectedURLs, ignoreFirstWindow = false) {
);
}
-async function drop(dragData, expectedURLs, ignoreFirstWindow = false) {
+async function drop(dragData, expectedURLs) {
let dragDataString = JSON.stringify(dragData);
info(
`Starting test for dragData:${dragDataString}; expectedURLs.length:${expectedURLs.length}`
diff --git a/browser/base/content/test/general/browser_plainTextLinks.js b/browser/base/content/test/general/browser_plainTextLinks.js
index 706f21387c..44c9b8422b 100644
--- a/browser/base/content/test/general/browser_plainTextLinks.js
+++ b/browser/base/content/test/general/browser_plainTextLinks.js
@@ -19,7 +19,7 @@ add_task(async function () {
await SimpleTest.promiseFocus(gBrowser.selectedBrowser);
// Initial setup of the content area.
- await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function (arg) {
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
let doc = content.document;
let range = doc.createRange();
let selection = content.getSelection();
diff --git a/browser/base/content/test/general/browser_private_no_prompt.js b/browser/base/content/test/general/browser_private_no_prompt.js
index d8c9f8e7b5..80ba0ca746 100644
--- a/browser/base/content/test/general/browser_private_no_prompt.js
+++ b/browser/base/content/test/general/browser_private_no_prompt.js
@@ -3,8 +3,8 @@ function test() {
var privateWin = OpenBrowserWindow({ private: true });
whenDelayedStartupFinished(privateWin, function () {
- privateWin.BrowserOpenTab();
- privateWin.BrowserTryToCloseWindow();
+ privateWin.BrowserCommands.openTab();
+ privateWin.BrowserCommands.tryToCloseWindow();
ok(true, "didn't prompt");
executeSoon(finish);
diff --git a/browser/base/content/test/general/browser_remoteTroubleshoot.js b/browser/base/content/test/general/browser_remoteTroubleshoot.js
index 84722b2603..55627f0b28 100644
--- a/browser/base/content/test/general/browser_remoteTroubleshoot.js
+++ b/browser/base/content/test/general/browser_remoteTroubleshoot.js
@@ -19,9 +19,9 @@ const TEST_URI_GOOD_OBJECT = Services.io.newURI(
// Creates a one-shot web-channel for the test data to be sent back from the test page.
function promiseChannelResponse(channelID, originOrPermission) {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let channel = new WebChannel(channelID, originOrPermission);
- channel.listen((id, data, target) => {
+ channel.listen((id, data) => {
channel.stopListening();
resolve(data);
});
diff --git a/browser/base/content/test/general/browser_save_link-perwindowpb.js b/browser/base/content/test/general/browser_save_link-perwindowpb.js
index 234813ca2c..29fd54d2d9 100644
--- a/browser/base/content/test/general/browser_save_link-perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_link-perwindowpb.js
@@ -14,7 +14,7 @@ function triggerSave(aWindow, aCallback) {
let testBrowser = aWindow.gBrowser.selectedBrowser;
// This page sets a cookie if and only if a cookie does not exist yet
let testURI =
- "https://example.com/browser/browser/base/content/test/general/bug792517-2.html";
+ "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517-2.html";
BrowserTestUtils.startLoadingURIString(testBrowser, testURI);
BrowserTestUtils.browserLoaded(testBrowser, false, testURI).then(() => {
waitForFocus(function () {
@@ -68,7 +68,7 @@ function triggerSave(aWindow, aCallback) {
info("popup hidden");
}
- function onTransferComplete(aWindow2, downloadSuccess, destDir) {
+ function onTransferComplete(aWindow2, downloadSuccess) {
ok(downloadSuccess, "Link should have been downloaded successfully");
aWindow2.close();
@@ -118,7 +118,7 @@ function test() {
info("Finished running the cleanup code");
});
- function observer(subject, topic, state) {
+ function observer(subject, topic) {
info("observer called with " + topic);
if (topic == "http-on-modify-request") {
onModifyRequest(subject);
@@ -132,7 +132,7 @@ function test() {
info("onExamineResponse with " + channel.URI.spec);
if (
channel.URI.spec !=
- "https://example.com/browser/browser/base/content/test/general/bug792517.sjs"
+ "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs"
) {
info("returning");
return;
@@ -158,7 +158,7 @@ function test() {
info("onModifyRequest with " + channel.URI.spec);
if (
channel.URI.spec !=
- "https://example.com/browser/browser/base/content/test/general/bug792517.sjs"
+ "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs"
) {
return;
}
diff --git a/browser/base/content/test/general/browser_save_link_when_window_navigates.js b/browser/base/content/test/general/browser_save_link_when_window_navigates.js
index 65daef5f1b..e5c7fa76b2 100644
--- a/browser/base/content/test/general/browser_save_link_when_window_navigates.js
+++ b/browser/base/content/test/general/browser_save_link_when_window_navigates.js
@@ -36,7 +36,7 @@ function triggerSave(aWindow, aCallback) {
var fileName;
let testBrowser = aWindow.gBrowser.selectedBrowser;
let testURI =
- "https://example.com/browser/browser/base/content/test/general/navigating_window_with_download.html";
+ "http://mochi.test:8888/browser/browser/base/content/test/general/navigating_window_with_download.html";
// Only observe the UTC dialog if it's enabled by pref
if (Services.prefs.getBoolPref(ALWAYS_ASK_PREF)) {
@@ -70,7 +70,7 @@ function triggerSave(aWindow, aCallback) {
info("done mockTransferCallback");
};
- function onUCTDialog(dialog) {
+ function onUCTDialog() {
SpecialPowers.spawn(testBrowser, [], async () => {
content.document.querySelector("iframe").remove();
}).then(() => executeSoon(continueDownloading));
@@ -104,7 +104,7 @@ var windowObserver = {
}
this._callback = aCallback;
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (aTopic != "domwindowopened") {
return;
}
@@ -113,7 +113,7 @@ var windowObserver = {
win.addEventListener(
"load",
- function (event) {
+ function () {
if (win.location == UCT_URI) {
SimpleTest.executeSoon(function () {
if (windowObserver._callback) {
diff --git a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
index 42632bdc5a..1312c7b954 100644
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
@@ -12,9 +12,9 @@ function createTemporarySaveDirectory() {
}
function promiseNoCacheEntry(filename) {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
Visitor.prototype = {
- onCacheStorageInfo(num, consumption) {
+ onCacheStorageInfo(num) {
info("disk storage contains " + num + " entries");
},
onCacheEntryInfo(uri) {
@@ -40,7 +40,7 @@ function promiseNoCacheEntry(filename) {
}
function promiseImageDownloaded() {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let fileName;
let MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window.browsingContext);
diff --git a/browser/base/content/test/general/browser_save_video.js b/browser/base/content/test/general/browser_save_video.js
index e9701d7023..f0450ac1fa 100644
--- a/browser/base/content/test/general/browser_save_video.js
+++ b/browser/base/content/test/general/browser_save_video.js
@@ -14,7 +14,7 @@ add_task(async function () {
let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
BrowserTestUtils.startLoadingURIString(
gBrowser,
- "https://example.com/browser/browser/base/content/test/general/web_video.html"
+ "http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html"
);
await loadPromise;
@@ -52,7 +52,7 @@ add_task(async function () {
is(
fileName,
- "web-video1-expectedName.ogv",
+ "web-video1-expectedName.webm",
"Video file name is correctly retrieved from Content-Disposition http header"
);
resolve();
diff --git a/browser/base/content/test/general/browser_tabfocus.js b/browser/base/content/test/general/browser_tabfocus.js
index b057a504e5..7cc9158084 100644
--- a/browser/base/content/test/general/browser_tabfocus.js
+++ b/browser/base/content/test/general/browser_tabfocus.js
@@ -322,7 +322,7 @@ add_task(async function () {
"tab change when selected tab element was focused"
);
- let switchWaiter = new Promise((resolve, reject) => {
+ let switchWaiter = new Promise(resolve => {
gBrowser.addEventListener(
"TabSwitchDone",
function () {
@@ -516,7 +516,7 @@ add_task(async function () {
// now go back again
gURLBar.focus();
- await new Promise((resolve, reject) => {
+ await new Promise(resolve => {
BrowserTestUtils.waitForContentEvent(
window.gBrowser.selectedBrowser,
"pageshow",
diff --git a/browser/base/content/test/general/browser_tabs_owner.js b/browser/base/content/test/general/browser_tabs_owner.js
index 4a32da12f1..e214b861e8 100644
--- a/browser/base/content/test/general/browser_tabs_owner.js
+++ b/browser/base/content/test/general/browser_tabs_owner.js
@@ -8,13 +8,13 @@ function test() {
is(gBrowser.tabs.length, 4, "4 tabs are open");
owner = gBrowser.selectedTab = gBrowser.tabs[2];
- BrowserOpenTab();
+ BrowserCommands.openTab();
is(gBrowser.selectedTab, gBrowser.tabs[4], "newly opened tab is selected");
gBrowser.removeCurrentTab();
is(gBrowser.selectedTab, owner, "owner is selected");
owner = gBrowser.selectedTab;
- BrowserOpenTab();
+ BrowserCommands.openTab();
gBrowser.selectedTab = gBrowser.tabs[1];
gBrowser.selectedTab = gBrowser.tabs[4];
gBrowser.removeCurrentTab();
@@ -25,7 +25,7 @@ function test() {
);
owner = gBrowser.selectedTab;
- BrowserOpenTab();
+ BrowserCommands.openTab();
gBrowser.moveTabTo(gBrowser.selectedTab, 0);
gBrowser.removeCurrentTab();
is(
diff --git a/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js b/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
index 6c62670e6f..26c040324a 100644
--- a/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
+++ b/browser/base/content/test/general/browser_viewSourceInTabOnViewSource.js
@@ -1,7 +1,7 @@
function wait_while_tab_is_busy() {
return new Promise(resolve => {
let progressListener = {
- onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
+ onStateChange(aWebProgress, aRequest, aStateFlags) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
gBrowser.removeProgressListener(this);
setTimeout(resolve, 0);
@@ -27,7 +27,7 @@ var with_new_tab_opened = async function (options, taskFn) {
};
add_task(async function test_regular_page() {
- function test_expect_view_source_enabled(browser) {
+ function test_expect_view_source_enabled() {
for (let element of [...XULBrowserWindow._elementsForViewSource]) {
ok(!element.hasAttribute("disabled"), "View Source should be enabled");
}
@@ -44,7 +44,7 @@ add_task(async function test_regular_page() {
});
add_task(async function test_view_source_page() {
- function test_expect_view_source_disabled(browser) {
+ function test_expect_view_source_disabled() {
for (let element of [...XULBrowserWindow._elementsForViewSource]) {
ok(element.hasAttribute("disabled"), "View Source should be disabled");
}
diff --git a/browser/base/content/test/general/browser_zbug569342.js b/browser/base/content/test/general/browser_zbug569342.js
index 4aa6bfbb9c..0c30ff3d1d 100644
--- a/browser/base/content/test/general/browser_zbug569342.js
+++ b/browser/base/content/test/general/browser_zbug569342.js
@@ -57,7 +57,7 @@ function testFindDisabled(url) {
}
async function testFindEnabled(url) {
- return BrowserTestUtils.withNewTab(url, async function (browser) {
+ return BrowserTestUtils.withNewTab(url, async function () {
ok(
!document.getElementById("cmd_find").getAttribute("disabled"),
"Find command should not be disabled"
diff --git a/browser/base/content/test/general/download_page.html b/browser/base/content/test/general/download_page.html
index 300bacdb72..625ff46aab 100644
--- a/browser/base/content/test/general/download_page.html
+++ b/browser/base/content/test/general/download_page.html
@@ -13,10 +13,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=676619
<ul>
<li><a href="download_page_1.txt"
download="test.txt" id="link1">Download "test.txt"</a></li>
- <li><a href="video.ogg"
- download id="link2">Download "video.ogg"</a></li>
- <li><a href="video.ogg"
- download="just some video.ogg" id="link3">Download "just some video.ogg"</a></li>
+ <li><a href="video.webm"
+ download id="link2">Download "video.webm"</a></li>
+ <li><a href="video.webm"
+ download="just some video.webm" id="link3">Download "just some video.webm"</a></li>
<li><a href="download_page_2.txt"
download="with-target.txt" id="link4">Download "with-target.txt"</a></li>
<li><a href="javascript:(1+2)+''"
@@ -33,7 +33,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=676619
download="download_page_4.txt" id="link11">Download "download_page_4.txt"</a></li>
<li><a href="http://example.com/"
download="example.com" id="link12" target="_blank">Download "example.com"</a></li>
- <li><a href="video.ogg"
+ <li><a href="video.webm"
download="no file extension" id="link13">Download "force extension"</a></li>
<li><a href="dummy.ics"
download="dummy.not-ics" id="link14">Download "dummy.not-ics"</a></li>
@@ -64,7 +64,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=676619
"wrong-file-name", {type: "application/x-some-file"}));
document.getElementById("link7").href = fileURL;
- window.addEventListener("beforeunload", function(evt) {
+ window.addEventListener("beforeunload", function() {
document.getElementById("unload-flag").textContent = "Fail";
});
</script>
diff --git a/browser/base/content/test/general/head.js b/browser/base/content/test/general/head.js
index f7b4a0d93b..94f60f2936 100644
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -165,7 +165,7 @@ function promiseOpenAndLoadWindow(aOptions, aWaitForDelayedStartup = false) {
return new Promise(resolve => {
let win = OpenBrowserWindow(aOptions);
if (aWaitForDelayedStartup) {
- Services.obs.addObserver(function onDS(aSubject, aTopic, aData) {
+ Services.obs.addObserver(function onDS(aSubject) {
if (aSubject != win) {
return;
}
@@ -185,7 +185,7 @@ function promiseOpenAndLoadWindow(aOptions, aWaitForDelayedStartup = false) {
}
async function whenNewTabLoaded(aWindow, aCallback) {
- aWindow.BrowserOpenTab();
+ aWindow.BrowserCommands.openTab();
let expectedURL = AboutNewTab.newTabURL;
let browser = aWindow.gBrowser.selectedBrowser;
diff --git a/browser/base/content/test/general/navigating_window_with_download.html b/browser/base/content/test/general/navigating_window_with_download.html
index 8649168cf5..6b0918941f 100644
--- a/browser/base/content/test/general/navigating_window_with_download.html
+++ b/browser/base/content/test/general/navigating_window_with_download.html
@@ -2,6 +2,6 @@
<html>
<head><title>This window will navigate while you're downloading something</title></head>
<body>
- <iframe src="https://example.com/browser/browser/base/content/test/general/unknownContentType_file.pif"></iframe>
+ <iframe src="http://mochi.test:8888/browser/browser/base/content/test/general/unknownContentType_file.pif"></iframe>
</body>
</html>
diff --git a/browser/base/content/test/general/video.ogg b/browser/base/content/test/general/video.ogg
deleted file mode 100644
index ac7ece3519..0000000000
--- a/browser/base/content/test/general/video.ogg
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/video.webm b/browser/base/content/test/general/video.webm
new file mode 100644
index 0000000000..0ca38d3cf0
--- /dev/null
+++ b/browser/base/content/test/general/video.webm
Binary files differ
diff --git a/browser/base/content/test/general/web_video.html b/browser/base/content/test/general/web_video.html
index 467fb0ce1c..e03c85d1dc 100644
--- a/browser/base/content/test/general/web_video.html
+++ b/browser/base/content/test/general/web_video.html
@@ -5,6 +5,6 @@
<body>
This document has some web video in it.
<br>
- <video src="web_video1.ogv" id="video1"> </video>
+ <video src="web_video1.webm" id="video1"> </video>
</body>
</html>
diff --git a/browser/base/content/test/general/web_video1.ogv b/browser/base/content/test/general/web_video1.ogv
deleted file mode 100644
index 093158432a..0000000000
--- a/browser/base/content/test/general/web_video1.ogv
+++ /dev/null
Binary files differ
diff --git a/browser/base/content/test/general/web_video1.ogv^headers^ b/browser/base/content/test/general/web_video1.ogv^headers^
deleted file mode 100644
index 4511e92552..0000000000
--- a/browser/base/content/test/general/web_video1.ogv^headers^
+++ /dev/null
@@ -1,3 +0,0 @@
-Content-Disposition: filename="web-video1-expectedName.ogv"
-Content-Type: video/ogg
-
diff --git a/browser/base/content/test/general/web_video1.webm b/browser/base/content/test/general/web_video1.webm
new file mode 100644
index 0000000000..2c9d7dad8d
--- /dev/null
+++ b/browser/base/content/test/general/web_video1.webm
Binary files differ
diff --git a/browser/base/content/test/general/web_video1.webm^headers^ b/browser/base/content/test/general/web_video1.webm^headers^
new file mode 100644
index 0000000000..d027132ea2
--- /dev/null
+++ b/browser/base/content/test/general/web_video1.webm^headers^
@@ -0,0 +1,3 @@
+Content-Disposition: filename="web-video1-expectedName.webm"
+Content-Type: video/webm
+
diff --git a/browser/base/content/test/historySwipeAnimation/browser_historySwipeAnimation.js b/browser/base/content/test/historySwipeAnimation/browser_historySwipeAnimation.js
index a5910964e7..eeeb7e8b9e 100644
--- a/browser/base/content/test/historySwipeAnimation/browser_historySwipeAnimation.js
+++ b/browser/base/content/test/historySwipeAnimation/browser_historySwipeAnimation.js
@@ -5,7 +5,7 @@
function test() {
waitForExplicitFinish();
- BrowserOpenTab();
+ BrowserCommands.openTab();
let tab = gBrowser.selectedTab;
registerCleanupFunction(function () {
gBrowser.removeTab(tab);
diff --git a/browser/base/content/test/keyboard/browser_toolbarButtonKeyPress.js b/browser/base/content/test/keyboard/browser_toolbarButtonKeyPress.js
index 8640716bab..ef92d4c528 100644
--- a/browser/base/content/test/keyboard/browser_toolbarButtonKeyPress.js
+++ b/browser/base/content/test/keyboard/browser_toolbarButtonKeyPress.js
@@ -12,7 +12,7 @@ const kDevPanelID = "PanelUI-developer-tools";
function waitForLocationChange() {
let promise = new Promise(resolve => {
let wpl = {
- onLocationChange(aWebProgress, aRequest, aLocation) {
+ onLocationChange() {
gBrowser.removeProgressListener(wpl);
resolve();
},
@@ -213,31 +213,23 @@ add_task(async function testSidebarsButtonPress() {
// This is an image with a click handler on its parent and no command handler,
// but the toolbar keyboard navigation code should handle keyboard activation.
add_task(async function testBookmarkButtonPress() {
- await BrowserTestUtils.withNewTab(
- "https://example.com",
- async function (aBrowser) {
- let button = document.getElementById("star-button-box");
- StarUI._createPanelIfNeeded();
- let panel = document.getElementById("editBookmarkPanel");
- let focused = BrowserTestUtils.waitForEvent(panel, "focus", true);
- // The button ignores activation while the bookmarked status is being
- // updated. So, wait for it to finish updating.
- await TestUtils.waitForCondition(
- () => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING
- );
- await focusAndActivateElement(button, () =>
- EventUtils.synthesizeKey(" ")
- );
- await focused;
- ok(
- true,
- "Focus inside edit bookmark panel after Bookmark button pressed"
- );
- let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
- EventUtils.synthesizeKey("KEY_Escape");
- await hidden;
- }
- );
+ await BrowserTestUtils.withNewTab("https://example.com", async function () {
+ let button = document.getElementById("star-button-box");
+ StarUI._createPanelIfNeeded();
+ let panel = document.getElementById("editBookmarkPanel");
+ let focused = BrowserTestUtils.waitForEvent(panel, "focus", true);
+ // The button ignores activation while the bookmarked status is being
+ // updated. So, wait for it to finish updating.
+ await TestUtils.waitForCondition(
+ () => BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING
+ );
+ await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" "));
+ await focused;
+ ok(true, "Focus inside edit bookmark panel after Bookmark button pressed");
+ let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
+ EventUtils.synthesizeKey("KEY_Escape");
+ await hidden;
+ });
});
// Test activation of the Bookmarks Menu button from the keyboard.
@@ -302,33 +294,24 @@ add_task(async function testDownloadsButtonPress() {
// with a browser element to embed the pocket UI into it.
// The Pocket panel should appear and focus should move inside it.
add_task(async function testPocketButtonPress() {
- await BrowserTestUtils.withNewTab(
- "https://example.com",
- async function (aBrowser) {
- let button = document.getElementById("save-to-pocket-button");
- // The panel is created on the fly, so we can't simply wait for focus
- // inside it.
- let showing = BrowserTestUtils.waitForEvent(
- document,
- "popupshowing",
- true
- );
- await focusAndActivateElement(button, () =>
- EventUtils.synthesizeKey(" ")
- );
- let event = await showing;
- let panel = event.target;
- is(panel.id, "customizationui-widget-panel");
- let focused = BrowserTestUtils.waitForEvent(panel, "focus", true);
- await focused;
- is(
- document.activeElement.tagName,
- "browser",
- "Focus inside Pocket panel after Bookmark button pressed"
- );
- let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
- EventUtils.synthesizeKey("KEY_Escape");
- await hidden;
- }
- );
+ await BrowserTestUtils.withNewTab("https://example.com", async function () {
+ let button = document.getElementById("save-to-pocket-button");
+ // The panel is created on the fly, so we can't simply wait for focus
+ // inside it.
+ let showing = BrowserTestUtils.waitForEvent(document, "popupshowing", true);
+ await focusAndActivateElement(button, () => EventUtils.synthesizeKey(" "));
+ let event = await showing;
+ let panel = event.target;
+ is(panel.id, "customizationui-widget-panel");
+ let focused = BrowserTestUtils.waitForEvent(panel, "focus", true);
+ await focused;
+ is(
+ document.activeElement.tagName,
+ "browser",
+ "Focus inside Pocket panel after Bookmark button pressed"
+ );
+ let hidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
+ EventUtils.synthesizeKey("KEY_Escape");
+ await hidden;
+ });
});
diff --git a/browser/base/content/test/metaTags/browser_bad_meta_tags.js b/browser/base/content/test/metaTags/browser_bad_meta_tags.js
index 00cc128ec0..aa025725dc 100644
--- a/browser/base/content/test/metaTags/browser_bad_meta_tags.js
+++ b/browser/base/content/test/metaTags/browser_bad_meta_tags.js
@@ -9,11 +9,12 @@ const TEST_PATH =
) + "bad_meta_tags.html";
/**
- * This tests that with the page bad_meta_tags.html, ContentMetaHandler.jsm parses
- * out the meta tags available and does not store content provided by a malformed
- * meta tag. In this case the best defined meta tags are malformed, so here we
- * test that we store the next best ones - "description" and "twitter:image". The
- * list of meta tags and order of preference is found in ContentMetaHandler.jsm.
+ * This tests that with the page bad_meta_tags.html, ContentMetaHandler.sys.mjs
+ * parses out the meta tags available and does not store content provided by a
+ * malformed meta tag. In this case the best defined meta tags are malformed, so
+ * here we test that we store the next best ones - "description" and "twitter:image".
+ * The list of meta tags and order of preference is found in
+ * ContentMetaHandler.sys.mjs.
*/
add_task(async function test_bad_meta_tags() {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH);
diff --git a/browser/base/content/test/metaTags/browser_meta_tags.js b/browser/base/content/test/metaTags/browser_meta_tags.js
index 380a71214c..870860dc18 100644
--- a/browser/base/content/test/metaTags/browser_meta_tags.js
+++ b/browser/base/content/test/metaTags/browser_meta_tags.js
@@ -8,11 +8,11 @@ const TEST_PATH =
"https://example.com"
) + "meta_tags.html";
/**
- * This tests that with the page meta_tags.html, ContentMetaHandler.jsm parses
- * out the meta tags avilable and only stores the best one for description and
- * one for preview image url. In the case of this test, the best defined meta
+ * This tests that with the page meta_tags.html, ContentMetaHandler.sys.mjs
+ * parses out the meta tags avilable and only stores the best one for description
+ * and one for preview image url. In the case of this test, the best defined meta
* tags are "og:description" and "og:image:secure_url". The list of meta tags
- * and order of preference is found in ContentMetaHandler.jsm.
+ * and order of preference is found in ContentMetaHandler.sys.mjs.
*/
add_task(async function test_metadata() {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH);
diff --git a/browser/base/content/test/outOfProcess/browser_basic_outofprocess.js b/browser/base/content/test/outOfProcess/browser_basic_outofprocess.js
index 50914a286c..41fc96986e 100644
--- a/browser/base/content/test/outOfProcess/browser_basic_outofprocess.js
+++ b/browser/base/content/test/outOfProcess/browser_basic_outofprocess.js
@@ -121,12 +121,9 @@ add_task(async function test_subframes_function() {
let browser = tab.linkedBrowser;
let counter = 0;
- let browsingContexts = await initChildFrames(
- browser,
- function (browsingContext) {
- return "<p>Text " + ++counter + "</p>";
- }
- );
+ let browsingContexts = await initChildFrames(browser, function () {
+ return "<p>Text " + ++counter + "</p>";
+ });
is(
counter,
diff --git a/browser/base/content/test/pageActions/head.js b/browser/base/content/test/pageActions/head.js
index cd269bf9b5..370f01734c 100644
--- a/browser/base/content/test/pageActions/head.js
+++ b/browser/base/content/test/pageActions/head.js
@@ -124,7 +124,7 @@ async function promiseAnimationFrame(win = window) {
async function promisePopupNotShown(id, win = window) {
let deferred = Promise.withResolvers();
- function listener(e) {
+ function listener() {
deferred.reject("Unexpected popupshown");
}
let panel = win.document.getElementById(id);
diff --git a/browser/base/content/test/pageinfo/browser.toml b/browser/base/content/test/pageinfo/browser.toml
index ae70eb68ff..9e14392450 100644
--- a/browser/base/content/test/pageinfo/browser.toml
+++ b/browser/base/content/test/pageinfo/browser.toml
@@ -5,7 +5,7 @@ support-files = [
"image.html",
"../general/audio.ogg",
"../general/moz.png",
- "../general/video.ogg",
+ "../general/video.webm",
]
["browser_pageinfo_iframe_media.js"]
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js b/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
index 354e85a241..dbd5d8fe25 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
@@ -76,7 +76,7 @@ async function test() {
// Pass a dummy imageElement, if there isn't an imageElement, pageInfo.js
// will do a preview, however this sometimes will cause intermittent failures,
// see bug 1403365.
- let pageInfo = BrowserPageInfo(url, "mediaTab", {});
+ let pageInfo = BrowserCommands.pageInfo(url, "mediaTab", {});
info("waitForEvent pageInfo");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_iframe_media.js b/browser/base/content/test/pageinfo/browser_pageinfo_iframe_media.js
index 7550379ad1..3dad0a50f3 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_iframe_media.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_iframe_media.js
@@ -10,7 +10,7 @@ add_task(async function test_all_images_mentioned() {
await BrowserTestUtils.withNewTab(
TEST_PATH + "iframes.html",
async function () {
- let pageInfo = BrowserPageInfo(
+ let pageInfo = BrowserCommands.pageInfo(
gBrowser.selectedBrowser.currentURI.spec,
"mediaTab"
);
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js b/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js
index 374cd5f032..0fea68d640 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_image_info.js
@@ -28,7 +28,7 @@ add_task(async function () {
};
});
- let pageInfo = BrowserPageInfo(
+ let pageInfo = BrowserCommands.pageInfo(
browser.currentURI.spec,
"mediaTab",
imageInfo
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_images.js b/browser/base/content/test/pageinfo/browser_pageinfo_images.js
index e1f71204d0..c356c1c690 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_images.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_images.js
@@ -10,7 +10,7 @@ add_task(async function test_all_images_mentioned() {
await BrowserTestUtils.withNewTab(
TEST_PATH + "all_images.html",
async function () {
- let pageInfo = BrowserPageInfo(
+ let pageInfo = BrowserCommands.pageInfo(
gBrowser.selectedBrowser.currentURI.spec,
"mediaTab"
);
@@ -97,7 +97,7 @@ add_task(async function test_image_size() {
await BrowserTestUtils.withNewTab(
TEST_PATH + "all_images.html",
async function () {
- let pageInfo = BrowserPageInfo(
+ let pageInfo = BrowserCommands.pageInfo(
gBrowser.selectedBrowser.currentURI.spec,
"mediaTab"
);
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_permissions.js b/browser/base/content/test/pageinfo/browser_pageinfo_permissions.js
index ebf027811d..6b11ac19b9 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_permissions.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_permissions.js
@@ -7,8 +7,8 @@ const TEST_ORIGIN_CERT_ERROR = "https://expired.example.com";
const LOW_TLS_VERSION = "https://tls1.example.com/";
async function testPermissions(defaultPermission) {
- await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function (browser) {
- let pageInfo = BrowserPageInfo(TEST_ORIGIN, "permTab");
+ await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function () {
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let defaultCheckbox = await TestUtils.waitForCondition(() =>
@@ -94,7 +94,7 @@ add_task(async function test_CertificateError() {
await pageLoaded;
- let pageInfo = BrowserPageInfo(TEST_ORIGIN_CERT_ERROR, "permTab");
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN_CERT_ERROR, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let permissionTab = pageInfo.document.getElementById("permTab");
await TestUtils.waitForCondition(
@@ -145,7 +145,7 @@ add_task(async function test_NetworkError() {
await pageLoaded;
- let pageInfo = BrowserPageInfo(LOW_TLS_VERSION, "permTab");
+ let pageInfo = BrowserCommands.pageInfo(LOW_TLS_VERSION, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let permissionTab = pageInfo.document.getElementById("permTab");
await TestUtils.waitForCondition(
@@ -192,8 +192,8 @@ add_task(async function test_default_geo_permission() {
// Test special behavior for cookie permissions.
add_task(async function test_cookie_permission() {
- await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function (browser) {
- let pageInfo = BrowserPageInfo(TEST_ORIGIN, "permTab");
+ await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function () {
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN, "permTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let defaultCheckbox = await TestUtils.waitForCondition(() =>
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_rtl.js b/browser/base/content/test/pageinfo/browser_pageinfo_rtl.js
index d0c06a03ff..677a58516e 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_rtl.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_rtl.js
@@ -1,18 +1,15 @@
async function testPageInfo() {
- await BrowserTestUtils.withNewTab(
- "https://example.com",
- async function (browser) {
- let pageInfo = BrowserPageInfo();
- await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
- is(
- getComputedStyle(pageInfo.document.documentElement).direction,
- "rtl",
- "Should be RTL"
- );
- ok(true, "Didn't assert or crash");
- pageInfo.close();
- }
- );
+ await BrowserTestUtils.withNewTab("https://example.com", async function () {
+ let pageInfo = BrowserCommands.pageInfo();
+ await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
+ is(
+ getComputedStyle(pageInfo.document.documentElement).direction,
+ "rtl",
+ "Should be RTL"
+ );
+ ok(true, "Didn't assert or crash");
+ pageInfo.close();
+ });
}
add_task(async function test_page_info_rtl() {
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_security.js b/browser/base/content/test/pageinfo/browser_pageinfo_security.js
index 47df97db06..17ff0b9b75 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_security.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_security.js
@@ -24,7 +24,7 @@ add_task(async function test_ShowCertificate() {
TEST_SUB_ORIGIN
);
- let pageInfo = BrowserPageInfo(TEST_SUB_ORIGIN, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(TEST_SUB_ORIGIN, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -74,7 +74,7 @@ add_task(async function test_image() {
let url = TEST_PATH + "moz.png";
await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
- let pageInfo = BrowserPageInfo(url, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(url, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -128,7 +128,10 @@ add_task(async function test_CertificateError() {
await pageLoaded;
- let pageInfo = BrowserPageInfo(TEST_ORIGIN_CERT_ERROR, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(
+ TEST_ORIGIN_CERT_ERROR,
+ "securityTab"
+ );
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -165,7 +168,7 @@ add_task(async function test_CertificateError() {
add_task(async function test_SecurityHTTP() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_HTTP_ORIGIN);
- let pageInfo = BrowserPageInfo(TEST_HTTP_ORIGIN, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(TEST_HTTP_ORIGIN, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -201,7 +204,7 @@ add_task(async function test_SecurityHTTP() {
add_task(async function test_ValidCert() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_ORIGIN);
- let pageInfo = BrowserPageInfo(TEST_ORIGIN, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -237,11 +240,11 @@ add_task(async function test_ValidCert() {
add_task(async function test_SiteData() {
await SiteDataTestUtils.addToIndexedDB(TEST_ORIGIN);
- await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function (browser) {
+ await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function () {
let totalUsage = await SiteDataTestUtils.getQuotaUsage(TEST_ORIGIN);
Assert.greater(totalUsage, 0, "The total usage should not be 0");
- let pageInfo = BrowserPageInfo(TEST_ORIGIN, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
@@ -302,8 +305,8 @@ add_task(async function test_Cookies() {
value: "1",
});
- await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function (browser) {
- let pageInfo = BrowserPageInfo(TEST_ORIGIN, "securityTab");
+ await BrowserTestUtils.withNewTab(TEST_ORIGIN, async function () {
+ let pageInfo = BrowserCommands.pageInfo(TEST_ORIGIN, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_separate_private.js b/browser/base/content/test/pageinfo/browser_pageinfo_separate_private.js
index ac93b7ddb2..74289107a8 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_separate_private.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_separate_private.js
@@ -9,7 +9,7 @@ add_task(async function () {
"https://example.com"
);
let browser = tab.linkedBrowser;
- let pageInfo = BrowserPageInfo(browser.currentURI.spec);
+ let pageInfo = BrowserCommands.pageInfo(browser.currentURI.spec);
await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init");
Assert.strictEqual(
pageInfo.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing,
@@ -25,7 +25,7 @@ add_task(async function () {
"https://example.com"
);
let privateBrowser = privateTab.linkedBrowser;
- let privatePageInfo = privateWindow.BrowserPageInfo(
+ let privatePageInfo = privateWindow.BrowserCommands.pageInfo(
privateBrowser.currentURI.spec
);
await BrowserTestUtils.waitForEvent(privatePageInfo, "page-info-init");
diff --git a/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js b/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js
index 3934cd2aea..b00df72851 100644
--- a/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_svg_image.js
@@ -7,7 +7,7 @@ add_task(async function () {
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, URI);
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, URI);
- const pageInfo = BrowserPageInfo(
+ const pageInfo = BrowserCommands.pageInfo(
gBrowser.selectedBrowser.currentURI.spec,
"mediaTab"
);
diff --git a/browser/base/content/test/pageinfo/image.html b/browser/base/content/test/pageinfo/image.html
index 1261be8e7b..35e2d78e1e 100644
--- a/browser/base/content/test/pageinfo/image.html
+++ b/browser/base/content/test/pageinfo/image.html
@@ -1,5 +1,5 @@
<html>
<img src='moz.png' height=100 width=150 id='test-image'>
- <video src='video.ogg' id='test-video'></video>
+ <video src='video.webm' id='test-video'></video>
<audio src='audio.ogg' id='test-audio'></audio>
</html>
diff --git a/browser/base/content/test/performance/StartupContentSubframe.sys.mjs b/browser/base/content/test/performance/StartupContentSubframe.sys.mjs
index a78e456afb..7d2d711765 100644
--- a/browser/base/content/test/performance/StartupContentSubframe.sys.mjs
+++ b/browser/base/content/test/performance/StartupContentSubframe.sys.mjs
@@ -16,7 +16,7 @@ export class StartupContentSubframeParent extends JSWindowActorParent {
}
export class StartupContentSubframeChild extends JSWindowActorChild {
- async handleEvent(event) {
+ async handleEvent() {
// When the remote subframe is loaded, an event will be fired to this actor,
// which will cause us to send the `LoadedScripts` message to the parent
// process.
diff --git a/browser/base/content/test/performance/browser_preferences_usage.js b/browser/base/content/test/performance/browser_preferences_usage.js
index 6bc623a360..9ad9a8dde8 100644
--- a/browser/base/content/test/performance/browser_preferences_usage.js
+++ b/browser/base/content/test/performance/browser_preferences_usage.js
@@ -70,13 +70,6 @@ function checkPrefGetters(stats, max, knownProblematicPrefs = {}) {
}
}
- // This pref will be accessed by mozJSComponentLoader when loading modules,
- // which fails TV runs since they run the test multiple times without restarting.
- // We just ignore this pref, since it's for testing only anyway.
- if (knownProblematicPrefs["browser.startup.record"]) {
- delete knownProblematicPrefs["browser.startup.record"];
- }
-
let unusedPrefs = Object.keys(knownProblematicPrefs);
is(
unusedPrefs.length,
@@ -104,18 +97,9 @@ add_task(async function startup() {
let max = 40;
let knownProblematicPrefs = {
- "browser.startup.record": {
- // This pref is accessed in Nighly and debug builds only.
- min: 200,
- max: 400,
- },
"network.loadinfo.skip_type_assertion": {
// This is accessed in debug only.
},
- "chrome.override_package.global": {
- min: 0,
- max: 50,
- },
};
let startupRecorder =
@@ -135,9 +119,6 @@ add_task(async function open_10_tabs() {
const max = 4 * DEFAULT_PROCESS_COUNT;
let knownProblematicPrefs = {
- "browser.startup.record": {
- max: 20,
- },
"browser.tabs.remote.logSwitchTiming": {
max: 35,
},
diff --git a/browser/base/content/test/performance/browser_startup_content.js b/browser/base/content/test/performance/browser_startup_content.js
index b0f861e47f..fac82ad990 100644
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -57,18 +57,11 @@ const known_scripts = {
]),
};
-if (!Services.appinfo.sessionHistoryInParent) {
- known_scripts.modules.add(
- "resource:///modules/sessionstore/ContentSessionStore.sys.mjs"
- );
-}
-
// Items on this list *might* load when creating the process, as opposed to
// items in the main list, which we expect will always load.
const intermittently_loaded_scripts = {
modules: new Set([
"resource://gre/modules/nsAsyncShutdown.sys.mjs",
- "resource://gre/modules/sessionstore/Utils.sys.mjs",
// Translations code which may be preffed on.
"resource://gre/actors/TranslationsChild.sys.mjs",
@@ -119,7 +112,8 @@ add_task(async function () {
let mm = gBrowser.selectedBrowser.messageManager;
let promise = BrowserTestUtils.waitForMessage(mm, "Test:LoadedScripts");
- // Load a custom frame script to avoid using ContentTask which loads Task.jsm
+ // Load a custom frame script to avoid using SpecialPowers.spawn which may
+ // load other modules.
mm.loadFrameScript(
"data:text/javascript,(" +
function () {
diff --git a/browser/base/content/test/performance/browser_startup_mainthreadio.js b/browser/base/content/test/performance/browser_startup_mainthreadio.js
index b65ede26d5..a89a068f13 100644
--- a/browser/base/content/test/performance/browser_startup_mainthreadio.js
+++ b/browser/base/content/test/performance/browser_startup_mainthreadio.js
@@ -189,6 +189,7 @@ const startupPhases = {
{
// bug 1541601
path: "PrfDef:channel-prefs.js",
+ condition: !MAC,
stat: 1,
read: 1,
close: 1,
diff --git a/browser/base/content/test/performance/browser_tabdetach.js b/browser/base/content/test/performance/browser_tabdetach.js
index a860362f1f..3cbdde50fc 100644
--- a/browser/base/content/test/performance/browser_tabdetach.js
+++ b/browser/base/content/test/performance/browser_tabdetach.js
@@ -59,7 +59,7 @@ add_task(async function test_detach_not_overflowed() {
expectedReflows: EXPECTED_REFLOWS,
// we are opening a whole new window, so there's no point in tracking
// rects being painted
- frames: { filter: rects => [] },
+ frames: { filter: () => [] },
}
);
@@ -87,7 +87,7 @@ add_task(async function test_detach_overflowed() {
expectedReflows: EXPECTED_REFLOWS,
// we are opening a whole new window, so there's no point in tracking
// rects being painted
- frames: { filter: rects => [] },
+ frames: { filter: () => [] },
}
);
diff --git a/browser/base/content/test/performance/browser_tabopen.js b/browser/base/content/test/performance/browser_tabopen.js
index 2457812cb7..b7eabf4844 100644
--- a/browser/base/content/test/performance/browser_tabopen.js
+++ b/browser/base/content/test/performance/browser_tabopen.js
@@ -144,7 +144,7 @@ add_task(async function () {
await withPerfObserver(
async function () {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
- BrowserOpenTab();
+ BrowserCommands.openTab();
await BrowserTestUtils.waitForEvent(
gBrowser.selectedTab,
"TabAnimationEnd"
diff --git a/browser/base/content/test/performance/browser_tabopen_squeeze.js b/browser/base/content/test/performance/browser_tabopen_squeeze.js
index f92bdc2ea4..dd73f66030 100644
--- a/browser/base/content/test/performance/browser_tabopen_squeeze.js
+++ b/browser/base/content/test/performance/browser_tabopen_squeeze.js
@@ -52,7 +52,7 @@ add_task(async function () {
await withPerfObserver(
async function () {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
- BrowserOpenTab();
+ BrowserCommands.openTab();
await BrowserTestUtils.waitForEvent(
gBrowser.selectedTab,
"TabAnimationEnd"
diff --git a/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js b/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
index 1fd33ed836..50d108c062 100644
--- a/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
+++ b/browser/base/content/test/performance/browser_tabstrip_overflow_underflow.js
@@ -90,7 +90,7 @@ add_task(async function () {
await withPerfObserver(
async function () {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
- BrowserOpenTab();
+ BrowserCommands.openTab();
await BrowserTestUtils.waitForEvent(
gBrowser.selectedTab,
"TabAnimationEnd"
@@ -115,7 +115,7 @@ add_task(async function () {
await withPerfObserver(
async function () {
let switchDone = BrowserTestUtils.waitForEvent(window, "TabSwitchDone");
- BrowserOpenTab();
+ BrowserCommands.openTab();
await switchDone;
await TestUtils.waitForCondition(() => {
return gBrowser.tabContainer.arrowScrollbox.hasAttribute(
diff --git a/browser/base/content/test/performance/browser_tabswitch.js b/browser/base/content/test/performance/browser_tabswitch.js
index bbbbac3a21..ba29efa662 100644
--- a/browser/base/content/test/performance/browser_tabswitch.js
+++ b/browser/base/content/test/performance/browser_tabswitch.js
@@ -59,6 +59,14 @@ add_task(async function () {
getComputedStyle(gBrowser.selectedTab).paddingInlineStart
);
let minTabWidth = firstTabRect.width - 2 * tabPaddingStart;
+ if (AppConstants.platform == "macosx") {
+ // On macOS, after bug 1886729, gecko screenshots like the ones for this
+ // test can't screenshot the native titlebar. That, plus the fact that
+ // there's no border or shadow (see bug 1702653) means that we only end up
+ // with the tab text color changing, which is smaller than the tab
+ // background size.
+ minTabWidth = 0;
+ }
let maxTabWidth = firstTabRect.width;
let inRange = (val, min, max) => min <= val && val <= max;
@@ -84,11 +92,7 @@ add_task(async function () {
// The tab selection changes between 2 adjacent tabs, so we expect
// both to change color at once: this should be a single rect of the
// width of 2 tabs.
- inRange(
- r.w,
- minTabWidth - 1, // -1 for the border on Win7
- maxTabWidth * 2
- )
+ inRange(r.w, minTabWidth, maxTabWidth * 2)
)
)
),
diff --git a/browser/base/content/test/performance/browser_windowclose.js b/browser/base/content/test/performance/browser_windowclose.js
index 7d11779acc..11fa669be0 100644
--- a/browser/base/content/test/performance/browser_windowclose.js
+++ b/browser/base/content/test/performance/browser_windowclose.js
@@ -53,7 +53,7 @@ add_task(async function () {
{
expectedReflows: EXPECTED_REFLOWS,
frames: {
- filter(rects, frame, previousFrame) {
+ filter(rects, frame) {
// Ignore the focus-out animation.
if (isLikelyFocusChange(rects, frame)) {
return [];
diff --git a/browser/base/content/test/performance/browser_windowopen.js b/browser/base/content/test/performance/browser_windowopen.js
index 02c6172948..b258cb67f5 100644
--- a/browser/base/content/test/performance/browser_windowopen.js
+++ b/browser/base/content/test/performance/browser_windowopen.js
@@ -44,7 +44,7 @@ add_task(async function () {
let expectations = {
expectedReflows: EXPECTED_REFLOWS,
frames: {
- filter(rects, frame, previousFrame) {
+ filter(rects, frame) {
// The first screenshot we get in OSX / Windows shows an unfocused browser
// window for some reason. See bug 1445161.
if (!alreadyFocused && isLikelyFocusChange(rects, frame)) {
diff --git a/browser/base/content/test/performance/head.js b/browser/base/content/test/performance/head.js
index 29722e6bbe..42f7ae95fc 100644
--- a/browser/base/content/test/performance/head.js
+++ b/browser/base/content/test/performance/head.js
@@ -42,7 +42,7 @@ async function recordReflows(testPromise, win = window) {
let reflows = [];
let observer = {
- reflow(start, end) {
+ reflow() {
// Gather information about the current code path.
reflows.push(new Error().stack);
@@ -50,7 +50,7 @@ async function recordReflows(testPromise, win = window) {
dirtyFrame(win);
},
- reflowInterruptible(start, end) {
+ reflowInterruptible() {
// Interruptible reflows are the reflows caused by the refresh
// driver ticking. These are fine.
},
@@ -99,11 +99,9 @@ async function recordReflows(testPromise, win = window) {
* // Sometimes, due to unpredictable timings, the reflow may be hit
* // less times.
* stack: [
- * "select@chrome://global/content/bindings/textbox.xml",
- * "focusAndSelectUrlBar@chrome://browser/content/browser.js",
- * "openLinkIn@chrome://browser/content/utilityOverlay.js",
- * "openUILinkIn@chrome://browser/content/utilityOverlay.js",
- * "BrowserOpenTab@chrome://browser/content/browser.js",
+ * "somefunction@chrome://somepackage/content/somefile.mjs",
+ * "otherfunction@chrome://otherpackage/content/otherfile.js",
+ * "morecode@resource://somewhereelse/SomeModule.sys.mjs",
* ],
* // We expect this particular reflow to happen up to 2 times.
* maxCount: 2,
@@ -113,10 +111,9 @@ async function recordReflows(testPromise, win = window) {
* // This reflow is caused by lorem ipsum. We expect this reflow
* // to only happen once, so we can omit the "maxCount" property.
* stack: [
- * "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml",
- * "_fillTrailingGap@chrome://browser/content/tabbrowser.xml",
- * "_handleNewTab@chrome://browser/content/tabbrowser.xml",
- * "onxbltransitionend@chrome://browser/content/tabbrowser.xml",
+ * "somefunction@chrome://somepackage/content/somefile.mjs",
+ * "otherfunction@chrome://otherpackage/content/otherfile.js",
+ * "morecode@resource://somewhereelse/SomeModule.sys.mjs",
* ],
* }
* ]
@@ -430,7 +427,7 @@ async function recordFrames(testPromise, win = window) {
let frames = [];
- let afterPaintListener = event => {
+ let afterPaintListener = () => {
let width, height;
canvas.width = width = win.innerWidth;
canvas.height = height = win.innerHeight;
diff --git a/browser/base/content/test/permissions/browser_autoplay_blocked.js b/browser/base/content/test/permissions/browser_autoplay_blocked.js
index d81481d6a5..7fd45a4340 100644
--- a/browser/base/content/test/permissions/browser_autoplay_blocked.js
+++ b/browser/base/content/test/permissions/browser_autoplay_blocked.js
@@ -102,7 +102,7 @@ add_task(async function testMainViewVisible() {
Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
- await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function (browser) {
+ await BrowserTestUtils.withNewTab(AUTOPLAY_PAGE, async function () {
let permissionsList = document.getElementById(
"permission-popup-permission-list"
);
diff --git a/browser/base/content/test/permissions/browser_canvas_fingerprinting_resistance.js b/browser/base/content/test/permissions/browser_canvas_fingerprinting_resistance.js
index dbb2d1ea32..62a49e359c 100644
--- a/browser/base/content/test/permissions/browser_canvas_fingerprinting_resistance.js
+++ b/browser/base/content/test/permissions/browser_canvas_fingerprinting_resistance.js
@@ -336,7 +336,7 @@ async function withNewTabInput(
await SpecialPowers.spawn(browser, [], initTab);
await enableResistFingerprinting(randomDataOnCanvasExtract, true);
let popupShown = promisePopupShown();
- await SpecialPowers.spawn(browser, [], function (host) {
+ await SpecialPowers.spawn(browser, [], function () {
E10SUtils.wrapHandlingUserInput(content, true, function () {
var button = content.document.getElementById("clickme");
button.click();
@@ -361,11 +361,7 @@ async function withNewTabInput(
await SpecialPowers.popPrefEnv();
}
-async function doTestInput(
- randomDataOnCanvasExtract,
- grantPermission,
- autoDeclineNoInput
-) {
+async function doTestInput(randomDataOnCanvasExtract, grantPermission) {
await BrowserTestUtils.withNewTab(
kUrl,
withNewTabInput.bind(null, randomDataOnCanvasExtract, grantPermission)
diff --git a/browser/base/content/test/permissions/browser_site_scoped_permissions.js b/browser/base/content/test/permissions/browser_site_scoped_permissions.js
index 7a8953de47..949d7a0596 100644
--- a/browser/base/content/test/permissions/browser_site_scoped_permissions.js
+++ b/browser/base/content/test/permissions/browser_site_scoped_permissions.js
@@ -21,7 +21,7 @@ add_task(async function testSiteScopedPermissionSubdomainAffectsBaseDomain() {
);
let id = "3rdPartyStorage^https://example.org";
- await BrowserTestUtils.withNewTab(EMPTY_PAGE, async function (browser) {
+ await BrowserTestUtils.withNewTab(EMPTY_PAGE, async function () {
Services.perms.addFromPrincipal(
subdomainPrincipal,
id,
@@ -76,49 +76,46 @@ add_task(async function testSiteScopedPermissionBaseDomainAffectsSubdomain() {
Services.scriptSecurityManager.createContentPrincipalFromOrigin(origin);
let id = "3rdPartyStorage^https://example.org";
- await BrowserTestUtils.withNewTab(
- SUBDOMAIN_EMPTY_PAGE,
- async function (browser) {
- Services.perms.addFromPrincipal(principal, id, SitePermissions.ALLOW);
- await openPermissionPopup();
-
- let permissionsList = document.getElementById(
- "permission-popup-permission-list"
- );
- let listEntryCount = permissionsList.querySelectorAll(
- ".permission-popup-permission-item"
- ).length;
- is(
- listEntryCount,
- 1,
- "Permission exists on base domain when set on subdomain"
- );
-
- closePermissionPopup();
-
- Services.perms.removeFromPrincipal(principal, id);
-
- // We intentionally turn off a11y_checks, because the following function
- // is expected to click a toolbar button that may be already hidden
- // with "display:none;". The permissions panel anchor is hidden because
- // the last permission was removed, however we force opening the panel
- // anyways in order to test that the list has been properly emptied:
- AccessibilityUtils.setEnv({
- mustHaveAccessibleRule: false,
- });
- await openPermissionPopup();
- AccessibilityUtils.resetEnv();
-
- listEntryCount = permissionsList.querySelectorAll(
- ".permission-popup-permission-item-3rdPartyStorage"
- ).length;
- is(
- listEntryCount,
- 0,
- "Permission removed on base domain when removed on subdomain"
- );
-
- await closePermissionPopup();
- }
- );
+ await BrowserTestUtils.withNewTab(SUBDOMAIN_EMPTY_PAGE, async function () {
+ Services.perms.addFromPrincipal(principal, id, SitePermissions.ALLOW);
+ await openPermissionPopup();
+
+ let permissionsList = document.getElementById(
+ "permission-popup-permission-list"
+ );
+ let listEntryCount = permissionsList.querySelectorAll(
+ ".permission-popup-permission-item"
+ ).length;
+ is(
+ listEntryCount,
+ 1,
+ "Permission exists on base domain when set on subdomain"
+ );
+
+ closePermissionPopup();
+
+ Services.perms.removeFromPrincipal(principal, id);
+
+ // We intentionally turn off a11y_checks, because the following function
+ // is expected to click a toolbar button that may be already hidden
+ // with "display:none;". The permissions panel anchor is hidden because
+ // the last permission was removed, however we force opening the panel
+ // anyways in order to test that the list has been properly emptied:
+ AccessibilityUtils.setEnv({
+ mustHaveAccessibleRule: false,
+ });
+ await openPermissionPopup();
+ AccessibilityUtils.resetEnv();
+
+ listEntryCount = permissionsList.querySelectorAll(
+ ".permission-popup-permission-item-3rdPartyStorage"
+ ).length;
+ is(
+ listEntryCount,
+ 0,
+ "Permission removed on base domain when removed on subdomain"
+ );
+
+ await closePermissionPopup();
+ });
});
diff --git a/browser/base/content/test/permissions/browser_temporary_permissions_navigation.js b/browser/base/content/test/permissions/browser_temporary_permissions_navigation.js
index 7da79b1810..490da04374 100644
--- a/browser/base/content/test/permissions/browser_temporary_permissions_navigation.js
+++ b/browser/base/content/test/permissions/browser_temporary_permissions_navigation.js
@@ -41,7 +41,7 @@ add_task(async function testTempPermissionOnReload() {
reloaded = BrowserTestUtils.browserLoaded(browser, false, origin);
// Reload as a user (should remove the temp permission).
- BrowserReload();
+ BrowserCommands.reload();
await reloaded;
diff --git a/browser/base/content/test/plugins/head.js b/browser/base/content/test/plugins/head.js
index 4f6c25b92a..76f87dfc43 100644
--- a/browser/base/content/test/plugins/head.js
+++ b/browser/base/content/test/plugins/head.js
@@ -147,7 +147,7 @@ function promiseWaitForFocus(aWindow) {
* @return Promise
*/
function waitForNotificationBar(notificationID, browser, callback) {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let notification;
let notificationBox = gBrowser.getNotificationBox(browser);
waitForCondition(
@@ -189,7 +189,7 @@ function waitForNotificationShown(notification, callback) {
}
PopupNotifications.panel.addEventListener(
"popupshown",
- function (e) {
+ function () {
callback();
},
{ once: true }
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification.js b/browser/base/content/test/popupNotifications/browser_popupNotification.js
index 235aa90b5f..4479cb1ee7 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification.js
@@ -26,7 +26,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerMainCommand(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(this.notifyObj.mainActionClicked, "mainAction was clicked");
ok(
!this.notifyObj.dismissalCallbackTriggered,
@@ -55,7 +55,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
ok(
!this.notifyObj.dismissalCallbackTriggered,
@@ -89,7 +89,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 1);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.extraSecondaryActionClicked,
"extra secondary action was clicked"
@@ -123,7 +123,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 2);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.extraSecondaryActionClicked,
"extra secondary action was clicked"
@@ -145,7 +145,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback triggered"
@@ -205,7 +205,7 @@ var tests = [
// switch back to the old browser
gBrowser.selectedTab = this.oldSelectedTab;
},
- onHidden(popup) {
+ onHidden() {
// actually remove the notification to prevent it from reappearing
ok(
wrongBrowserNotificationObject.dismissalCallbackTriggered,
@@ -247,7 +247,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
this.notification2.remove();
},
- onHidden(popup) {
+ onHidden() {
ok(
!this.notifyObj.dismissalCallbackTriggered,
"dismissal callback wasn't triggered"
@@ -276,7 +276,7 @@ var tests = [
is(popup.children.length, 1, "only one notification left");
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(this.testNotif1.mainActionClicked, "main action #1 was clicked");
ok(
!this.testNotif1.secondaryActionClicked,
@@ -316,7 +316,7 @@ var tests = [
);
triggerMainCommand(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
ok(
!this.notifyObj.dismissalCallbackTriggered,
@@ -348,7 +348,7 @@ var tests = [
);
triggerMainCommand(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
ok(
!this.notifyObj.dismissalCallbackTriggered,
@@ -380,7 +380,7 @@ var tests = [
);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
// Remove the notifications
this.firstNotification.remove();
this.secondNotification.remove();
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
index 8738a3b605..1b0dea66f6 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
@@ -24,7 +24,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback triggered"
@@ -52,7 +52,7 @@ var tests = [
);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
let icon = document.getElementById("geo-notification-icon");
isnot(
icon.getBoundingClientRect().width,
@@ -84,7 +84,7 @@ var tests = [
});
this.notification = showNotification(this.notifyObj);
},
- async onShown(popup) {
+ async onShown() {
this.complete = false;
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
@@ -95,7 +95,7 @@ var tests = [
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
},
- onHidden(popup) {
+ onHidden() {
ok(
this.complete,
"Should only have hidden the notification after 3 page loads"
@@ -122,7 +122,7 @@ var tests = [
});
this.notification = showNotification(this.notifyObj);
},
- async onShown(popup) {
+ async onShown() {
this.complete = false;
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
@@ -134,7 +134,7 @@ var tests = [
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
},
- onHidden(popup) {
+ onHidden() {
ok(
this.complete,
"Should only have hidden the notification after the timeout was passed"
@@ -172,7 +172,7 @@ var tests = [
this.complete = true;
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.complete,
"Should only have hidden the notification after it was dismissed"
@@ -212,7 +212,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification.remove();
this.box.remove();
},
@@ -272,7 +272,7 @@ var tests = [
let notification = popup.children[0];
EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback triggered"
@@ -302,7 +302,7 @@ var tests = [
);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback triggered"
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_3.js b/browser/base/content/test/popupNotifications/browser_popupNotification_3.js
index 1b7626c660..1d8b6b473b 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_3.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_3.js
@@ -27,7 +27,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
!this.notifyObj.dismissalCallbackTriggered,
"dismissal callback wasn't triggered"
@@ -70,7 +70,7 @@ var tests = [
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification1.remove();
ok(
this.notifyObj1.removedCallbackTriggered,
@@ -127,7 +127,7 @@ var tests = [
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notificationNew.remove();
gBrowser.removeTab(gBrowser.selectedTab);
@@ -156,7 +156,7 @@ var tests = [
dismissNotification(popup);
});
},
- onHidden(popup) {
+ onHidden() {
ok(
!this.notifyObj.mainActionClicked,
"mainAction was not clicked because it was too soon"
@@ -188,7 +188,7 @@ var tests = [
triggerMainCommand(popup);
}, 500);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.mainActionClicked,
"mainAction was clicked after the delay"
@@ -308,7 +308,7 @@ var tests = [
};
showNotification(this.notifyObj);
},
- async onShown(popup) {
+ async onShown() {
info("Adding observer and performing navigation");
await Promise.all([
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
index b0e8f016ef..3ea0e943a3 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
@@ -23,7 +23,7 @@ var tests = [
checkPopup(popup, this.testNotif);
triggerMainCommand(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(this.testNotif.mainActionClicked, "main action has been triggered");
},
},
@@ -38,7 +38,7 @@ var tests = [
checkPopup(popup, this.testNotif);
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.testNotif.secondaryActionClicked,
"secondary action has been triggered"
@@ -83,7 +83,7 @@ var tests = [
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification1.remove();
this.notification2.remove();
},
@@ -213,7 +213,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerMainCommand(popup);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback was triggered"
@@ -237,7 +237,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.notifyObj.dismissalCallbackTriggered,
"dismissal callback was triggered"
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_5.js b/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
index 0ec5de0c3a..48640b9b00 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
@@ -62,7 +62,7 @@ var tests = [
this.notification1.remove();
this.notification2.remove();
},
- onHidden(popup) {},
+ onHidden() {},
},
// The anchor icon should be shown for notifications in background windows.
{
@@ -116,7 +116,7 @@ var tests = [
this.complete = true;
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(
!this.complete,
"Should have hidden the notification after navigation"
@@ -155,7 +155,7 @@ var tests = [
this.complete = true;
triggerSecondaryCommand(popup, 0);
},
- onHidden(popup) {
+ onHidden() {
ok(
this.complete,
"Should have hidden the notification after clicking Not Now"
@@ -174,7 +174,7 @@ var tests = [
this.notifyObj.options.persistent = true;
gNotification = showNotification(this.notifyObj);
},
- async onShown(popup) {
+ async onShown() {
this.oldSelectedTab = gBrowser.selectedTab;
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
@@ -182,7 +182,7 @@ var tests = [
"http://example.com/"
);
},
- onHidden(popup) {
+ onHidden() {
ok(true, "Should have hidden the notification after tab switch");
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
@@ -318,7 +318,7 @@ var tests = [
this.notification1.remove();
this.notification2.remove();
},
- onHidden(popup) {},
+ onHidden() {},
},
// Test that persistent notifications are shown stacked by anchor on update
{
@@ -363,7 +363,7 @@ var tests = [
this.notification2.remove();
this.notification3.remove();
},
- onHidden(popup) {},
+ onHidden() {},
},
// Test that on closebutton click, only the persistent notification
// that contained the closebutton loses its persistent status.
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js b/browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js
index 4a68105e27..7e8e3f0269 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js
@@ -36,7 +36,7 @@ var tests = [
// process of being hidden right now.
isnot(popup.state, "hiding", "popup is not hiding");
},
- onHidden(popup) {
+ onHidden() {
window.removeEventListener("command", commandTriggered, true);
ok(buttonPressed, "button pressed");
},
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js b/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js
index 5c20751c3f..bd6fd38d3f 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_keyboard.js
@@ -46,7 +46,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
EventUtils.synthesizeKey("KEY_Escape");
},
- onHidden(popup) {
+ onHidden() {
ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
ok(
@@ -77,7 +77,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
EventUtils.synthesizeKey("KEY_Escape");
},
- onHidden(popup) {
+ onHidden() {
ok(!this.notifyObj.mainActionClicked, "mainAction was not clicked");
ok(
!this.notifyObj.secondaryActionClicked,
@@ -123,7 +123,7 @@ var tests = [
is(document.activeElement, popup.children[0].closebutton);
this.notification.remove();
},
- onHidden(popup) {},
+ onHidden() {},
},
// Test that you can switch between active notifications with the space key
// and that the notification is focused on selection.
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_no_anchors.js b/browser/base/content/test/popupNotifications/browser_popupNotification_no_anchors.js
index a73e1f5948..68e782cea6 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_no_anchors.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_no_anchors.js
@@ -43,7 +43,7 @@ var tests = [
);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
@@ -85,7 +85,7 @@ var tests = [
);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
@@ -135,7 +135,7 @@ var tests = [
checkPopup(popup, this.notifyObj);
dismissNotification(popup);
},
- onHidden(popup) {
+ onHidden() {
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
diff --git a/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js b/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
index 3b027bc1ef..3c652b26a2 100644
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
@@ -44,22 +44,22 @@ add_setup(async function () {
});
});
+/**
+ * The security delay calculation in PopupNotification.sys.mjs is dependent on
+ * the monotonically increasing value of performance.now. This timestamp is
+ * not relative to a fixed date, but to runtime.
+ * We need to wait for the value performance.now() to be larger than the
+ * security delay in order to observe the bug. Only then does the
+ * timeSinceShown check in PopupNotifications.sys.mjs lead to a timeSinceShown
+ * value that is unconditionally greater than lazy.buttonDelay for
+ * notification.timeShown = null = 0.
+ * See: https://searchfox.org/mozilla-central/rev/f32d5f3949a3f4f185122142b29f2e3ab776836e/toolkit/modules/PopupNotifications.sys.mjs#1870-1872
+ *
+ * When running in automation as part of a larger test suite performance.now()
+ * should usually be already sufficiently high in which case this check should
+ * directly resolve.
+ */
async function ensureSecurityDelayReady() {
- /**
- * The security delay calculation in PopupNotification.sys.mjs is dependent on
- * the monotonically increasing value of performance.now. This timestamp is
- * not relative to a fixed date, but to runtime.
- * We need to wait for the value performance.now() to be larger than the
- * security delay in order to observe the bug. Only then does the
- * timeSinceShown check in PopupNotifications.sys.mjs lead to a timeSinceShown
- * value that is unconditionally greater than lazy.buttonDelay for
- * notification.timeShown = null = 0.
- * See: https://searchfox.org/mozilla-central/rev/f32d5f3949a3f4f185122142b29f2e3ab776836e/toolkit/modules/PopupNotifications.sys.mjs#1870-1872
- *
- * When running in automation as part of a larger test suite performance.now()
- * should usually be already sufficiently high in which case this check should
- * directly resolve.
- */
await TestUtils.waitForCondition(
() => performance.now() > TEST_SECURITY_DELAY,
"Wait for performance.now() > SECURITY_DELAY",
@@ -69,73 +69,73 @@ async function ensureSecurityDelayReady() {
}
/**
- * Tests that when we show a second notification while the panel is open the
- * timeShown attribute is correctly set and the security delay is enforced
- * properly.
+ * Test helper for security delay tests which performs the following steps:
+ * 1. Shows a test notification.
+ * 2. Waits for the notification panel to be shown and checks that the initial
+ * security delay blocks clicks.
+ * 3. Waits for the security delay to expire. Clicks should now be allowed.
+ * 4. Executes the provided onSecurityDelayExpired function. This function
+ * should renew the security delay.
+ * 5. Tests that the security delay was renewed.
+ * 6. Ensures that after the security delay the notification can be closed.
+ *
+ * @param {*} options
+ * @param {function} options.onSecurityDelayExpired - Function to run after the
+ * security delay has expired. This function should trigger a renew of the
+ * security delay.
+ * @param {function} options.cleanupFn - Optional cleanup function to run after
+ * the test has completed.
+ * @returns {Promise<void>} - Resolves when the test has completed.
*/
-add_task(async function test_timeShownMultipleNotifications() {
+async function runPopupNotificationSecurityDelayTest({
+ onSecurityDelayExpired,
+ cleanupFn = () => {},
+}) {
await ensureSecurityDelayReady();
- ok(
- !PopupNotifications.isPanelOpen,
- "PopupNotification panel should not be open initially."
- );
-
- info("Open the first notification.");
+ info("Open a notification.");
let popupShownPromise = waitForNotificationPanel();
showNotification();
await popupShownPromise;
ok(
PopupNotifications.isPanelOpen,
- "PopupNotification should be open after first show call."
+ "PopupNotification should be open after show call."
);
- is(
- PopupNotifications._currentNotifications.length,
- 1,
- "There should only be one notification"
+ // Test that the initial security delay works.
+ info(
+ "Trigger main action via button click during the initial security delay."
);
+ triggerMainCommand(PopupNotifications.panel);
+ await new Promise(resolve => setTimeout(resolve, 0));
+
+ ok(PopupNotifications.isPanelOpen, "PopupNotification should still be open.");
let notification = PopupNotifications.getNotification(
"foo",
gBrowser.selectedBrowser
);
- is(notification?.id, "foo", "There should be a notification with id foo");
- ok(notification.timeShown, "The notification should have timeShown set");
-
- info(
- "Call show again with the same notification id while the PopupNotification panel is still open."
- );
- showNotification();
ok(
- PopupNotifications.isPanelOpen,
- "PopupNotification should still open after second show call."
- );
- notification = PopupNotifications.getNotification(
- "foo",
- gBrowser.selectedBrowser
- );
- is(
- PopupNotifications._currentNotifications.length,
- 1,
- "There should still only be one notification"
+ notification,
+ "Notification should still be open because we clicked during the security delay."
);
+ // If the notification is no longer shown (test failure) skip the remaining
+ // checks.
+ if (!notification) {
+ await cleanupFn();
+ return;
+ }
- is(
- notification?.id,
- "foo",
- "There should still be a notification with id foo"
+ info("Wait for security delay to expire.");
+ await new Promise(resolve =>
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ setTimeout(resolve, TEST_SECURITY_DELAY + 500)
);
- ok(notification.timeShown, "The notification should have timeShown set");
- let notificationHiddenPromise = waitForNotificationPanelHidden();
-
- info("Trigger main action via button click during security delay");
-
- // Wait for a tick of the event loop to ensure the button we're clicking
- // has been slotted into moz-button-group
- await new Promise(resolve => setTimeout(resolve, 0));
+ info("Run test specific actions which restarts the security delay.");
+ await onSecurityDelayExpired();
+ info("Trigger main action via button click during the new security delay.");
triggerMainCommand(PopupNotifications.panel);
await new Promise(resolve => setTimeout(resolve, 0));
@@ -149,10 +149,10 @@ add_task(async function test_timeShownMultipleNotifications() {
notification,
"Notification should still be open because we clicked during the security delay."
);
-
// If the notification is no longer shown (test failure) skip the remaining
// checks.
if (!notification) {
+ await cleanupFn();
return;
}
@@ -163,6 +163,7 @@ add_task(async function test_timeShownMultipleNotifications() {
notification.timeShown = performance.now() - fakeTimeShown;
info("Trigger main action via button click outside security delay");
+ let notificationHiddenPromise = waitForNotificationPanelHidden();
triggerMainCommand(PopupNotifications.panel);
info("Wait for panel to be hidden.");
@@ -170,15 +171,19 @@ add_task(async function test_timeShownMultipleNotifications() {
ok(
!PopupNotifications.getNotification("foo", gBrowser.selectedBrowser),
- "Should not longer see the notification."
+ "Should no longer see the notification."
);
-});
+
+ info("Cleanup.");
+ await cleanupFn();
+}
/**
- * Tests that when we reshow a notification after a tab switch the timeShown
- * attribute is correctly reset and the security delay is enforced.
+ * Tests that when we show a second notification while the panel is open the
+ * timeShown attribute is correctly set and the security delay is enforced
+ * properly.
*/
-add_task(async function test_notificationReshowTabSwitch() {
+add_task(async function test_timeShownMultipleNotifications() {
await ensureSecurityDelayReady();
ok(
@@ -195,6 +200,12 @@ add_task(async function test_notificationReshowTabSwitch() {
"PopupNotification should be open after first show call."
);
+ is(
+ PopupNotifications._currentNotifications.length,
+ 1,
+ "There should only be one notification"
+ );
+
let notification = PopupNotifications.getNotification(
"foo",
gBrowser.selectedBrowser
@@ -202,69 +213,39 @@ add_task(async function test_notificationReshowTabSwitch() {
is(notification?.id, "foo", "There should be a notification with id foo");
ok(notification.timeShown, "The notification should have timeShown set");
- info("Trigger main action via button click during security delay");
- triggerMainCommand(PopupNotifications.panel);
-
- await new Promise(resolve => setTimeout(resolve, 0));
-
- ok(PopupNotifications.isPanelOpen, "PopupNotification should still be open.");
- notification = PopupNotifications.getNotification(
- "foo",
- gBrowser.selectedBrowser
- );
- ok(
- notification,
- "Notification should still be open because we clicked during the security delay."
- );
-
- // If the notification is no longer shown (test failure) skip the remaining
- // checks.
- if (!notification) {
- return;
- }
-
- let panelHiddenPromise = waitForNotificationPanelHidden();
- let panelShownPromise;
-
- info("Open a new tab which hides the notification panel.");
- await BrowserTestUtils.withNewTab("https://example.com", async browser => {
- info("Wait for panel to be hidden by tab switch.");
- await panelHiddenPromise;
- info(
- "Keep the tab open until the security delay for the original notification show has expired."
- );
- await new Promise(resolve =>
- // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
- setTimeout(resolve, TEST_SECURITY_DELAY + 500)
- );
-
- panelShownPromise = waitForNotificationPanel();
- });
info(
- "Wait for the panel to show again after the tab close. We're showing the original tab again."
+ "Call show again with the same notification id while the PopupNotification panel is still open."
);
- await panelShownPromise;
-
+ showNotification();
ok(
PopupNotifications.isPanelOpen,
- "PopupNotification should be shown after tab close."
+ "PopupNotification should still open after second show call."
);
notification = PopupNotifications.getNotification(
"foo",
gBrowser.selectedBrowser
);
is(
+ PopupNotifications._currentNotifications.length,
+ 1,
+ "There should still only be one notification"
+ );
+
+ is(
notification?.id,
"foo",
"There should still be a notification with id foo"
);
+ ok(notification.timeShown, "The notification should have timeShown set");
let notificationHiddenPromise = waitForNotificationPanelHidden();
- info(
- "Because we re-show the panel after tab close / switch the security delay should have reset."
- );
- info("Trigger main action via button click during the new security delay.");
+ info("Trigger main action via button click during security delay");
+
+ // Wait for a tick of the event loop to ensure the button we're clicking
+ // has been slotted into moz-button-group
+ await new Promise(resolve => setTimeout(resolve, 0));
+
triggerMainCommand(PopupNotifications.panel);
await new Promise(resolve => setTimeout(resolve, 0));
@@ -278,6 +259,7 @@ add_task(async function test_notificationReshowTabSwitch() {
notification,
"Notification should still be open because we clicked during the security delay."
);
+
// If the notification is no longer shown (test failure) skip the remaining
// checks.
if (!notification) {
@@ -298,109 +280,83 @@ add_task(async function test_notificationReshowTabSwitch() {
ok(
!PopupNotifications.getNotification("foo", gBrowser.selectedBrowser),
- "Should not longer see the notification."
+ "Should no longer see the notification."
);
});
/**
+ * Tests that when we reshow a notification after a tab switch the timeShown
+ * attribute is correctly reset and the security delay is enforced.
+ */
+add_task(async function test_notificationReshowTabSwitch() {
+ await runPopupNotificationSecurityDelayTest({
+ onSecurityDelayExpired: async () => {
+ let panelHiddenPromise = waitForNotificationPanelHidden();
+ let panelShownPromise;
+
+ info("Open a new tab which hides the notification panel.");
+ await BrowserTestUtils.withNewTab("https://example.com", async () => {
+ info("Wait for panel to be hidden by tab switch.");
+ await panelHiddenPromise;
+ panelShownPromise = waitForNotificationPanel();
+ });
+ info(
+ "Wait for the panel to show again after the tab close. We're showing the original tab again."
+ );
+ await panelShownPromise;
+
+ ok(
+ PopupNotifications.isPanelOpen,
+ "PopupNotification should be shown after tab close."
+ );
+ let notification = PopupNotifications.getNotification(
+ "foo",
+ gBrowser.selectedBrowser
+ );
+ is(
+ notification?.id,
+ "foo",
+ "There should still be a notification with id foo"
+ );
+
+ info(
+ "Because we re-show the panel after tab close / switch the security delay should have reset."
+ );
+ },
+ });
+});
+
+/**
* Tests that the security delay gets reset when a window is repositioned and
* the PopupNotifications panel position is updated.
*/
add_task(async function test_notificationWindowMove() {
- await ensureSecurityDelayReady();
-
- info("Open a notification.");
- let popupShownPromise = waitForNotificationPanel();
- showNotification();
- await popupShownPromise;
- ok(
- PopupNotifications.isPanelOpen,
- "PopupNotification should be open after show call."
- );
-
- // Test that the initial security delay works.
- info("Trigger main action via button click during the new security delay.");
- triggerMainCommand(PopupNotifications.panel);
-
- await new Promise(resolve => setTimeout(resolve, 0));
-
- ok(PopupNotifications.isPanelOpen, "PopupNotification should still be open.");
- let notification = PopupNotifications.getNotification(
- "foo",
- gBrowser.selectedBrowser
- );
- ok(
- notification,
- "Notification should still be open because we clicked during the security delay."
- );
- // If the notification is no longer shown (test failure) skip the remaining
- // checks.
- if (!notification) {
- return;
- }
-
- info("Wait for security delay to expire.");
- await new Promise(resolve =>
- // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
- setTimeout(resolve, TEST_SECURITY_DELAY + 500)
- );
-
- info("Reposition the window");
- // Remember original window position.
- let { screenX, screenY } = window;
-
- let promisePopupPositioned = BrowserTestUtils.waitForEvent(
- PopupNotifications.panel,
- "popuppositioned"
- );
-
- // Move the window.
- window.moveTo(200, 200);
-
- // Wait for the panel to reposition and the PopupNotifications listener to run.
- await promisePopupPositioned;
- await new Promise(resolve => setTimeout(resolve, 0));
-
- info("Trigger main action via button click during the new security delay.");
- triggerMainCommand(PopupNotifications.panel);
-
- await new Promise(resolve => setTimeout(resolve, 0));
-
- ok(PopupNotifications.isPanelOpen, "PopupNotification should still be open.");
- notification = PopupNotifications.getNotification(
- "foo",
- gBrowser.selectedBrowser
- );
- ok(
- notification,
- "Notification should still be open because we clicked during the security delay."
- );
- // If the notification is no longer shown (test failure) skip the remaining
- // checks.
- if (!notification) {
- return;
- }
-
- // Ensure that once the security delay has passed the notification can be
- // closed again.
- let fakeTimeShown = TEST_SECURITY_DELAY + 500;
- info(`Manually set timeShown to ${fakeTimeShown}ms in the past.`);
- notification.timeShown = performance.now() - fakeTimeShown;
-
- info("Trigger main action via button click outside security delay");
- let notificationHiddenPromise = waitForNotificationPanelHidden();
- triggerMainCommand(PopupNotifications.panel);
-
- info("Wait for panel to be hidden.");
- await notificationHiddenPromise;
-
- ok(
- !PopupNotifications.getNotification("foo", gBrowser.selectedBrowser),
- "Should not longer see the notification."
- );
-
- // Reset window position
- window.moveTo(screenX, screenY);
+ let screenX, screenY;
+
+ await runPopupNotificationSecurityDelayTest({
+ onSecurityDelayExpired: async () => {
+ info("Reposition the window");
+ // Remember original window position.
+ screenX = window.screenX;
+ screenY = window.screenY;
+
+ let promisePopupPositioned = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popuppositioned"
+ );
+
+ // Move the window.
+ window.moveTo(200, 200);
+
+ // Wait for the panel to reposition and the PopupNotifications listener to run.
+ await promisePopupPositioned;
+ await new Promise(resolve => setTimeout(resolve, 0));
+ },
+ cleanupFn: async () => {
+ // Reset window position
+ window.moveTo(screenX, screenY);
+ },
+ });
});
/**
@@ -563,5 +519,49 @@ add_task(async function test_notificationDuringFullScreenTransition() {
info("Wait for full screen transition end.");
await promiseFullScreenTransitionEnd;
info("Full screen transition end");
+
+ await SpecialPowers.popPrefEnv();
+ });
+});
+
+/**
+ * Tests that the security delay gets extended when pointer lock is entered.
+ */
+add_task(async function test_notificationPointerLock() {
+ // We need a tab to enter pointer lock.
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "https://example.com"
+ );
+
+ await runPopupNotificationSecurityDelayTest({
+ onSecurityDelayExpired: async () => {
+ info("Enter pointer lock");
+ // Move focus to the browser to ensure pointer lock request succeeds.
+ gBrowser.selectedBrowser.focus();
+ let pointerLockEnterPromise = TestUtils.topicObserved(
+ "pointer-lock-entered"
+ );
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
+ SpecialPowers.wrap(content.document).notifyUserGestureActivation();
+ await content.document.body.requestPointerLock();
+ });
+
+ // Wait for pointer lock to be entered and the PopupNotifications listener to run.
+ await pointerLockEnterPromise;
+ await new Promise(resolve => setTimeout(resolve, 0));
+ },
+ cleanupFn: async () => {
+ // Cleanup.
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
+ SpecialPowers.wrap(content.document).notifyUserGestureActivation();
+ await content.document.exitPointerLock();
+ });
+ await TestUtils.waitForCondition(
+ () => !window.PointerLock.isActive,
+ "Wait for pointer lock exit."
+ );
+ BrowserTestUtils.removeTab(tab);
+ },
});
});
diff --git a/browser/base/content/test/popups/browser_popup_close_main_window.js b/browser/base/content/test/popups/browser_popup_close_main_window.js
index 148e937bca..abf6c43c3f 100644
--- a/browser/base/content/test/popups/browser_popup_close_main_window.js
+++ b/browser/base/content/test/popups/browser_popup_close_main_window.js
@@ -37,7 +37,7 @@ add_task(async function closing_last_window_equals_quitting() {
Services.obs.addObserver(obs, "browser-lastwindow-close-requested");
let newWin = await BrowserTestUtils.openNewBrowserWindow();
let closedPromise = BrowserTestUtils.windowClosed(newWin);
- newWin.BrowserTryToCloseWindow();
+ newWin.BrowserCommands.tryToCloseWindow();
await closedPromise;
is(observed, 1, "Got a notification for closing the normal window.");
Services.obs.removeObserver(obs, "browser-lastwindow-close-requested");
@@ -68,12 +68,12 @@ add_task(async function closing_last_window_equals_quitting() {
});
let popupWin = await popupPromise;
let closedPromise = BrowserTestUtils.windowClosed(newWin);
- newWin.BrowserTryToCloseWindow();
+ newWin.BrowserCommands.tryToCloseWindow();
await closedPromise;
is(observed, 0, "Got no notification for closing the normal window.");
closedPromise = BrowserTestUtils.windowClosed(popupWin);
- popupWin.BrowserTryToCloseWindow();
+ popupWin.BrowserCommands.tryToCloseWindow();
await closedPromise;
is(
observed,
diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI.js b/browser/base/content/test/protectionsUI/browser_protectionsUI.js
index 5dc6acebf7..e512f7a415 100644
--- a/browser/base/content/test/protectionsUI/browser_protectionsUI.js
+++ b/browser/base/content/test/protectionsUI/browser_protectionsUI.js
@@ -500,7 +500,7 @@ add_task(async function testNumberOfBlockedTrackers() {
// attribute will only be set if the previous counter is zero. Instead, we
// wait for the change of the text content of the counter.
let updateCounterPromise = new Promise(resolve => {
- let mut = new MutationObserver(mutations => {
+ let mut = new MutationObserver(() => {
resolve();
mut.disconnect();
});
diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_cookies_subview.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_cookies_subview.js
index 00281ac415..1346fb94c1 100644
--- a/browser/base/content/test/protectionsUI/browser_protectionsUI_cookies_subview.js
+++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_cookies_subview.js
@@ -397,7 +397,7 @@ add_task(async function testCookiesSubViewAllowedHeuristic() {
let popup;
let windowCreated = TestUtils.topicObserved(
"chrome-document-global-created",
- (subject, data) => {
+ subject => {
popup = subject;
return true;
}
diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_fetch.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_fetch.js
index 26b131d4eb..02aa21474d 100644
--- a/browser/base/content/test/protectionsUI/browser_protectionsUI_fetch.js
+++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_fetch.js
@@ -15,7 +15,7 @@ add_task(async function test_fetch() {
await SpecialPowers.spawn(newTabBrowser, [], async function () {
await content.wrappedJSObject
.test_fetch()
- .then(response => Assert.ok(false, "should have denied the request"))
+ .then(() => Assert.ok(false, "should have denied the request"))
.catch(e => Assert.ok(true, `Caught exception: ${e}`));
});
await contentBlockingEvent;
diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_info_message.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_info_message.js
index fadfaaab98..1e07db2689 100644
--- a/browser/base/content/test/protectionsUI/browser_protectionsUI_info_message.js
+++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_info_message.js
@@ -51,10 +51,10 @@ add_task(async function testPanelInfoMessage() {
});
// Test that the info message is displayed when the panel opens
- let container = document.getElementById("messaging-system-message-container");
+ let container = document.getElementById("info-message-container");
let message = document.getElementById("protections-popup-message");
let learnMoreLink = document.querySelector(
- "#messaging-system-message-container .text-link"
+ "#info-message-container .text-link"
);
// Check the visibility of the info message.
diff --git a/browser/base/content/test/referrer/head.js b/browser/base/content/test/referrer/head.js
index c812d73e80..34a5f2a58e 100644
--- a/browser/base/content/test/referrer/head.js
+++ b/browser/base/content/test/referrer/head.js
@@ -165,7 +165,7 @@ function delayedStartupFinished(aWindow) {
* @return {Promise}
* @resolves With the tab once it's loaded.
*/
-function someTabLoaded(aWindow) {
+function someTabLoaded() {
return BrowserTestUtils.waitForNewTab(gTestWindow.gBrowser, null, true);
}
diff --git a/browser/base/content/test/sanitize/browser_cookiePermission_aboutURL.js b/browser/base/content/test/sanitize/browser_cookiePermission_aboutURL.js
index ada8286437..ff6badb535 100644
--- a/browser/base/content/test/sanitize/browser_cookiePermission_aboutURL.js
+++ b/browser/base/content/test/sanitize/browser_cookiePermission_aboutURL.js
@@ -15,10 +15,10 @@ function checkDataForAboutURL() {
{}
);
let request = indexedDB.openForPrincipal(principal, "TestDatabase", 1);
- request.onupgradeneeded = function (e) {
+ request.onupgradeneeded = function () {
data = false;
};
- request.onsuccess = function (e) {
+ request.onsuccess = function () {
resolve(data);
};
});
diff --git a/browser/base/content/test/sanitize/browser_sanitize-timespans.js b/browser/base/content/test/sanitize/browser_sanitize-timespans.js
index f9be12775b..28b528d71f 100644
--- a/browser/base/content/test/sanitize/browser_sanitize-timespans.js
+++ b/browser/base/content/test/sanitize/browser_sanitize-timespans.js
@@ -20,7 +20,7 @@ function promiseFormHistoryRemoved() {
function promiseDownloadRemoved(list) {
return new Promise(resolve => {
let view = {
- onDownloadRemoved(download) {
+ onDownloadRemoved() {
list.removeView(view);
resolve();
},
diff --git a/browser/base/content/test/sanitize/browser_sanitize-timespans_v2.js b/browser/base/content/test/sanitize/browser_sanitize-timespans_v2.js
index c732262a1a..067a651890 100644
--- a/browser/base/content/test/sanitize/browser_sanitize-timespans_v2.js
+++ b/browser/base/content/test/sanitize/browser_sanitize-timespans_v2.js
@@ -23,7 +23,7 @@ function promiseFormHistoryRemoved() {
function promiseDownloadRemoved(list) {
return new Promise(resolve => {
let view = {
- onDownloadRemoved(download) {
+ onDownloadRemoved() {
list.removeView(view);
resolve();
},
diff --git a/browser/base/content/test/sanitize/browser_sanitizeDialog_v2.js b/browser/base/content/test/sanitize/browser_sanitizeDialog_v2.js
index 8ae0263c82..ecdc5490d4 100644
--- a/browser/base/content/test/sanitize/browser_sanitizeDialog_v2.js
+++ b/browser/base/content/test/sanitize/browser_sanitizeDialog_v2.js
@@ -844,14 +844,14 @@ add_task(async function testLoadtimeTelemetry() {
let loadTimeDistribution = Glean.privacySanitize.loadTime.testGetValue();
let expectedNumberOfCounts = Object.entries(EXPECTED_CONTEXT_COUNTS).reduce(
- (acc, [key, value]) => acc + value,
+ (acc, [, value]) => acc + value,
0
);
// No guarantees from timers means no guarantees on buckets.
// But we can guarantee it's only two samples.
is(
Object.entries(loadTimeDistribution.values).reduce(
- (acc, [bucket, count]) => acc + count,
+ (acc, [, count]) => acc + count,
0
),
expectedNumberOfCounts,
diff --git a/browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js b/browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js
index ccb3c7d519..736df32e81 100644
--- a/browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js
+++ b/browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js
@@ -10,6 +10,14 @@ ChromeUtils.defineESModuleGetters(this, {
Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
});
+const LARGE_USAGE_NUM = 100000000000000000000000000000000000000000000000000;
+
+function isIframeOverflowing(win) {
+ return (
+ win.scrollWidth > win.clientWidth || win.scrollHeight > win.clientHeight
+ );
+}
+
add_setup(async function () {
await blankSlate();
registerCleanupFunction(async function () {
@@ -275,7 +283,7 @@ add_task(async function testClearingBeforeDataSizesLoad() {
info("stub called");
info("This promise should never resolve");
- await new Promise(resolve => {});
+ await new Promise(() => {});
});
dh.onload = async function () {
// we don't need to initiate a event listener to wait for the resolver to be assigned for this
@@ -308,3 +316,58 @@ add_task(async function testClearingBeforeDataSizesLoad() {
// Restore the sandbox after the test is complete
sandbox.restore();
});
+
+// tests the dialog resizing upon wrapping of text
+// so that the clear buttons do not get cut out of the dialog.
+add_task(async function testPossibleWrappingOfDialog() {
+ await blankSlate();
+
+ let dh = new ClearHistoryDialogHelper({
+ checkingDataSizes: true,
+ });
+ // Create a sandbox for isolated stubbing within the test
+ let sandbox = sinon.createSandbox();
+ sandbox
+ .stub(SiteDataManager, "getQuotaUsageForTimeRanges")
+ .callsFake(async () => {
+ info("stubbed getQuotaUsageForTimeRanges called");
+
+ return {
+ TIMESPAN_HOUR: 0,
+ TIMESPAN_2HOURS: 0,
+ TIMESPAN_4HOURS: LARGE_USAGE_NUM,
+ TIMESPAN_TODAY: 0,
+ TIMESPAN_EVERYTHING: 0,
+ };
+ });
+
+ dh.onload = async function () {
+ let windowObj =
+ window.browsingContext.topChromeWindow.gDialogBox._dialog._frame
+ .contentWindow;
+ let promise = new Promise(resolve => {
+ windowObj.addEventListener("resize", resolve);
+ });
+ this.selectDuration(Sanitizer.TIMESPAN_4HOURS);
+
+ await promise;
+ ok(
+ !isIframeOverflowing(windowObj.document.getElementById("SanitizeDialog")),
+ "There should be no overflow on wrapping in the dialog"
+ );
+
+ this.selectDuration(Sanitizer.TIMESPAN_2HOURS);
+ await promise;
+ ok(
+ !isIframeOverflowing(windowObj.document.getElementById("SanitizeDialog")),
+ "There should be no overflow on wrapping in the dialog"
+ );
+
+ this.cancelDialog();
+ };
+ dh.open();
+ await dh.promiseClosed;
+
+ // Restore the sandbox after the test is complete
+ sandbox.restore();
+});
diff --git a/browser/base/content/test/sanitize/head.js b/browser/base/content/test/sanitize/head.js
index 30d96c69f6..1b41226fd1 100644
--- a/browser/base/content/test/sanitize/head.js
+++ b/browser/base/content/test/sanitize/head.js
@@ -49,10 +49,10 @@ function checkIndexedDB(host, originAttributes) {
originAttributes
);
let request = indexedDB.openForPrincipal(principal, "TestDatabase", 1);
- request.onupgradeneeded = function (e) {
+ request.onupgradeneeded = function () {
data = false;
};
- request.onsuccess = function (e) {
+ request.onsuccess = function () {
resolve(data);
};
});
diff --git a/browser/base/content/test/sidebar/browser_sidebar_adopt.js b/browser/base/content/test/sidebar/browser_sidebar_adopt.js
index 344a71cb9b..988ac1487f 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_adopt.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_adopt.js
@@ -5,7 +5,7 @@
* during the initial browser startup - but it would be hard to do with a mochitest. */
registerCleanupFunction(() => {
- SidebarUI.hide();
+ SidebarController.hide();
});
function failIfSidebarFocusedFires() {
@@ -26,7 +26,7 @@ add_task(async function testAdoptedTwoWindows() {
info("Ensure that sidebar state is adopted only from the opener");
let win1 = await BrowserTestUtils.openNewBrowserWindow();
- await win1.SidebarUI.show("viewBookmarksSidebar");
+ await win1.SidebarController.show("viewBookmarksSidebar");
await BrowserTestUtils.closeWindow(win1);
let win2 = await BrowserTestUtils.openNewBrowserWindow();
@@ -34,7 +34,7 @@ add_task(async function testAdoptedTwoWindows() {
!win2.document.getElementById("sidebar-button").hasAttribute("checked"),
"Sidebar button isn't checked"
);
- ok(!win2.SidebarUI.isOpen, "Sidebar is closed");
+ ok(!win2.SidebarController.isOpen, "Sidebar is closed");
await BrowserTestUtils.closeWindow(win2);
});
@@ -46,7 +46,7 @@ add_task(async function testEventsReceivedInMainWindow() {
let initialShown = BrowserTestUtils.waitForEvent(window, "SidebarShown");
let initialFocus = BrowserTestUtils.waitForEvent(window, "SidebarFocused");
- await SidebarUI.show("viewBookmarksSidebar");
+ await SidebarController.show("viewBookmarksSidebar");
await initialShown;
await initialFocus;
diff --git a/browser/base/content/test/sidebar/browser_sidebar_app_locale_changed.js b/browser/base/content/test/sidebar/browser_sidebar_app_locale_changed.js
index 5b07da9839..1e52895a7d 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_app_locale_changed.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_app_locale_changed.js
@@ -8,7 +8,7 @@
add_task(function cleanup() {
registerCleanupFunction(() => {
- SidebarUI.hide();
+ SidebarController.hide();
});
});
@@ -17,7 +17,7 @@ add_task(function cleanup() {
*/
async function testLiveReloading(sidebarName) {
info("Showing the sidebar " + sidebarName);
- await SidebarUI.show(sidebarName);
+ await SidebarController.show(sidebarName);
function getTreeChildren() {
const sidebarDoc =
@@ -44,7 +44,7 @@ async function testLiveReloading(sidebarName) {
);
info("Hiding the sidebar");
- SidebarUI.hide();
+ SidebarController.hide();
}
add_task(async function test_bookmarks_sidebar() {
diff --git a/browser/base/content/test/sidebar/browser_sidebar_keys.js b/browser/base/content/test/sidebar/browser_sidebar_keys.js
index f12d1cf5f7..61e4ce9737 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_keys.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_keys.js
@@ -11,11 +11,11 @@ async function testSidebarKeyToggle(key, options, expectedSidebarId) {
expectedSidebarId
);
EventUtils.synthesizeKey(key, options);
- Assert.ok(!SidebarUI.isOpen);
+ Assert.ok(!SidebarController.isOpen);
}
add_task(async function test_sidebar_keys() {
- registerCleanupFunction(() => SidebarUI.hide());
+ registerCleanupFunction(() => SidebarController.hide());
await testSidebarKeyToggle("b", { accelKey: true }, "viewBookmarksSidebar");
@@ -30,7 +30,7 @@ add_task(async function test_sidebar_in_customize_mode() {
let { CustomizableUI } = ChromeUtils.importESModule(
"resource:///modules/CustomizableUI.sys.mjs"
);
- registerCleanupFunction(() => SidebarUI.hide());
+ registerCleanupFunction(() => SidebarController.hide());
let placement = CustomizableUI.getPlacementOfWidget("sidebar-button");
if (!(placement?.area == CustomizableUI.AREA_NAVBAR)) {
@@ -55,7 +55,7 @@ add_task(async function test_sidebar_in_customize_mode() {
).a;
let promiseShown = BrowserTestUtils.waitForEvent(window, "SidebarShown");
- SidebarUI.show("viewBookmarksSidebar");
+ SidebarController.show("viewBookmarksSidebar");
await promiseShown;
Assert.greater(
@@ -80,8 +80,8 @@ add_task(async function test_sidebar_in_customize_mode() {
);
// Attempt toggle - should fail in customize mode.
- await SidebarUI.toggle();
- ok(SidebarUI.isOpen, "Sidebar is still open");
+ await SidebarController.toggle();
+ ok(SidebarController.isOpen, "Sidebar is still open");
// Exit customize mode. This should re-enable the toggle and make the sidebar
// toggle widget appear checked again, since toggle() didn't hide the sidebar.
@@ -98,8 +98,8 @@ add_task(async function test_sidebar_in_customize_mode() {
"Sidebar widget background should appear checked again"
);
- await SidebarUI.toggle();
- ok(!SidebarUI.isOpen, "Sidebar is closed");
+ await SidebarController.toggle();
+ ok(!SidebarController.isOpen, "Sidebar is closed");
Assert.equal(
getBGAlpha(),
0,
diff --git a/browser/base/content/test/sidebar/browser_sidebar_move.js b/browser/base/content/test/sidebar/browser_sidebar_move.js
index 3de26b7966..05ea9e3322 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_move.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_move.js
@@ -1,18 +1,20 @@
registerCleanupFunction(() => {
Services.prefs.clearUserPref("sidebar.position_start");
- SidebarUI.hide();
+ SidebarController.hide();
});
const EXPECTED_START_ORDINALS = [
- ["sidebar-box", 1],
- ["sidebar-splitter", 2],
- ["appcontent", 3],
+ ["sidebar-main", 1],
+ ["sidebar-box", 2],
+ ["sidebar-splitter", 3],
+ ["appcontent", 4],
];
const EXPECTED_END_ORDINALS = [
- ["sidebar-box", 3],
- ["sidebar-splitter", 2],
- ["appcontent", 1],
+ ["sidebar-main", 5],
+ ["sidebar-box", 4],
+ ["sidebar-splitter", 3],
+ ["appcontent", 2],
];
function getBrowserChildrenWithOrdinals() {
@@ -23,8 +25,8 @@ function getBrowserChildrenWithOrdinals() {
}
add_task(async function () {
- await SidebarUI.show("viewBookmarksSidebar");
- SidebarUI.showSwitcherPanel();
+ await SidebarController.show("viewBookmarksSidebar");
+ SidebarController.showSwitcherPanel();
let reversePositionButton = document.getElementById(
"sidebar-reverse-position"
@@ -41,8 +43,8 @@ add_task(async function () {
ok(!box.hasAttribute("positionend"), "Positioned start");
// Moved to right
- SidebarUI.reversePosition();
- SidebarUI.showSwitcherPanel();
+ SidebarController.reversePosition();
+ SidebarController.showSwitcherPanel();
Assert.deepEqual(
getBrowserChildrenWithOrdinals(),
EXPECTED_END_ORDINALS,
@@ -56,8 +58,8 @@ add_task(async function () {
ok(box.hasAttribute("positionend"), "Positioned end");
// Moved to back to left
- SidebarUI.reversePosition();
- SidebarUI.showSwitcherPanel();
+ SidebarController.reversePosition();
+ SidebarController.showSwitcherPanel();
Assert.deepEqual(
getBrowserChildrenWithOrdinals(),
EXPECTED_START_ORDINALS,
diff --git a/browser/base/content/test/sidebar/browser_sidebar_persist.js b/browser/base/content/test/sidebar/browser_sidebar_persist.js
index fe67bed9e0..4977c7ef0f 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_persist.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_persist.js
@@ -18,7 +18,7 @@ add_task(async function persist_sidebar_width() {
{
info("Showing new window and setting sidebar box");
const win = await BrowserTestUtils.openNewBrowserWindow();
- await win.SidebarUI.show("viewBookmarksSidebar");
+ await win.SidebarController.show("viewBookmarksSidebar");
win.document.getElementById("sidebar-box").style.width = "100px";
await BrowserTestUtils.closeWindow(win);
}
@@ -26,7 +26,7 @@ add_task(async function persist_sidebar_width() {
{
info("Showing new window and seeing persisted width");
const win = await BrowserTestUtils.openNewBrowserWindow();
- await win.SidebarUI.show("viewBookmarksSidebar");
+ await win.SidebarController.show("viewBookmarksSidebar");
is(
win.document.getElementById("sidebar-box").style.width,
"100px",
diff --git a/browser/base/content/test/sidebar/browser_sidebar_switcher.js b/browser/base/content/test/sidebar/browser_sidebar_switcher.js
index 032c23b029..0fc9e18e01 100644
--- a/browser/base/content/test/sidebar/browser_sidebar_switcher.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_switcher.js
@@ -1,5 +1,5 @@
registerCleanupFunction(() => {
- SidebarUI.hide();
+ SidebarController.hide();
});
/**
@@ -9,14 +9,14 @@ registerCleanupFunction(() => {
*/
function showSwitcherPanelPromise() {
return new Promise(resolve => {
- SidebarUI._switcherPanel.addEventListener(
+ SidebarController._switcherPanel.addEventListener(
"popupshown",
() => {
resolve();
},
{ once: true }
);
- SidebarUI.showSwitcherPanel();
+ SidebarController.showSwitcherPanel();
});
}
@@ -25,7 +25,10 @@ function showSwitcherPanelPromise() {
* @returns Promise which resolves when the popup menu is opened
*/
async function waitForSwitcherPopupShown() {
- return BrowserTestUtils.waitForEvent(SidebarUI._switcherPanel, "popupshown");
+ return BrowserTestUtils.waitForEvent(
+ SidebarController._switcherPanel,
+ "popupshown"
+ );
}
/**
@@ -63,7 +66,7 @@ async function testSidebarMenuKeyToggle(key, sidebarTitle) {
info(`Testing "${key}" key handling of sidebar menu popup items
to access ${sidebarTitle} sidebar`);
- Assert.ok(SidebarUI.isOpen, "Sidebar is open");
+ Assert.ok(SidebarController.isOpen, "Sidebar is open");
let sidebarSwitcher = document.querySelector("#sidebar-switcher-target");
let sidebar = document.getElementById("sidebar");
@@ -89,7 +92,7 @@ async function testSidebarMenuKeyToggle(key, sidebarTitle) {
"The sidebar switcher target button is focused"
);
Assert.equal(
- SidebarUI._switcherPanel.state,
+ SidebarController._switcherPanel.state,
"closed",
"Sidebar menu popup is closed"
);
@@ -102,7 +105,7 @@ async function testSidebarMenuKeyToggle(key, sidebarTitle) {
await promisePopupShown;
Assert.equal(
- SidebarUI._switcherPanel.state,
+ SidebarController._switcherPanel.state,
"open",
"Sidebar menu popup is open"
);
@@ -111,7 +114,7 @@ async function testSidebarMenuKeyToggle(key, sidebarTitle) {
let arrowDown = async (menuitemId, msg) => {
let menuItemActive = BrowserTestUtils.waitForEvent(
- SidebarUI._switcherPanel,
+ SidebarController._switcherPanel,
"DOMMenuItemActive"
);
EventUtils.synthesizeKey("KEY_ArrowDown", {});
@@ -149,18 +152,18 @@ async function testSidebarMenuKeyToggle(key, sidebarTitle) {
info("Testing keyboard navigation when a sidebar menu popup is closed");
Assert.equal(
- SidebarUI._switcherPanel.state,
+ SidebarController._switcherPanel.state,
"closed",
"Sidebar menu popup is closed"
);
// Test the sidebar panel is updated
Assert.equal(
- SidebarUI._box.getAttribute("sidebarcommand"),
+ SidebarController._box.getAttribute("sidebarcommand"),
`view${sidebarTitle}Sidebar` /* e.g. "viewHistorySidebar" */,
`${sidebarTitle} sidebar loaded`
);
Assert.equal(
- SidebarUI.currentID,
+ SidebarController.currentID,
`view${sidebarTitle}Sidebar` /* e.g. "viewHistorySidebar" */,
`${sidebarTitle}'s current ID is updated to a target view`
);
@@ -173,7 +176,7 @@ add_task(async function markup() {
false,
"Unexpected sidebar found - a previous test failed to cleanup correctly"
);
- SidebarUI.hide();
+ SidebarController.hide();
}
let sidebarPopup = document.querySelector("#sidebarMenu-popup");
@@ -205,7 +208,7 @@ add_task(async function markup() {
info("Test dynamic changes in the markup of the sidebar switcher control");
- await SidebarUI.show("viewBookmarksSidebar");
+ await SidebarController.show("viewBookmarksSidebar");
await showSwitcherPanelPromise();
Assert.equal(
@@ -229,25 +232,25 @@ add_task(async function markup() {
"Sidebar switcher button is collapsed when a sidebar menu is dismissed"
);
- SidebarUI.hide();
+ SidebarController.hide();
});
add_task(async function keynav() {
// If a sidebar is already open, close it.
- if (SidebarUI.isOpen) {
+ if (SidebarController.isOpen) {
Assert.ok(
false,
"Unexpected sidebar found - a previous test failed to cleanup correctly"
);
- SidebarUI.hide();
+ SidebarController.hide();
}
- await SidebarUI.show("viewBookmarksSidebar");
+ await SidebarController.show("viewBookmarksSidebar");
await testSidebarMenuKeyToggle("KEY_Enter", "History");
await testSidebarMenuKeyToggle(" ", "Tabs");
- SidebarUI.hide();
+ SidebarController.hide();
});
add_task(async function mouse() {
@@ -257,11 +260,11 @@ add_task(async function mouse() {
false,
"Unexpected sidebar found - a previous test failed to cleanup correctly"
);
- SidebarUI.hide();
+ SidebarController.hide();
}
let sidebar = document.querySelector("#sidebar-box");
- await SidebarUI.show("viewBookmarksSidebar");
+ await SidebarController.show("viewBookmarksSidebar");
await showSwitcherPanelPromise();
await pickSwitcherMenuitem("#sidebar-switcher-history");
diff --git a/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js b/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js
index 858cd3d632..79b6d216c5 100644
--- a/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js
+++ b/browser/base/content/test/siteIdentity/browser_identityBlock_focus.js
@@ -98,7 +98,7 @@ add_task(async function testWithNotifications() {
// Checks that with invalid pageproxystate the identity block is ignored.
add_task(async function testInvalidPageProxyState() {
await SpecialPowers.pushPrefEnv({ set: [["accessibility.tabfocus", 7]] });
- await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
+ await BrowserTestUtils.withNewTab("about:blank", async function () {
// Loading about:blank will automatically focus the urlbar, which, however, can
// race with the test code. So we only send the shortcut if the urlbar isn't focused yet.
if (document.activeElement != gURLBar.inputField) {
diff --git a/browser/base/content/test/siteIdentity/browser_identityPopup_clearSiteData.js b/browser/base/content/test/siteIdentity/browser_identityPopup_clearSiteData.js
index 0107814b98..ff77b42ed8 100644
--- a/browser/base/content/test/siteIdentity/browser_identityPopup_clearSiteData.js
+++ b/browser/base/content/test/siteIdentity/browser_identityPopup_clearSiteData.js
@@ -67,7 +67,7 @@ async function testClearing(
});
}
- await BrowserTestUtils.withNewTab(testURI, async function (browser) {
+ await BrowserTestUtils.withNewTab(testURI, async function () {
// Verify we have added quota storage.
if (testQuota) {
let usage = await SiteDataTestUtils.getQuotaUsage(originA);
diff --git a/browser/base/content/test/siteIdentity/browser_navigation_failures.js b/browser/base/content/test/siteIdentity/browser_navigation_failures.js
index ac3fcc4067..f71552cdcf 100644
--- a/browser/base/content/test/siteIdentity/browser_navigation_failures.js
+++ b/browser/base/content/test/siteIdentity/browser_navigation_failures.js
@@ -85,10 +85,10 @@ function startServer(cert) {
output = transport.openOutputStream(0, 0, 0);
},
- onHandshakeDone(socket, status) {
+ onHandshakeDone() {
input.asyncWait(
{
- onInputStreamReady(readyInput) {
+ onInputStreamReady() {
try {
input.close();
output.close();
diff --git a/browser/base/content/test/siteIdentity/browser_secure_transport_insecure_scheme.js b/browser/base/content/test/siteIdentity/browser_secure_transport_insecure_scheme.js
index 9dce76266a..bd004bae1b 100644
--- a/browser/base/content/test/siteIdentity/browser_secure_transport_insecure_scheme.js
+++ b/browser/base/content/test/siteIdentity/browser_secure_transport_insecure_scheme.js
@@ -19,7 +19,7 @@ const NOT_SECURE_LABEL = Services.prefs.getBoolPref(
* @param {string} uri - URI of the page to test with.
*/
async function testPageInfoNotEncrypted(uri) {
- let pageInfo = BrowserPageInfo(uri, "securityTab");
+ let pageInfo = BrowserCommands.pageInfo(uri, "securityTab");
await BrowserTestUtils.waitForEvent(pageInfo, "load");
let pageInfoDoc = pageInfo.document;
let securityTab = pageInfoDoc.getElementById("securityTab");
@@ -87,7 +87,7 @@ function startServer(cert) {
output = transport.openOutputStream(0, 0, 0);
},
- onHandshakeDone(socket, status) {
+ onHandshakeDone() {
input.asyncWait(
{
onInputStreamReady(readyInput) {
@@ -152,7 +152,7 @@ add_task(async function () {
QueryInterface: ChromeUtils.generateQI(["nsISystemProxySettings"]),
mainThreadOnly: true,
PACURI: null,
- getProxyForURI: (aSpec, aScheme, aHost, aPort) => {
+ getProxyForURI: () => {
return `HTTPS localhost:${server.port}`;
},
};
@@ -181,7 +181,7 @@ add_task(async function () {
// secure, in a real situation the connection from the proxy to
// http://example.com won't be secure, so we treat it as not secure.
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
- await BrowserTestUtils.withNewTab("http://example.com/", async browser => {
+ await BrowserTestUtils.withNewTab("http://example.com/", async () => {
let identityMode = window.document.getElementById("identity-box").className;
is(
identityMode,
diff --git a/browser/base/content/test/siteIdentity/head.js b/browser/base/content/test/siteIdentity/head.js
index 733796ffb7..9936a8bf6f 100644
--- a/browser/base/content/test/siteIdentity/head.js
+++ b/browser/base/content/test/siteIdentity/head.js
@@ -244,12 +244,12 @@ async function assertMixedContentBlockingState(tabbrowser, states = {}) {
);
gIdentityHandler._identityIconBox.click();
await promisePanelOpen;
- let popupAttr = doc
- .getElementById("identity-popup")
- .getAttribute("mixedcontent");
- let bodyAttr = doc
- .getElementById("identity-popup-securityView-extended-info")
- .getAttribute("mixedcontent");
+ let popupAttr =
+ doc.getElementById("identity-popup").getAttribute("mixedcontent") || "";
+ let bodyAttr =
+ doc
+ .getElementById("identity-popup-securityView-extended-info")
+ .getAttribute("mixedcontent") || "";
is(
popupAttr.includes("active-loaded"),
diff --git a/browser/base/content/test/static/browser_all_files_referenced.js b/browser/base/content/test/static/browser_all_files_referenced.js
index 5e83443ec7..9668288181 100644
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -81,6 +81,9 @@ var gExceptionPaths = [
// CSS files are referenced inside JS in an html template
"chrome://browser/content/aboutlogins/components/",
+
+ // Strip on Share parameter lists
+ "chrome://global/content/antitracking/",
];
// These are not part of the omni.ja file, so we find them only when running
@@ -99,13 +102,6 @@ if (AppConstants.MOZ_BACKGROUNDTASKS) {
gExceptionPaths.push("resource://app/modules/backgroundtasks/");
}
-if (AppConstants.NIGHTLY_BUILD) {
- // This is nightly-only debug tool.
- gExceptionPaths.push(
- "chrome://browser/content/places/interactionsViewer.html"
- );
-}
-
// Each allowlist entry should have a comment indicating which file is
// referencing the listed file in a way that the test can't detect, or a
// bug number to remove or use the file if it is indeed currently unreferenced.
@@ -280,9 +276,6 @@ var allowlist = [
// find the references)
{ file: "chrome://browser/content/screenshots/copied-notification.svg" },
- // Bug 1875361
- { file: "chrome://global/content/ml/SummarizerModel.sys.mjs" },
-
// toolkit/xre/MacRunFromDmgUtils.mm
{ file: "resource://gre/localization/en-US/toolkit/global/run-from-dmg.ftl" },
@@ -291,8 +284,31 @@ var allowlist = [
{ file: "chrome://browser/content/screenshots/copy.svg" },
{ file: "chrome://browser/content/screenshots/download.svg" },
{ file: "chrome://browser/content/screenshots/download-white.svg" },
+
+ // Referenced programmatically
+ { file: "chrome://browser/content/backup/BackupManifest.1.schema.json" },
+
+ // Bug 1892002
+ { file: "resource://app/modules/TopSites.sys.mjs" },
];
+if (AppConstants.NIGHTLY_BUILD) {
+ allowlist.push(
+ ...[
+ // This is nightly-only debug tool.
+ { file: "chrome://browser/content/places/interactionsViewer.html" },
+
+ // A debug tool that is only available in Nightly builds, and is accessed
+ // directly by developers via the chrome URI (bug 1888491)
+ { file: "chrome://browser/content/backup/debug.html" },
+
+ // The Transformers.js prod lib is not used in Nightly builds
+ { file: "chrome://global/content/ml/transformers.js" },
+ { file: "chrome://global/content/ml/ort.js" },
+ ]
+ );
+}
+
if (AppConstants.platform != "win") {
// toolkit/mozapps/defaultagent/Notification.cpp
// toolkit/mozapps/defaultagent/ScheduledTask.cpp
diff --git a/browser/base/content/test/static/browser_parsable_css.js b/browser/base/content/test/static/browser_parsable_css.js
index 602cc5a7e2..6b075fc98f 100644
--- a/browser/base/content/test/static/browser_parsable_css.js
+++ b/browser/base/content/test/static/browser_parsable_css.js
@@ -14,12 +14,6 @@ let ignoreList = [
{ sourceName: /codemirror\.css$/i, isFromDevTools: true },
// UA-only media features.
{
- sourceName: /\b(autocomplete-item)\.css$/,
- errorMessage: /Expected media feature name but found \u2018-moz.*/i,
- isFromDevTools: false,
- platforms: ["windows"],
- },
- {
sourceName:
/\b(contenteditable|EditorOverride|svg|forms|html|mathml|ua)\.css$/i,
errorMessage: /Unknown pseudo-class.*-moz-/i,
@@ -27,7 +21,7 @@ let ignoreList = [
},
{
sourceName:
- /\b(scrollbars|xul|html|mathml|ua|forms|svg|manageDialog|autocomplete-item-shared|formautofill)\.css$/i,
+ /\b(scrollbars|xul|html|mathml|ua|forms|svg|manageDialog|formautofill)\.css$/i,
errorMessage: /Unknown property.*-moz-/i,
isFromDevTools: false,
},
@@ -42,6 +36,12 @@ let ignoreList = [
errorMessage: /Unknown property.*overflow-clip-box/i,
isFromDevTools: false,
},
+ // content: -moz-alt-content is UA-only.
+ {
+ sourceName: /\b(html)\.css$/i,
+ errorMessage: /Error in parsing value for ‘content’/i,
+ isFromDevTools: false,
+ },
// These variables are declared somewhere else, and error when we load the
// files directly. They're all marked intermittent because their appearance
// in the error console seems to not be consistent.
@@ -123,6 +123,8 @@ let propNameAllowlist = [
isFromDevTools: false,
},
{ propName: "--browser-stack-z-index-rdm-toolbar", isFromDevTools: false },
+ // about:profiling is in devtools even though it uses non-devtools styles.
+ { propName: "--in-content-border-hover", isFromDevTools: false },
// These variables are specified from devtools but read from non-devtools
// styles, which confuses the test.
@@ -434,13 +436,13 @@ add_task(async function checkAllTheCSS() {
let loadCSS = chromeUri =>
new Promise(resolve => {
let linkEl, onLoad, onError;
- onLoad = e => {
+ onLoad = () => {
processCSSRules(linkEl.sheet);
resolve();
linkEl.removeEventListener("load", onLoad);
linkEl.removeEventListener("error", onError);
};
- onError = e => {
+ onError = () => {
ok(
false,
"Loading " + linkEl.getAttribute("href") + " threw an error!"
diff --git a/browser/base/content/test/static/browser_parsable_script.js b/browser/base/content/test/static/browser_parsable_script.js
index d4dcbd87fe..71a2930ddc 100644
--- a/browser/base/content/test/static/browser_parsable_script.js
+++ b/browser/base/content/test/static/browser_parsable_script.js
@@ -19,12 +19,13 @@ const kESModuleList = new Set([
/browser\/vpn-card.js$/,
/toolkit\/content\/global\/certviewer\/components\/.*\.js$/,
/toolkit\/content\/global\/certviewer\/.*\.js$/,
+ /toolkit\/content\/global\/ml\/transformers.*\.js$/,
/chrome\/pdfjs\/content\/web\/.*\.js$/,
]);
-// Normally we would use reflect.jsm to get Reflect.parse. However, if
-// we do that, then all the AST data is allocated in reflect.jsm's
-// zone. That exposes a bug in our GC. The GC collects reflect.jsm's
+// Normally we would use reflect.sys.mjs to get Reflect.parse. However, if
+// we do that, then all the AST data is allocated in reflect.sys.mjs's
+// zone. That exposes a bug in our GC. The GC collects reflect.sys.mjs's
// zone but not the zone in which our test code lives (since no new
// data is being allocated in it). The cross-compartment wrappers in
// our zone that point to the AST data never get collected, and so the
@@ -69,7 +70,7 @@ function uriIsESModule(uri) {
}
function parsePromise(uri, parseTarget) {
- let promise = new Promise((resolve, reject) => {
+ let promise = new Promise(resolve => {
let xhr = new XMLHttpRequest();
xhr.open("GET", uri, true);
xhr.onreadystatechange = function () {
diff --git a/browser/base/content/test/static/browser_sentence_case_strings.js b/browser/base/content/test/static/browser_sentence_case_strings.js
index e995f76b1a..12952c9600 100644
--- a/browser/base/content/test/static/browser_sentence_case_strings.js
+++ b/browser/base/content/test/static/browser_sentence_case_strings.js
@@ -103,7 +103,7 @@ function checkSubheaders(view) {
}
async function checkUpdateBanner(view) {
- let banner = view.querySelector("#appMenu-proton-update-banner");
+ let banner = view.querySelector("#appMenu-update-banner");
const notifications = [
"update-downloading",
diff --git a/browser/base/content/test/static/head.js b/browser/base/content/test/static/head.js
index d9b978e853..317ad430af 100644
--- a/browser/base/content/test/static/head.js
+++ b/browser/base/content/test/static/head.js
@@ -135,7 +135,7 @@ function* generateEntriesFromJarFile(jarFile, extension) {
}
function fetchFile(uri) {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
let xhr = new XMLHttpRequest();
xhr.responseType = "text";
xhr.open("GET", uri, true);
diff --git a/browser/base/content/test/sync/browser_contextmenu_sendpage.js b/browser/base/content/test/sync/browser_contextmenu_sendpage.js
index a80cf8a1d0..14b5f72860 100644
--- a/browser/base/content/test/sync/browser_contextmenu_sendpage.js
+++ b/browser/base/content/test/sync/browser_contextmenu_sendpage.js
@@ -93,47 +93,44 @@ add_task(async function test_link_contextmenu() {
"context-sendlinktodevice-popup"
);
- let expectedArray = ["context-openlinkintab"];
-
- if (
+ const expectOpenLinkInUserContextMenu =
Services.prefs.getBoolPref("privacy.userContext.enabled") &&
- ContextualIdentityService.getPublicIdentities().length
- ) {
- expectedArray.push("context-openlinkinusercontext-menu");
- }
+ ContextualIdentityService.getPublicIdentities().length;
+
+ const expectStripOnShareLink = Services.prefs.getBoolPref(
+ "privacy.query_stripping.strip_on_share.enabled"
+ );
+
+ const expectTranslateSelection =
+ Services.prefs.getBoolPref("browser.translations.enable") &&
+ Services.prefs.getBoolPref("browser.translations.select.enable");
- expectedArray.push(
+ const expectInspectAccessibility =
+ Services.prefs.getBoolPref("devtools.accessibility.enabled", true) &&
+ (Services.prefs.getBoolPref("devtools.everOpened", false) ||
+ Services.prefs.getIntPref("devtools.selfxss.count", 0) > 0);
+
+ const expectedArray = [
+ "context-openlinkintab",
+ ...(expectOpenLinkInUserContextMenu
+ ? ["context-openlinkinusercontext-menu"]
+ : []),
"context-openlink",
"context-openlinkprivate",
"context-sep-open",
"context-bookmarklink",
"context-savelink",
"context-savelinktopocket",
- "context-copylink"
- );
-
- if (
- Services.prefs.getBoolPref("privacy.query_stripping.strip_on_share.enabled")
- ) {
- expectedArray.push("context-stripOnShareLink");
- }
-
- expectedArray.push(
+ "context-copylink",
+ ...(expectStripOnShareLink ? ["context-stripOnShareLink"] : []),
"context-sendlinktodevice",
"context-sep-sendlinktodevice",
"context-searchselect",
- "frame-sep"
- );
-
- if (
- Services.prefs.getBoolPref("devtools.accessibility.enabled", true) &&
- (Services.prefs.getBoolPref("devtools.everOpened", false) ||
- Services.prefs.getIntPref("devtools.selfxss.count", 0) > 0)
- ) {
- expectedArray.push("context-inspect-a11y");
- }
-
- expectedArray.push("context-inspect");
+ ...(expectTranslateSelection ? ["context-translate-selection"] : []),
+ "frame-sep",
+ ...(expectInspectAccessibility ? ["context-inspect-a11y"] : []),
+ "context-inspect",
+ ];
let menu = document.getElementById("contentAreaContextMenu");
diff --git a/browser/base/content/test/sync/browser_contextmenu_sendtab.js b/browser/base/content/test/sync/browser_contextmenu_sendtab.js
index 4922869c1d..bc49680e37 100644
--- a/browser/base/content/test/sync/browser_contextmenu_sendtab.js
+++ b/browser/base/content/test/sync/browser_contextmenu_sendtab.js
@@ -323,7 +323,7 @@ async function openTabContextMenu(openSubmenuId = null) {
function promiseObserver(topic) {
return new Promise(resolve => {
- let obs = (aSubject, aTopic, aData) => {
+ let obs = (aSubject, aTopic) => {
Services.obs.removeObserver(obs, aTopic);
resolve(aSubject);
};
diff --git a/browser/base/content/test/sync/browser_fxa_web_channel.js b/browser/base/content/test/sync/browser_fxa_web_channel.js
index c232f26f26..23c5510422 100644
--- a/browser/base/content/test/sync/browser_fxa_web_channel.js
+++ b/browser/base/content/test/sync/browser_fxa_web_channel.js
@@ -27,7 +27,7 @@ var gTests = [
content_uri: TEST_HTTP_PATH,
channel_id: TEST_CHANNEL_ID,
});
- let promiseObserver = new Promise((resolve, reject) => {
+ let promiseObserver = new Promise(resolve => {
makeObserver(
ON_PROFILE_CHANGE_NOTIFICATION,
function (subject, topic, data) {
@@ -52,7 +52,7 @@ var gTests = [
{
desc: "fxa web channel - login messages should notify the fxAccounts object",
async run() {
- let promiseLogin = new Promise((resolve, reject) => {
+ let promiseLogin = new Promise(resolve => {
let login = accountData => {
Assert.equal(typeof accountData.authAt, "number");
Assert.equal(accountData.email, "testuser@testuser.com");
@@ -91,7 +91,7 @@ var gTests = [
async run() {
let properUrl = TEST_BASE_URL + "?can_link_account";
- let promiseEcho = new Promise((resolve, reject) => {
+ let promiseEcho = new Promise(resolve => {
let webChannelOrigin = Services.io.newURI(properUrl);
// responses sent to content are echoed back over the
// `fxaccounts_webchannel_response_echo` channel. Ensure the
@@ -100,7 +100,7 @@ var gTests = [
"fxaccounts_webchannel_response_echo",
webChannelOrigin
);
- echoWebChannel.listen((webChannelId, message, target) => {
+ echoWebChannel.listen((webChannelId, message) => {
Assert.equal(message.command, "fxaccounts:can_link_account");
Assert.equal(message.messageId, 2);
Assert.equal(message.data.ok, true);
@@ -136,7 +136,7 @@ var gTests = [
{
desc: "fxa web channel - logout messages should notify the fxAccounts object",
async run() {
- let promiseLogout = new Promise((resolve, reject) => {
+ let promiseLogout = new Promise(resolve => {
let logout = uid => {
Assert.equal(uid, "uid");
@@ -167,7 +167,7 @@ var gTests = [
{
desc: "fxa web channel - delete messages should notify the fxAccounts object",
async run() {
- let promiseDelete = new Promise((resolve, reject) => {
+ let promiseDelete = new Promise(resolve => {
let logout = uid => {
Assert.equal(uid, "uid");
@@ -199,8 +199,8 @@ var gTests = [
desc: "fxa web channel - firefox_view messages should call the openFirefoxView helper",
async run() {
let wasCalled = false;
- let promiseMessageHandled = new Promise((resolve, reject) => {
- let openFirefoxView = (browser, entryPoint) => {
+ let promiseMessageHandled = new Promise(resolve => {
+ let openFirefoxView = browser => {
wasCalled = true;
Assert.ok(
!!browser.ownerGlobal,
diff --git a/browser/base/content/test/sync/browser_sync.js b/browser/base/content/test/sync/browser_sync.js
index 168c6f22b0..03077ea67c 100644
--- a/browser/base/content/test/sync/browser_sync.js
+++ b/browser/base/content/test/sync/browser_sync.js
@@ -607,17 +607,20 @@ add_task(async function test_experiment_ui_state_unconfigured() {
checkFxAAvatar("not_configured");
let expectedLabel = gSync.fluentStrings.formatValueSync(
- "appmenuitem-sign-in-account"
+ "synced-tabs-fxa-sign-in"
+ );
+
+ let expectedDescriptionLabel = gSync.fluentStrings.formatValueSync(
+ "fxa-menu-sync-description"
);
await openMainPanel();
checkFxaToolbarButtonPanel({
headerTitle: expectedLabel,
- headerDescription: "",
+ headerDescription: expectedDescriptionLabel,
enabledItems: [
"PanelUI-fxa-cta-menu",
- "PanelUI-fxa-menu-sync-button",
"PanelUI-fxa-menu-monitor-button",
"PanelUI-fxa-menu-relay-button",
"PanelUI-fxa-menu-vpn-button",
@@ -690,7 +693,6 @@ add_task(async function test_experiment_ui_state_signedin() {
"PanelUI-fxa-menu-sync-prefs-button",
"PanelUI-fxa-menu-account-signout-button",
"PanelUI-fxa-cta-menu",
- "PanelUI-fxa-menu-sync-button",
"PanelUI-fxa-menu-monitor-button",
"PanelUI-fxa-menu-relay-button",
"PanelUI-fxa-menu-vpn-button",
@@ -772,7 +774,7 @@ function checkSyncNowButtons(syncing, tooltip = null) {
for (const syncButton of syncButtons) {
is(
syncButton.getAttribute("syncstatus"),
- syncing ? "active" : "",
+ syncing ? "active" : null,
"button active has the right value"
);
if (tooltip) {
@@ -894,7 +896,7 @@ function checkItemsVisibilities(itemsIds, expectedShownItemId) {
function promiseObserver(topic) {
return new Promise(resolve => {
- let obs = (aSubject, aTopic, aData) => {
+ let obs = (aSubject, aTopic) => {
Services.obs.removeObserver(obs, aTopic);
resolve(aSubject);
};
diff --git a/browser/base/content/test/tabPrompts/browser.toml b/browser/base/content/test/tabPrompts/browser.toml
index 037f1f0d2b..aa7d4c724e 100644
--- a/browser/base/content/test/tabPrompts/browser.toml
+++ b/browser/base/content/test/tabPrompts/browser.toml
@@ -39,6 +39,8 @@ support-files = ["file_beforeunload_stop.html"]
https_first_disabled = true
support-files = ["openPromptOffTimeout.html"]
+["browser_promptDelays.js"]
+
["browser_promptFocus.js"]
["browser_prompt_close_event.js"]
diff --git a/browser/base/content/test/tabPrompts/browser_abort_when_in_modal_state.js b/browser/base/content/test/tabPrompts/browser_abort_when_in_modal_state.js
index cb3a1f72d6..d6d2434017 100644
--- a/browser/base/content/test/tabPrompts/browser_abort_when_in_modal_state.js
+++ b/browser/base/content/test/tabPrompts/browser_abort_when_in_modal_state.js
@@ -8,14 +8,10 @@ const { PromiseTestUtils } = ChromeUtils.importESModule(
);
/**
- * Check that if we're using a window-modal prompt,
- * the next synchronous window-internal modal prompt aborts rather than
- * leaving us in a deadlock about how to enter modal state.
+ * Check that the next synchronous window-internal modal prompt aborts rather
+ * than leaving us in a deadlock about how to enter modal state.
*/
add_task(async function test_check_multiple_prompts() {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
let container = document.getElementById("window-modal-dialog");
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
diff --git a/browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js b/browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js
index 86d7c992c5..1211694973 100644
--- a/browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js
+++ b/browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js
@@ -119,7 +119,7 @@ async function waitForDialog(doConfirmPrompt, crossDomain, prefEnabled) {
} else {
Assert.equal(
dialog._overlay.getAttribute("hideContent"),
- "",
+ null,
"Dialog overlay does not hide the current sites content"
);
Assert.equal(
@@ -137,7 +137,7 @@ async function waitForDialog(doConfirmPrompt, crossDomain, prefEnabled) {
} else {
Assert.equal(
dialog._overlay.getAttribute("hideContent"),
- "",
+ null,
"Dialog overlay does not hide the current sites content"
);
Assert.equal(
diff --git a/browser/base/content/test/tabPrompts/browser_contentOrigins.js b/browser/base/content/test/tabPrompts/browser_contentOrigins.js
index 2bf4ba6039..0c40763a99 100644
--- a/browser/base/content/test/tabPrompts/browser_contentOrigins.js
+++ b/browser/base/content/test/tabPrompts/browser_contentOrigins.js
@@ -127,12 +127,6 @@ async function checkDialog(
});
}
-add_setup(async function () {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.modalType.httpAuth", Ci.nsIPrompt.MODAL_TYPE_TAB]],
- });
-});
-
add_task(async function test_check_prompt_origin_display() {
await checkAlert("https://example.com/", { value: "example.com" });
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
diff --git a/browser/base/content/test/tabPrompts/browser_promptDelays.js b/browser/base/content/test/tabPrompts/browser_promptDelays.js
new file mode 100644
index 0000000000..ecd01cdb69
--- /dev/null
+++ b/browser/base/content/test/tabPrompts/browser_promptDelays.js
@@ -0,0 +1,113 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PERMISSION_DIALOG =
+ "chrome://mozapps/content/handling/permissionDialog.xhtml";
+
+add_setup(async function () {
+ // Set a new handler as default.
+ const protoSvc = Cc[
+ "@mozilla.org/uriloader/external-protocol-service;1"
+ ].getService(Ci.nsIExternalProtocolService);
+ let protoInfo = protoSvc.getProtocolHandlerInfo("web+testprotocol");
+ protoInfo.preferredAction = protoInfo.useHelperApp;
+ let handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].createInstance(
+ Ci.nsIWebHandlerApp
+ );
+ handler.uriTemplate = "https://example.com/foobar?uri=%s";
+ handler.name = "Test protocol";
+ let handlers = protoInfo.possibleApplicationHandlers;
+ handlers.appendElement(handler);
+
+ protoInfo.preferredApplicationHandler = handler;
+ protoInfo.alwaysAskBeforeHandling = false;
+
+ const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
+ Ci.nsIHandlerService
+ );
+ handlerSvc.store(protoInfo);
+
+ registerCleanupFunction(() => {
+ handlerSvc.remove(protoInfo);
+ });
+});
+
+add_task(async function test_promptWhileNotForeground() {
+ await BrowserTestUtils.withNewTab("about:blank", async browser => {
+ let windowOpened = BrowserTestUtils.waitForNewWindow();
+ await SpecialPowers.spawn(browser, [], () => {
+ content.eval(`window.open('about:blank', "_blank", "height=600");`);
+ });
+ let otherWin = await windowOpened;
+ info("Opened extra window, now start a prompt.");
+
+ // To ensure we test the delay helper correctly, shorten the delay:
+ await SpecialPowers.pushPrefEnv({
+ set: [["security.dialog_enable_delay", 50]],
+ });
+
+ let promptPromise = BrowserTestUtils.promiseAlertDialogOpen(
+ null,
+ PERMISSION_DIALOG,
+ { isSubDialog: true }
+ );
+ await SpecialPowers.spawn(browser, [], () => {
+ content.document.location.href = "web+testprotocol:hello";
+ });
+ info("Started opening prompt.");
+ let prompt = await promptPromise;
+ info("Opened prompt.");
+ let dialog = prompt.document.querySelector("dialog");
+ let button = dialog.getButton("accept");
+ is(button.getAttribute("disabled"), "true", "Button should be disabled");
+
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(r => setTimeout(r, 500));
+ is(
+ button.getAttribute("disabled"),
+ "true",
+ "Button should still be disabled while the dialog is in the background"
+ );
+
+ let buttonGetsEnabled = BrowserTestUtils.waitForMutationCondition(
+ button,
+ { attributeFilter: ["disabled"] },
+ () => button.getAttribute("disabled") != "true"
+ );
+ await BrowserTestUtils.closeWindow(otherWin);
+ info("Waiting for button to be enabled.");
+ await buttonGetsEnabled;
+ ok(true, "The button was enabled.");
+ dialog.cancelDialog();
+
+ await SpecialPowers.popPrefEnv();
+ });
+});
+
+add_task(async function test_promptWhileForeground() {
+ await BrowserTestUtils.withNewTab("about:blank", async browser => {
+ let promptPromise = BrowserTestUtils.promiseAlertDialogOpen(
+ null,
+ PERMISSION_DIALOG,
+ { isSubDialog: true }
+ );
+ await SpecialPowers.spawn(browser, [], () => {
+ content.document.location.href = "web+testprotocol:hello";
+ });
+ info("Started opening prompt.");
+ let prompt = await promptPromise;
+ info("Opened prompt.");
+ let dialog = prompt.document.querySelector("dialog");
+ let button = dialog.getButton("accept");
+ is(button.getAttribute("disabled"), "true", "Button should be disabled");
+ await BrowserTestUtils.waitForMutationCondition(
+ button,
+ { attributeFilter: ["disabled"] },
+ () => button.getAttribute("disabled") != "true"
+ );
+ ok(true, "The button was enabled.");
+ dialog.cancelDialog();
+ });
+});
diff --git a/browser/base/content/test/tabPrompts/browser_promptFocus.js b/browser/base/content/test/tabPrompts/browser_promptFocus.js
index 89ca064c10..cab812f57b 100644
--- a/browser/base/content/test/tabPrompts/browser_promptFocus.js
+++ b/browser/base/content/test/tabPrompts/browser_promptFocus.js
@@ -20,8 +20,7 @@ add_task(async function test_tabdialogbox_tab_switch_focus() {
tabPromises.push(
BrowserTestUtils.openNewForegroundTab(
gBrowser,
- // eslint-disable-next-line @microsoft/sdl/no-insecure-url
- "http://example.com",
+ "https://example.com",
true
)
);
diff --git a/browser/base/content/test/tabPrompts/browser_windowPrompt.js b/browser/base/content/test/tabPrompts/browser_windowPrompt.js
index 535142f485..0aca489b50 100644
--- a/browser/base/content/test/tabPrompts/browser_windowPrompt.js
+++ b/browser/base/content/test/tabPrompts/browser_windowPrompt.js
@@ -7,9 +7,6 @@
* Check that the in-window modal dialogs work correctly.
*/
add_task(async function test_check_window_modal_prompt_service() {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
// Avoid blocking the test on the (sync) alert by sticking it in a timeout:
setTimeout(
@@ -69,9 +66,6 @@ add_task(async function test_check_window_modal_prompt_service() {
* Check that the dialog's own closing methods being invoked don't break things.
*/
add_task(async function test_check_window_modal_prompt_service() {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
// Avoid blocking the test on the (sync) alert by sticking it in a timeout:
setTimeout(
@@ -105,9 +99,6 @@ add_task(async function test_check_window_modal_prompt_service() {
});
add_task(async function test_check_multiple_prompts() {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
let container = document.getElementById("window-modal-dialog");
let dialogPromise = BrowserTestUtils.promiseAlertDialogOpen();
@@ -173,9 +164,6 @@ add_task(async function test_check_minimize_response() {
if (AppConstants.platform == "linux") {
return;
}
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
window,
@@ -235,10 +223,6 @@ add_task(async function test_check_minimize_response() {
* underlying SubDialog has fully opened.
*/
add_task(async function test_closed_callback() {
- await SpecialPowers.pushPrefEnv({
- set: [["prompts.windowPromptSubDialog", true]],
- });
-
let promptClosedPromise = Services.prompt.asyncAlert(
window.browsingContext,
Services.prompt.MODAL_TYPE_INTERNAL_WINDOW,
diff --git a/browser/base/content/test/tabcrashed/browser_aboutRestartRequired.toml b/browser/base/content/test/tabcrashed/browser_aboutRestartRequired.toml
index 88988434fb..8f8648d810 100644
--- a/browser/base/content/test/tabcrashed/browser_aboutRestartRequired.toml
+++ b/browser/base/content/test/tabcrashed/browser_aboutRestartRequired.toml
@@ -14,8 +14,10 @@ prefs = [
#["browser_aboutRestartRequired_buildid_false-positive.js"]
#skip-if = ["win11_2009 && msix && debug"] # bug 1823581
-["browser_aboutRestartRequired_buildid_mismatch.js"]
-skip-if = ["win11_2009 && msix && debug"] # bug 1823581
+# Bug 1888355: re-enable once bug 1877361 is fixed
+#["browser_aboutRestartRequired_buildid_mismatch.js"]
+#skip-if = ["win11_2009 && msix && debug"] # bug 1823581
-["browser_aboutRestartRequired_buildid_no-platform-ini.js"]
-skip-if = ["win11_2009 && msix && debug"] # bug 1823581
+# Bug 1888355: re-enable once bug 1877361 is fixed
+#["browser_aboutRestartRequired_buildid_no-platform-ini.js"]
+#skip-if = ["win11_2009 && msix && debug"] # bug 1823581
diff --git a/browser/base/content/test/tabcrashed/browser_aboutRestartRequired_noForkServer.toml b/browser/base/content/test/tabcrashed/browser_aboutRestartRequired_noForkServer.toml
index ec045ddf79..ddb49a0e26 100644
--- a/browser/base/content/test/tabcrashed/browser_aboutRestartRequired_noForkServer.toml
+++ b/browser/base/content/test/tabcrashed/browser_aboutRestartRequired_noForkServer.toml
@@ -12,3 +12,11 @@ prefs = [
# Bug 1876056: remove once bug 1877361 is fixed
["browser_aboutRestartRequired_buildid_false-positive.js"]
skip-if = ["win11_2009 && msix && debug"] # bug 1823581
+
+# Bug 1888355: re-enable once bug 1877361 is fixed
+["browser_aboutRestartRequired_buildid_mismatch.js"]
+skip-if = ["win11_2009 && msix && debug"] # bug 1823581
+
+# Bug 1888355: re-enable once bug 1877361 is fixed
+["browser_aboutRestartRequired_buildid_no-platform-ini.js"]
+skip-if = ["win11_2009 && msix && debug"] # bug 1823581
diff --git a/browser/base/content/test/tabcrashed/head.js b/browser/base/content/test/tabcrashed/head.js
index bb57c85d6d..b4e9137012 100644
--- a/browser/base/content/test/tabcrashed/head.js
+++ b/browser/base/content/test/tabcrashed/head.js
@@ -117,7 +117,7 @@ async function setupLocalCrashReportServer() {
// reports. This test needs them enabled. The test also needs a mock
// report server, and fortunately one is already set up by toolkit/
// crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
- // which CrashSubmit.jsm uses as a server override.
+ // which CrashSubmit.sys.mjs uses as a server override.
let noReport = Services.env.get("MOZ_CRASHREPORTER_NO_REPORT");
let serverUrl = Services.env.get("MOZ_CRASHREPORTER_URL");
Services.env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
@@ -135,7 +135,7 @@ async function setupLocalCrashReportServer() {
*/
function prepareNoDump() {
let originalGetDumpID = TabCrashHandler.getDumpID;
- TabCrashHandler.getDumpID = function (browser) {
+ TabCrashHandler.getDumpID = function () {
return null;
};
registerCleanupFunction(() => {
@@ -156,11 +156,11 @@ function unsetBuildidMatchDontSendEnv() {
}
function getEventPromise(eventName, eventKind) {
- return new Promise(function (resolve, reject) {
+ return new Promise(function (resolve) {
info("Installing event listener (" + eventKind + ")");
window.addEventListener(
eventName,
- event => {
+ () => {
ok(true, "Received " + eventName + " (" + eventKind + ") event");
info("Call resolve() for " + eventKind + " event");
resolve();
diff --git a/browser/base/content/test/tabs/browser.toml b/browser/base/content/test/tabs/browser.toml
index 1b4a6900bf..8a95c87a6e 100644
--- a/browser/base/content/test/tabs/browser.toml
+++ b/browser/base/content/test/tabs/browser.toml
@@ -30,6 +30,8 @@ skip-if = [
["browser_bfcache_exemption_about_pages.js"]
skip-if = ["!fission"]
+["browser_blank_tab_label.js"]
+
["browser_bug580956.js"]
["browser_bug_1387976_restore_lazy_tab_browser_muted_state.js"]
@@ -76,6 +78,8 @@ support-files = ["tab_that_closes.html"]
["browser_hiddentab_contextmenu.js"]
+["browser_lastSeenActive.js"]
+
["browser_lazy_tab_browser_events.js"]
["browser_link_in_tab_title_and_url_prefilled_blank_page.js"]
@@ -138,6 +142,8 @@ support-files = [
["browser_multiselect_tabs_close.js"]
+["browser_multiselect_tabs_close_duplicate_tabs.js"]
+
["browser_multiselect_tabs_close_other_tabs.js"]
["browser_multiselect_tabs_close_tabs_to_the_left.js"]
diff --git a/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js b/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js
index b782c3aada..fea1de8fe0 100644
--- a/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js
+++ b/browser/base/content/test/tabs/browser_allow_process_switches_despite_related_browser.js
@@ -13,7 +13,7 @@ add_task(async function () {
});
let promiseTab = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI_SOURCE);
- BrowserViewSource(tab.linkedBrowser);
+ BrowserCommands.viewSource(tab.linkedBrowser);
let viewSourceTab = await promiseTab;
registerCleanupFunction(async function () {
BrowserTestUtils.removeTab(viewSourceTab);
diff --git a/browser/base/content/test/tabs/browser_audioTabIcon.js b/browser/base/content/test/tabs/browser_audioTabIcon.js
index 53b5140abb..c065e2b173 100644
--- a/browser/base/content/test/tabs/browser_audioTabIcon.js
+++ b/browser/base/content/test/tabs/browser_audioTabIcon.js
@@ -396,7 +396,7 @@ async function test_swapped_browser_while_not_playing(oldTab, newBrowser) {
);
let AudioPlaybackPromise = new Promise(resolve => {
- let observer = (subject, topic, data) => {
+ let observer = () => {
ok(false, "Should not see an audio-playback notification");
};
Services.obs.addObserver(observer, "audio-playback");
@@ -443,7 +443,7 @@ async function test_swapped_browser_while_not_playing(oldTab, newBrowser) {
await test_tooltip(newTab.overlayIcon, "Unmute tab", true, newTab);
}
-async function test_browser_swapping(tab, browser) {
+async function test_browser_swapping(tab) {
// First, test swapping with a playing but muted tab.
await play(tab);
diff --git a/browser/base/content/test/tabs/browser_blank_tab_label.js b/browser/base/content/test/tabs/browser_blank_tab_label.js
new file mode 100644
index 0000000000..9fe5f6b1b0
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_blank_tab_label.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Ensure that we don't use an entirely-blank (non-printable) document title
+ * as the tab label.
+ */
+add_task(async function test_ensure_printable_label() {
+ const TEST_DOC = `
+ <!DOCTYPE html>
+ <meta charset="utf-8">
+ <!-- Title is NO-BREAK SPACE, COMBINING ACUTE ACCENT, ARABIC LETTER MARK -->
+ <title>&nbsp;&%23x0301;&%23x061C;</title>
+ Is my title blank?`;
+
+ let newTab;
+ function tabLabelChecker() {
+ Assert.stringMatches(
+ newTab.label,
+ /\p{L}|\p{N}|\p{P}|\p{S}/u,
+ "Tab label should contain printable character."
+ );
+ }
+ let mutationObserver = new MutationObserver(tabLabelChecker);
+ registerCleanupFunction(() => mutationObserver.disconnect());
+
+ gBrowser.tabContainer.addEventListener(
+ "TabOpen",
+ event => {
+ newTab = event.target;
+ tabLabelChecker();
+ mutationObserver.observe(newTab, {
+ attributeFilter: ["label"],
+ });
+ },
+ { once: true }
+ );
+
+ await BrowserTestUtils.withNewTab("data:text/html," + TEST_DOC, async () => {
+ // Wait another longer-than-tick to ensure more mutation observer things have
+ // come in.
+ await new Promise(executeSoon);
+
+ // Check one last time for good measure, for the final label:
+ tabLabelChecker();
+ });
+});
diff --git a/browser/base/content/test/tabs/browser_e10s_about_page_triggeringprincipal.js b/browser/base/content/test/tabs/browser_e10s_about_page_triggeringprincipal.js
index 4610551977..8fbee64db4 100644
--- a/browser/base/content/test/tabs/browser_e10s_about_page_triggeringprincipal.js
+++ b/browser/base/content/test/tabs/browser_e10s_about_page_triggeringprincipal.js
@@ -86,7 +86,7 @@ add_task(async function test_principal_ctrl_click() {
await BrowserTestUtils.withNewTab(
"about:test-about-principal-parent",
- async function (browser) {
+ async function () {
let loadPromise = BrowserTestUtils.waitForNewTab(
gBrowser,
"about:test-about-principal-child",
@@ -149,7 +149,7 @@ add_task(async function test_principal_right_click_open_link_in_new_tab() {
await BrowserTestUtils.withNewTab(
"about:test-about-principal-parent",
- async function (browser) {
+ async function () {
let loadPromise = BrowserTestUtils.waitForNewTab(
gBrowser,
"about:test-about-principal-child",
diff --git a/browser/base/content/test/tabs/browser_e10s_about_process.js b/browser/base/content/test/tabs/browser_e10s_about_process.js
index f73e8e659c..504dfe0265 100644
--- a/browser/base/content/test/tabs/browser_e10s_about_process.js
+++ b/browser/base/content/test/tabs/browser_e10s_about_process.js
@@ -37,7 +37,7 @@ const TEST_MODULES = [
function AboutModule() {}
AboutModule.prototype = {
- newChannel(aURI, aLoadInfo) {
+ newChannel() {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
},
@@ -52,7 +52,7 @@ AboutModule.prototype = {
return 0;
},
- getIndexedDBOriginPostfix(aURI) {
+ getIndexedDBOriginPostfix() {
return null;
},
diff --git a/browser/base/content/test/tabs/browser_lastSeenActive.js b/browser/base/content/test/tabs/browser_lastSeenActive.js
new file mode 100644
index 0000000000..d6bba57d93
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_lastSeenActive.js
@@ -0,0 +1,260 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { SessionStoreTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/SessionStoreTestUtils.sys.mjs"
+);
+
+const triggeringPrincipal_base64 = E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;
+
+SessionStoreTestUtils.init(this, window);
+// take a state snapshot we can restore to after each test
+const ORIG_STATE = SessionStore.getBrowserState();
+
+const SECOND_MS = 1000;
+const DAY_MS = 24 * 60 * 60 * 1000;
+const today = new Date().getTime();
+const yesterday = new Date(Date.now() - DAY_MS).getTime();
+
+function tabEntry(url, lastAccessed) {
+ return {
+ entries: [{ url, triggeringPrincipal_base64 }],
+ lastAccessed,
+ };
+}
+
+/**
+ * Make the given window focused and active
+ */
+async function switchToWindow(win) {
+ info("switchToWindow, waiting for promiseFocus");
+ await SimpleTest.promiseFocus(win);
+ info("switchToWindow, waiting for correct Services.focus.activeWindow");
+ await BrowserTestUtils.waitForCondition(
+ () => Services.focus.activeWindow == win
+ );
+}
+
+async function changeSizeMode(win, mode) {
+ let promise = BrowserTestUtils.waitForEvent(win, "sizemodechange");
+ win[mode]();
+ await promise;
+}
+
+async function cleanup() {
+ await switchToWindow(window);
+ await SessionStoreTestUtils.promiseBrowserState(ORIG_STATE);
+ is(
+ BrowserWindowTracker.orderedWindows.length,
+ 1,
+ "One window at the end of test cleanup"
+ );
+ info("cleanup, browser state restored");
+}
+
+function deltaTime(time, expectedTime) {
+ return Math.abs(expectedTime - time);
+}
+
+function getWindowUrl(win) {
+ return win.gBrowser.selectedBrowser?.currentURI?.spec;
+}
+
+function getWindowByTabUrl(url) {
+ return BrowserWindowTracker.orderedWindows.find(
+ win => getWindowUrl(win) == url
+ );
+}
+
+add_task(async function restoredTabs() {
+ const now = Date.now();
+ await SessionStoreTestUtils.promiseBrowserState({
+ windows: [
+ {
+ tabs: [
+ tabEntry("data:,Window0-Tab0", yesterday),
+ tabEntry("data:,Window0-Tab1", yesterday),
+ ],
+ selected: 2,
+ },
+ ],
+ });
+ is(
+ gBrowser.visibleTabs[1],
+ gBrowser.selectedTab,
+ "The selected tab is the 2nd visible tab"
+ );
+ is(
+ getWindowUrl(window),
+ "data:,Window0-Tab1",
+ "The expected tab is selected"
+ );
+ Assert.greaterOrEqual(
+ gBrowser.selectedTab.lastSeenActive,
+ now,
+ "The selected tab's lastSeenActive is now"
+ );
+ Assert.greaterOrEqual(
+ gBrowser.selectedTab.lastAccessed,
+ now,
+ "The selected tab's lastAccessed is now"
+ );
+
+ // tab restored from session but never seen or active
+ is(
+ gBrowser.visibleTabs[0].lastSeenActive,
+ yesterday,
+ "The restored tab's lastSeenActive is yesterday"
+ );
+ await cleanup();
+});
+
+add_task(async function switchingTabs() {
+ let now = Date.now();
+ let initialTab = gBrowser.selectedTab;
+ let applicationStart = Services.startup.getStartupInfo().start.getTime();
+ let openedTab = BrowserTestUtils.addTab(gBrowser, "data:,Tab1");
+ await BrowserTestUtils.browserLoaded(openedTab.linkedBrowser);
+
+ ok(!openedTab.selected, "The background tab we opened isn't selected");
+ Assert.greaterOrEqual(
+ initialTab.selected && initialTab.lastSeenActive,
+ now,
+ "The initial tab is selected and last seen now"
+ );
+
+ is(
+ openedTab.lastSeenActive,
+ applicationStart,
+ `Background tab got default lastSeenActive value, delta: ${deltaTime(
+ openedTab.lastSeenActive,
+ applicationStart
+ )}`
+ );
+
+ now = Date.now();
+ await BrowserTestUtils.switchTab(gBrowser, openedTab);
+ Assert.greaterOrEqual(
+ openedTab.lastSeenActive,
+ now,
+ "The tab we switched to is last seen now"
+ );
+
+ await cleanup();
+});
+
+add_task(async function switchingWindows() {
+ info("Restoring to the test browser state");
+ await SessionStoreTestUtils.promiseBrowserState({
+ windows: [
+ {
+ tabs: [tabEntry("data:,Window1-Tab0", yesterday)],
+ selected: 1,
+ sizemodeBeforeMinimized: "normal",
+ sizemode: "maximized",
+ zIndex: 1, // this will be the selected window
+ },
+ {
+ tabs: [tabEntry("data:,Window2-Tab0", yesterday)],
+ selected: 1,
+ sizemodeBeforeMinimized: "normal",
+ sizemode: "maximized",
+ zIndex: 2,
+ },
+ ],
+ });
+ info("promiseBrowserState resolved");
+ info(
+ `BrowserWindowTracker.pendingWindows: ${BrowserWindowTracker.pendingWindows.size}`
+ );
+ await Promise.all(
+ Array.from(BrowserWindowTracker.pendingWindows.values()).map(
+ win => win.deferred.promise
+ )
+ );
+ info("All the pending windows are resolved");
+ info("Waiting for the firstBrowserLoaded in each of the windows");
+ await Promise.all(
+ BrowserWindowTracker.orderedWindows.map(win => {
+ const selectedUrl = getWindowUrl(win);
+ if (selectedUrl && selectedUrl !== "about:blank") {
+ return Promise.resolve();
+ }
+ return BrowserTestUtils.firstBrowserLoaded(win, false);
+ })
+ );
+ let expectedTabURLs = ["data:,Window1-Tab0", "data:,Window2-Tab0"];
+ let [win1, win2] = expectedTabURLs.map(url => getWindowByTabUrl(url));
+ if (BrowserWindowTracker.getTopWindow() !== win1) {
+ info("Switch to win1 which isn't active/top after restoring session");
+ // In theory the zIndex values in the session state should make win1 active
+ // But in practice that isn't always true. To ensure we're testing from a known state,
+ // ensure the first window is active before proceeding with the test
+ await switchToWindow(win1);
+ [win1, win2] = expectedTabURLs.map(url => getWindowByTabUrl(url));
+ }
+
+ let actualTabURLs = Array.from(BrowserWindowTracker.orderedWindows).map(win =>
+ getWindowUrl(win)
+ );
+ Assert.deepEqual(
+ actualTabURLs,
+ expectedTabURLs,
+ "Both windows are open with selected tab URLs in the expected order"
+ );
+
+ let lastSeenTimes = [win1, win2].map(
+ win => win.gBrowser.selectedTab.lastSeenActive
+ );
+
+ info("Focusing the other window");
+ await switchToWindow(win2);
+ // wait a little so the timestamps will differ and then check again
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(res => setTimeout(res, 100));
+ Assert.greater(
+ win2.gBrowser.selectedTab.lastSeenActive,
+ lastSeenTimes[1],
+ "The foreground window selected tab is last seen more recently than it was before being focused"
+ );
+ Assert.greater(
+ win2.gBrowser.selectedTab.lastSeenActive,
+ win1.gBrowser.selectedTab.lastSeenActive,
+ "The foreground window selected tab is last seen more recently than the backgrounded one"
+ );
+
+ lastSeenTimes = [win1, win2].map(
+ win => win.gBrowser.selectedTab.lastSeenActive
+ );
+ // minimize the foreground window and focus the other
+ let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
+ win2,
+ "sizemodechange"
+ );
+ win2.minimize();
+ info("Waiting for the sizemodechange on minimized window");
+ await promiseSizeModeChange;
+ await switchToWindow(win1);
+
+ ok(
+ !win2.gBrowser.selectedTab.linkedBrowser.docShellIsActive,
+ "Docshell should be Inactive"
+ );
+ ok(win2.document.hidden, "Minimized windows's document should be hidden");
+
+ // wait a little so the timestamps will differ and then check again
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(res => setTimeout(res, 100));
+ Assert.greater(
+ win1.gBrowser.selectedTab.lastSeenActive,
+ win2.gBrowser.selectedTab.lastSeenActive,
+ "The foreground window selected tab is last seen more recently than the minimized one"
+ );
+ Assert.greater(
+ win1.gBrowser.selectedTab.lastSeenActive,
+ lastSeenTimes[0],
+ "The foreground window selected tab is last seen more recently than it was before being focused"
+ );
+
+ await cleanup();
+});
diff --git a/browser/base/content/test/tabs/browser_lazy_tab_browser_events.js b/browser/base/content/test/tabs/browser_lazy_tab_browser_events.js
index 665bdb7f69..5e09225cde 100644
--- a/browser/base/content/test/tabs/browser_lazy_tab_browser_events.js
+++ b/browser/base/content/test/tabs/browser_lazy_tab_browser_events.js
@@ -93,10 +93,10 @@ add_task(async function test_hidden_muted_lazy_tabs_and_swapping() {
mutedTab.toggleMuteAudio();
gBrowser.hideTab(hiddenTab);
- is(lazyTab.linkedPanel, "", "lazyTab is lazy");
- is(hiddenTab.linkedPanel, "", "hiddenTab is lazy");
- is(mutedTab.linkedPanel, "", "mutedTab is lazy");
- is(normalTab.linkedPanel, "", "normalTab is lazy");
+ is(lazyTab.linkedPanel, null, "lazyTab is lazy");
+ is(hiddenTab.linkedPanel, null, "hiddenTab is lazy");
+ is(mutedTab.linkedPanel, null, "mutedTab is lazy");
+ is(normalTab.linkedPanel, null, "normalTab is lazy");
ok(mutedTab.linkedBrowser.audioMuted, "mutedTab is muted");
ok(hiddenTab.hidden, "hiddenTab is hidden");
@@ -117,7 +117,7 @@ add_task(async function test_hidden_muted_lazy_tabs_and_swapping() {
});
gBrowser.swapBrowsersAndCloseOther(lazyTab, mutedTab);
tabEventTracker.checkExpectations();
- is(lazyTab.linkedPanel, "", "muted lazyTab is still lazy");
+ is(lazyTab.linkedPanel, null, "muted lazyTab is still lazy");
ok(lazyTab.linkedBrowser.audioMuted, "muted lazyTab is now muted");
ok(!lazyTab.hidden, "muted lazyTab is not hidden");
@@ -133,7 +133,7 @@ add_task(async function test_hidden_muted_lazy_tabs_and_swapping() {
});
gBrowser.swapBrowsersAndCloseOther(lazyTab, hiddenTab);
tabEventTracker.checkExpectations();
- is(lazyTab.linkedPanel, "", "hidden lazyTab is still lazy");
+ is(lazyTab.linkedPanel, null, "hidden lazyTab is still lazy");
ok(!lazyTab.linkedBrowser.audioMuted, "hidden lazyTab is not muted any more");
ok(lazyTab.hidden, "hidden lazyTab has been hidden");
@@ -149,7 +149,7 @@ add_task(async function test_hidden_muted_lazy_tabs_and_swapping() {
});
gBrowser.swapBrowsersAndCloseOther(lazyTab, normalTab);
tabEventTracker.checkExpectations();
- is(lazyTab.linkedPanel, "", "normal lazyTab is still lazy");
+ is(lazyTab.linkedPanel, null, "normal lazyTab is still lazy");
ok(!lazyTab.linkedBrowser.audioMuted, "normal lazyTab is not muted any more");
ok(!lazyTab.hidden, "normal lazyTab is not hidden any more");
diff --git a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_blank_target.js b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_blank_target.js
index f8773e3720..9212667a35 100644
--- a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_blank_target.js
+++ b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_blank_target.js
@@ -66,7 +66,7 @@ add_task(async function normal_page__foreground__abort() {
tab: WAIT_A_BIT_LOADING_TITLE,
urlbar: UrlbarTestUtils.trimURL(WAIT_A_BIT_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
@@ -160,7 +160,7 @@ add_task(async function normal_page__background__abort() {
tab: WAIT_A_BIT_LOADING_TITLE,
urlbar: UrlbarTestUtils.trimURL(HOME_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
diff --git a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_by_script.js b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_by_script.js
index 07cf7a8ea2..57e28ca834 100644
--- a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_by_script.js
+++ b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_by_script.js
@@ -44,7 +44,7 @@ add_task(async function normal_page__by_script__abort() {
tab: BLANK_TITLE,
urlbar: UrlbarTestUtils.trimURL(BLANK_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
diff --git a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_no_target.js b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_no_target.js
index ab18d7c7e0..464a7c43de 100644
--- a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_no_target.js
+++ b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_no_target.js
@@ -47,7 +47,7 @@ add_task(async function normal_page__no_target__abort() {
tab: HOME_TITLE,
urlbar: UrlbarTestUtils.trimURL(HOME_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
diff --git a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_other_target.js b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_other_target.js
index 7dc0e8fa45..53242ca359 100644
--- a/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_other_target.js
+++ b/browser/base/content/test/tabs/browser_link_in_tab_title_and_url_prefilled_normal_page_other_target.js
@@ -45,7 +45,7 @@ add_task(async function normal_page__other_target__foreground__abort() {
tab: BLANK_TITLE,
urlbar: UrlbarTestUtils.trimURL(BLANK_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
@@ -117,7 +117,7 @@ add_task(async function normal_page__other_target__background__abort() {
tab: WAIT_A_BIT_LOADING_TITLE,
urlbar: UrlbarTestUtils.trimURL(HOME_URL),
},
- async actionWhileLoading(onTabLoaded) {
+ async actionWhileLoading() {
info("Abort loading");
document.getElementById("stop-button").click();
},
diff --git a/browser/base/content/test/tabs/browser_long_data_url_label_truncation.js b/browser/base/content/test/tabs/browser_long_data_url_label_truncation.js
index db0571a2c0..89952b6c4d 100644
--- a/browser/base/content/test/tabs/browser_long_data_url_label_truncation.js
+++ b/browser/base/content/test/tabs/browser_long_data_url_label_truncation.js
@@ -33,7 +33,7 @@ add_task(async function test_ensure_truncation() {
let fileReader = new FileReader();
const DATA_URL = await new Promise(resolve => {
- fileReader.addEventListener("load", e => resolve(fileReader.result));
+ fileReader.addEventListener("load", () => resolve(fileReader.result));
fileReader.readAsDataURL(new Blob([MOBY], { type: "text/html" }));
});
// Substring the full URL to avoid log clutter because Assert will print
diff --git a/browser/base/content/test/tabs/browser_multiselect_tabs_close_duplicate_tabs.js b/browser/base/content/test/tabs/browser_multiselect_tabs_close_duplicate_tabs.js
new file mode 100644
index 0000000000..d18795447f
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_close_duplicate_tabs.js
@@ -0,0 +1,178 @@
+const PREF_WARN_ON_CLOSE = "browser.tabs.warnOnCloseOtherTabs";
+const PREF_SHOWN_DUPE_DIALOG =
+ "browser.tabs.haveShownCloseAllDuplicateTabsWarning";
+
+add_task(async function setPref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ [PREF_WARN_ON_CLOSE, false],
+ [PREF_SHOWN_DUPE_DIALOG, true],
+ ],
+ });
+});
+
+add_task(async function withAMultiSelectedTab() {
+ let initialTab = gBrowser.selectedTab;
+ let tab1 = await addTab();
+ let tab2 = await addTab();
+ let tab3 = await addTab();
+ let tab4 = await addTab();
+
+ is(gBrowser.multiSelectedTabsCount, 0, "Zero multiselected tabs");
+
+ await triggerClickOn(tab1, { ctrlKey: true });
+
+ let tab4Pinned = BrowserTestUtils.waitForEvent(tab4, "TabPinned");
+ gBrowser.pinTab(tab4);
+ await tab4Pinned;
+
+ ok(initialTab.multiselected, "InitialTab is multiselected");
+ ok(tab1.multiselected, "Tab1 is multiselected");
+ ok(!tab2.multiselected, "Tab2 is not multiselected");
+ ok(!tab3.multiselected, "Tab3 is not multiselected");
+ ok(!tab4.multiselected, "Tab4 is not multiselected");
+ ok(tab4.pinned, "Tab4 is pinned");
+ is(gBrowser.multiSelectedTabsCount, 2, "Two multiselected tabs");
+ is(gBrowser.selectedTab, initialTab, "InitialTab is the active tab");
+
+ let closingTabs = [tab2, tab3];
+ let tabClosingPromises = [];
+ for (let tab of closingTabs) {
+ tabClosingPromises.push(BrowserTestUtils.waitForTabClosing(tab));
+ }
+
+ gBrowser.removeDuplicateTabs(tab1);
+
+ await Promise.all(tabClosingPromises);
+
+ ok(!initialTab.closing, "InitialTab is not closing");
+ ok(!tab1.closing, "Tab1 is not closing");
+ ok(tab2.closing, "Tab2 is closing");
+ ok(tab3.closing, "Tab3 is closing");
+ ok(!tab4.closing, "Tab4 is not closing");
+ is(gBrowser.multiSelectedTabsCount, 2, "Two multiselected tabs");
+ is(gBrowser.selectedTab, initialTab, "InitialTab is still the active tab");
+
+ gBrowser.clearMultiSelectedTabs();
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab4);
+});
+
+add_task(async function withNotAMultiSelectedTab() {
+ let initialTab = gBrowser.selectedTab;
+ let tab1 = await addTab("http://mochi.test:8888/");
+ let tab2 = await addTab("http://mochi.test:8888/");
+ let tab3 = await addTab("http://mochi.test:8888/");
+ let tab4 = await addTab("http://mochi.test:8888/");
+ let tab5 = await addTab("http://mochi.test:8888/");
+ let tab6 = await addTab("http://mochi.test:8888/", { userContextId: 1 });
+
+ is(gBrowser.multiSelectedTabsCount, 0, "Zero multiselected tabs");
+
+ await BrowserTestUtils.switchTab(gBrowser, tab1);
+ await triggerClickOn(tab2, { ctrlKey: true });
+ await triggerClickOn(tab5, { ctrlKey: true });
+
+ let tab4Pinned = BrowserTestUtils.waitForEvent(tab4, "TabPinned");
+ gBrowser.pinTab(tab4);
+ await tab4Pinned;
+
+ let tab5Pinned = BrowserTestUtils.waitForEvent(tab5, "TabPinned");
+ gBrowser.pinTab(tab5);
+ await tab5Pinned;
+
+ ok(!initialTab.multiselected, "InitialTab is not multiselected");
+ ok(tab1.multiselected, "Tab1 is multiselected");
+ ok(tab2.multiselected, "Tab2 is multiselected");
+ ok(!tab3.multiselected, "Tab3 is not multiselected");
+ ok(!tab4.multiselected, "Tab4 is not multiselected");
+ ok(tab4.pinned, "Tab4 is pinned");
+ ok(tab5.multiselected, "Tab5 is multiselected");
+ ok(tab5.pinned, "Tab5 is pinned");
+ ok(!tab6.multiselected, "Tab6 is not multiselected");
+ ok(!tab6.pinned, "Tab6 is not pinned");
+ is(gBrowser.multiSelectedTabsCount, 3, "Three multiselected tabs");
+ is(gBrowser.selectedTab, tab1, "Tab1 is the active tab");
+
+ let closingTabs = [tab1, tab2];
+ let tabClosingPromises = [];
+ for (let tab of closingTabs) {
+ tabClosingPromises.push(BrowserTestUtils.waitForTabClosing(tab));
+ }
+
+ await BrowserTestUtils.switchTab(
+ gBrowser,
+ gBrowser.removeDuplicateTabs(tab3)
+ );
+
+ await Promise.all(tabClosingPromises);
+
+ ok(!initialTab.closing, "InitialTab is not closing");
+ ok(tab1.closing, "Tab1 is closing");
+ ok(tab2.closing, "Tab2 is closing");
+ ok(!tab3.closing, "Tab3 is not closing");
+ ok(!tab4.closing, "Tab4 is not closing");
+ ok(!tab5.closing, "Tab5 is not closing");
+ ok(!tab6.closing, "Tab6 is not closing");
+ is(
+ gBrowser.multiSelectedTabsCount,
+ 0,
+ "Zero multiselected tabs, selection is cleared"
+ );
+ is(gBrowser.selectedTab, tab3, "tab3 is the active tab now");
+
+ for (let tab of [tab3, tab4, tab5, tab6]) {
+ BrowserTestUtils.removeTab(tab);
+ }
+});
+
+add_task(async function closeAllDuplicateTabs() {
+ let initialTab = gBrowser.selectedTab;
+ let tab1 = await addTab("http://mochi.test:8888/one");
+ let tab2 = await addTab("http://mochi.test:8888/two", { userContextId: 1 });
+ let tab3 = await addTab("http://mochi.test:8888/one");
+ let tab4 = await addTab("http://mochi.test:8888/two");
+ let tab5 = await addTab("http://mochi.test:8888/one");
+ let tab6 = await addTab("http://mochi.test:8888/two");
+
+ let tab1Pinned = BrowserTestUtils.waitForEvent(tab1, "TabPinned");
+ gBrowser.pinTab(tab1);
+ await tab1Pinned;
+
+ // So we have 1p,2c,1,2,1,2
+ // We expect 1p,2c,X,2,X,X because the pinned 1 will dupe the other two 1,
+ // but the 2c's userContextId makes it unique against the other two 2,
+ // but one of the other two 2 will close.
+
+ // Ensure tab4 remains by making it active more recently than tab6.
+ tab4._lastSeenActive = Date.now(); // as recent as it gets.
+
+ // Assert some preconditions:
+ ok(tab1.pinned, "Tab1 is pinned");
+ Assert.greater(tab4.lastSeenActive, tab6.lastSeenActive);
+
+ let closingTabs = [tab3, tab5, tab6];
+ let tabClosingPromises = [];
+ for (let tab of closingTabs) {
+ tabClosingPromises.push(BrowserTestUtils.waitForTabClosing(tab));
+ }
+
+ await BrowserTestUtils.switchTab(
+ gBrowser,
+ gBrowser.removeAllDuplicateTabs(initialTab)
+ );
+
+ await Promise.all(tabClosingPromises);
+
+ ok(!initialTab.closing, "InitialTab is not closing");
+ ok(!tab1.closing, "Tab1 is not closing");
+ ok(!tab2.closing, "Tab2 is not closing");
+ ok(tab3.closing, "Tab3 is closing");
+ ok(!tab4.closing, "Tab4 is not closing");
+ ok(tab5.closing, "Tab5 is closing");
+ ok(tab6.closing, "Tab6 is closing");
+
+ for (let tab of [tab1, tab2, tab4]) {
+ BrowserTestUtils.removeTab(tab);
+ }
+});
diff --git a/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js b/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js
index d668d21df8..f294769898 100644
--- a/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_move_to_new_window_contextmenu.js
@@ -61,9 +61,9 @@ add_task(async function testLazyTabs() {
await triggerClickOn(oldTabs[i], { ctrlKey: true });
}
- isnot(oldTabs[0].linkedPanel, "", `Old tab 0 shouldn't be lazy`);
+ isnot(oldTabs[0].linkedPanel, null, `Old tab 0 shouldn't be lazy`);
for (let i = 1; i < numTabs; ++i) {
- is(oldTabs[i].linkedPanel, "", `Old tab ${i} should be lazy`);
+ is(oldTabs[i].linkedPanel, null, `Old tab ${i} should be lazy`);
}
is(gBrowser.multiSelectedTabsCount, numTabs, `${numTabs} multiselected tabs`);
@@ -79,11 +79,11 @@ add_task(async function testLazyTabs() {
if (i == 0) {
isnot(
oldTab.linkedPanel,
- "",
+ null,
`Old tab ${i} should continue not being lazy`
);
} else if (i > 0) {
- is(oldTab.linkedPanel, "", `Old tab ${i} should continue being lazy`);
+ is(oldTab.linkedPanel, null, `Old tab ${i} should continue being lazy`);
} else {
return;
}
@@ -101,9 +101,13 @@ add_task(async function testLazyTabs() {
await tabsMoved;
let newTabs = newWindow.gBrowser.tabs;
- isnot(newTabs[0].linkedPanel, "", `New tab 0 should continue not being lazy`);
+ isnot(
+ newTabs[0].linkedPanel,
+ null,
+ `New tab 0 should continue not being lazy`
+ );
for (let i = 1; i < numTabs; ++i) {
- is(newTabs[i].linkedPanel, "", `New tab ${i} should continue being lazy`);
+ is(newTabs[i].linkedPanel, null, `New tab ${i} should continue being lazy`);
}
is(
diff --git a/browser/base/content/test/tabs/browser_new_tab_bookmarks_toolbar_height.js b/browser/base/content/test/tabs/browser_new_tab_bookmarks_toolbar_height.js
index 66258659fd..157254142d 100644
--- a/browser/base/content/test/tabs/browser_new_tab_bookmarks_toolbar_height.js
+++ b/browser/base/content/test/tabs/browser_new_tab_bookmarks_toolbar_height.js
@@ -12,7 +12,7 @@ async function expectHeightChanges(tab, expectedNewHeightChanges, msg) {
let contentObservedHeightChanges = await ContentTask.spawn(
tab.linkedBrowser,
null,
- async args => {
+ async () => {
await new Promise(resolve => content.requestAnimationFrame(resolve));
return content.document.body.innerText;
}
@@ -109,7 +109,7 @@ add_task(async function () {
info("Opening a new tab, making the previous tab non-selected");
await expectBmToolbarVisibilityChange(
() => {
- BrowserOpenTab();
+ BrowserCommands.openTab();
ok(
!tab.selected,
"non-new tab is in the background (not the selected tab)"
diff --git a/browser/base/content/test/tabs/browser_new_tab_in_privilegedabout_process_pref.js b/browser/base/content/test/tabs/browser_new_tab_in_privilegedabout_process_pref.js
index ec11951cb0..568510b20a 100644
--- a/browser/base/content/test/tabs/browser_new_tab_in_privilegedabout_process_pref.js
+++ b/browser/base/content/test/tabs/browser_new_tab_in_privilegedabout_process_pref.js
@@ -159,7 +159,7 @@ add_task(async function process_switching_through_navigation_features() {
assertIsPrivilegedProcess(browser, "new tab opened from about:newtab");
// Check that reload does not break the privileged about: content process affinity.
- BrowserReload();
+ BrowserCommands.reload();
await BrowserTestUtils.browserLoaded(browser, false, ABOUT_NEWTAB);
assertIsPrivilegedProcess(browser, "about:newtab after reload");
diff --git a/browser/base/content/test/tabs/browser_new_tab_url.js b/browser/base/content/test/tabs/browser_new_tab_url.js
index 233cb4e59e..ab00560929 100644
--- a/browser/base/content/test/tabs/browser_new_tab_url.js
+++ b/browser/base/content/test/tabs/browser_new_tab_url.js
@@ -3,7 +3,7 @@
"use strict";
add_task(async function test_browser_open_newtab_default_url() {
- BrowserOpenTab();
+ BrowserCommands.openTab();
const tab = gBrowser.selectedTab;
if (tab.linkedBrowser.currentURI.spec !== window.BROWSER_NEW_TAB_URL) {
@@ -19,7 +19,7 @@ add_task(async function test_browser_open_newtab_default_url() {
add_task(async function test_browser_open_newtab_specific_url() {
const url = "https://example.com";
- BrowserOpenTab({ url });
+ BrowserCommands.openTab({ url });
const tab = gBrowser.selectedTab;
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
diff --git a/browser/base/content/test/tabs/browser_open_newtab_start_observer_notification.js b/browser/base/content/test/tabs/browser_open_newtab_start_observer_notification.js
index cb9fc3c6d7..2bc26cf667 100644
--- a/browser/base/content/test/tabs/browser_open_newtab_start_observer_notification.js
+++ b/browser/base/content/test/tabs/browser_open_newtab_start_observer_notification.js
@@ -9,10 +9,10 @@ add_task(async function test_browser_open_newtab_start_observer_notification() {
Services.obs.addObserver(observe, "browser-open-newtab-start");
});
- // We're calling BrowserOpenTab() (rather the using BrowserTestUtils
+ // We're calling BrowserCommands.openTab() (rather the using BrowserTestUtils
// because we want to be sure that it triggers the event to fire, since
// it's very close to where various user-actions are triggered.
- BrowserOpenTab();
+ BrowserCommands.openTab();
const newTabCreatedPromise = await observerFiredPromise;
const browser = await newTabCreatedPromise;
const tab = gBrowser.selectedTab;
diff --git a/browser/base/content/test/tabs/browser_pinnedTabs_closeByKeyboard.js b/browser/base/content/test/tabs/browser_pinnedTabs_closeByKeyboard.js
index fbcd0bb492..4631afba42 100644
--- a/browser/base/content/test/tabs/browser_pinnedTabs_closeByKeyboard.js
+++ b/browser/base/content/test/tabs/browser_pinnedTabs_closeByKeyboard.js
@@ -5,14 +5,14 @@
function test() {
waitForExplicitFinish();
- function testState(aPinned) {
+ function testState() {
function elemAttr(id, attr) {
return document.getElementById(id).getAttribute(attr);
}
is(
elemAttr("key_close", "disabled"),
- "",
+ null,
"key_closed should always be enabled"
);
is(
diff --git a/browser/base/content/test/tabs/browser_privilegedmozilla_process_pref.js b/browser/base/content/test/tabs/browser_privilegedmozilla_process_pref.js
index 9e1c1ff5cd..922f94b07c 100644
--- a/browser/base/content/test/tabs/browser_privilegedmozilla_process_pref.js
+++ b/browser/base/content/test/tabs/browser_privilegedmozilla_process_pref.js
@@ -140,7 +140,7 @@ add_task(async function process_switching_through_navigation_features() {
);
// Check that reload does not break the privileged mozilla content process affinity.
- BrowserReload();
+ BrowserCommands.reload();
await BrowserTestUtils.browserLoaded(browser, false, TEST_HIGH1);
is(
browser.frameLoader.remoteTab.osPid,
diff --git a/browser/base/content/test/tabs/browser_removeTabs_order.js b/browser/base/content/test/tabs/browser_removeTabs_order.js
index 071cc03716..a993415653 100644
--- a/browser/base/content/test/tabs/browser_removeTabs_order.js
+++ b/browser/base/content/test/tabs/browser_removeTabs_order.js
@@ -16,7 +16,7 @@ add_task(async function () {
// Add a beforeunload event listener in one of the tabs; it should be called
// before closing any of the tabs.
await ContentTask.spawn(tab2.linkedBrowser, null, async function () {
- content.window.addEventListener("beforeunload", function (event) {}, true);
+ content.window.addEventListener("beforeunload", function () {}, true);
});
let permitUnloadSpy = sinon.spy(tab2.linkedBrowser, "asyncPermitUnload");
diff --git a/browser/base/content/test/tabs/browser_tab_label_picture_in_picture.js b/browser/base/content/test/tabs/browser_tab_label_picture_in_picture.js
index dae4ffc444..59cfd37c0d 100644
--- a/browser/base/content/test/tabs/browser_tab_label_picture_in_picture.js
+++ b/browser/base/content/test/tabs/browser_tab_label_picture_in_picture.js
@@ -11,7 +11,7 @@ add_task(async function test_pip_label_changes_tab() {
let pipLabel = pipTab.querySelector(".tab-icon-sound-pip-label");
- await BrowserTestUtils.withNewTab("about:blank", async browser => {
+ await BrowserTestUtils.withNewTab("about:blank", async () => {
let selectedTab = newWin.document.querySelector(
".tabbrowser-tab[selected]"
);
diff --git a/browser/base/content/test/tabs/browser_tab_manager_visibility.js b/browser/base/content/test/tabs/browser_tab_manager_visibility.js
index b7de777512..df6e75cd66 100644
--- a/browser/base/content/test/tabs/browser_tab_manager_visibility.js
+++ b/browser/base/content/test/tabs/browser_tab_manager_visibility.js
@@ -17,7 +17,7 @@ add_task(async function tab_manager_visibility_preference_on() {
gBrowser: newWindow.gBrowser,
url: TEST_HOSTNAME + DUMMY_PAGE_PATH,
},
- async function (browser) {
+ async function () {
await Assert.ok(
BrowserTestUtils.isVisible(
newWindow.document.getElementById("alltabs-button")
@@ -39,7 +39,7 @@ add_task(async function tab_manager_visibility_preference_off() {
gBrowser: newWindow.gBrowser,
url: TEST_HOSTNAME + DUMMY_PAGE_PATH,
},
- async function (browser) {
+ async function () {
await Assert.ok(
BrowserTestUtils.isHidden(
newWindow.document.getElementById("alltabs-button")
diff --git a/browser/base/content/test/tabs/browser_tab_preview.js b/browser/base/content/test/tabs/browser_tab_preview.js
index 718afbb940..19ba85b9f8 100644
--- a/browser/base/content/test/tabs/browser_tab_preview.js
+++ b/browser/base/content/test/tabs/browser_tab_preview.js
@@ -4,14 +4,14 @@
"use strict";
+const { sinon } = ChromeUtils.importESModule(
+ "resource://testing-common/Sinon.sys.mjs"
+);
+
async function openPreview(tab) {
- const previewShown = BrowserTestUtils.waitForEvent(
- document.getElementById("tabbrowser-tab-preview"),
- "previewshown",
- false,
- e => {
- return e.detail.tab === tab;
- }
+ const previewShown = BrowserTestUtils.waitForPopupEvent(
+ document.getElementById("tab-preview-panel"),
+ "shown"
);
EventUtils.synthesizeMouseAtCenter(tab, { type: "mouseover" });
return previewShown;
@@ -19,9 +19,9 @@ async function openPreview(tab) {
async function closePreviews() {
const tabs = document.getElementById("tabbrowser-tabs");
- const previewHidden = BrowserTestUtils.waitForEvent(
- document.getElementById("tabbrowser-tab-preview"),
- "previewhidden"
+ const previewHidden = BrowserTestUtils.waitForPopupEvent(
+ document.getElementById("tab-preview-panel"),
+ "hidden"
);
EventUtils.synthesizeMouse(tabs, 0, tabs.outerHeight + 1, {
type: "mouseout",
@@ -34,6 +34,7 @@ add_setup(async function () {
set: [
["browser.tabs.cardPreview.enabled", true],
["browser.tabs.cardPreview.showThumbnails", false],
+ ["browser.tabs.tooltipsShowPidAndActiveness", false],
["ui.tooltip.delay_ms", 0],
],
});
@@ -53,38 +54,120 @@ add_task(async function hoverTests() {
const tabUrl2 =
"data:text/html,<html><head><title>Second New Tab</title></head><body>Hello</body></html>";
const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl2);
- const previewContainer = document.getElementById("tabbrowser-tab-preview");
+ const previewContainer = document.getElementById("tab-preview-panel");
await openPreview(tab1);
- Assert.ok(
- ["open", "showing"].includes(previewContainer.panel.state),
- "tab1 preview shown"
- );
Assert.equal(
- previewContainer.renderRoot.querySelector(".tab-preview-title").innerText,
+ previewContainer.querySelector(".tab-preview-title").innerText,
"First New Tab",
"Preview of tab1 shows correct title"
);
+ await closePreviews();
await openPreview(tab2);
- Assert.ok(
- ["open", "showing"].includes(previewContainer.panel.state),
- "tab2 preview shown"
- );
Assert.equal(
- previewContainer.renderRoot.querySelector(".tab-preview-title").innerText,
+ previewContainer.querySelector(".tab-preview-title").innerText,
"Second New Tab",
"Preview of tab2 shows correct title"
);
await closePreviews();
- Assert.ok(
- ["closed", "hiding"].includes(previewContainer.panel.state),
- "preview container is now hidden"
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+
+ // Move the mouse outside of the tab strip.
+ EventUtils.synthesizeMouseAtCenter(document.documentElement, {
+ type: "mouseover",
+ });
+});
+
+/**
+ * Verify that the pid and activeness statuses are not shown
+ * when the flag is not enabled.
+ */
+add_task(async function pidAndActivenessHiddenByDefaultTests() {
+ const tabUrl1 =
+ "data:text/html,<html><head><title>First New Tab</title></head><body>Hello</body></html>";
+ const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
+ const previewContainer = document.getElementById("tab-preview-panel");
+
+ await openPreview(tab1);
+ Assert.equal(
+ previewContainer.querySelector(".tab-preview-pid").innerText,
+ "",
+ "Tab PID is not shown"
+ );
+ Assert.equal(
+ previewContainer.querySelector(".tab-preview-activeness").innerText,
+ "",
+ "Tab activeness is not shown"
);
+ await closePreviews();
+
+ BrowserTestUtils.removeTab(tab1);
+
+ // Move the mouse outside of the tab strip.
+ EventUtils.synthesizeMouseAtCenter(document.documentElement, {
+ type: "mouseover",
+ });
+});
+
+add_task(async function pidAndActivenessTests() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.tabs.tooltipsShowPidAndActiveness", true]],
+ });
+
+ const tabUrl1 =
+ "data:text/html,<html><head><title>Single process tab</title></head><body>Hello</body></html>";
+ const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
+ const tabUrl2 = `data:text/html,<html>
+ <head>
+ <title>Multi-process tab</title>
+ </head>
+ <body>
+ <iframe
+ id="inlineFrameExample"
+ title="Inline Frame Example"
+ width="300"
+ height="200"
+ src="https://example.com">
+ </iframe>
+ </body>
+ </html>`;
+ const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl2);
+ const previewContainer = document.getElementById("tab-preview-panel");
+
+ await openPreview(tab1);
+ Assert.stringMatches(
+ previewContainer.querySelector(".tab-preview-pid").innerText,
+ /^pid: \d+$/,
+ "Tab PID is shown on single process tab"
+ );
+ Assert.equal(
+ previewContainer.querySelector(".tab-preview-activeness").innerText,
+ "",
+ "Tab activeness is not shown on inactive tab"
+ );
+ await closePreviews();
+
+ await openPreview(tab2);
+ Assert.stringMatches(
+ previewContainer.querySelector(".tab-preview-pid").innerText,
+ /^pids: \d+, \d+$/,
+ "Tab PIDs are shown on multi-process tab"
+ );
+ Assert.equal(
+ previewContainer.querySelector(".tab-preview-activeness").innerText,
+ "[A]",
+ "Tab activeness is shown on active tab"
+ );
+ await closePreviews();
+
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
+ await SpecialPowers.popPrefEnv();
// Move the mouse outside of the tab strip.
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
@@ -105,29 +188,41 @@ add_task(async function thumbnailTests() {
const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
const tabUrl2 = "about:blank";
const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl2);
- const previewContainer = document.getElementById("tabbrowser-tab-preview");
+ const previewPanel = document.getElementById("tab-preview-panel");
- const thumbnailUpdated = BrowserTestUtils.waitForEvent(
- previewContainer,
- "previewThumbnailUpdated"
+ let thumbnailUpdated = BrowserTestUtils.waitForEvent(
+ previewPanel,
+ "previewThumbnailUpdated",
+ false,
+ evt => evt.detail.thumbnail
);
await openPreview(tab1);
await thumbnailUpdated;
Assert.ok(
- previewContainer.renderRoot.querySelectorAll("img,canvas").length,
+ previewPanel.querySelectorAll(
+ ".tab-preview-thumbnail-container img, .tab-preview-thumbnail-container canvas"
+ ).length,
"Tab1 preview contains thumbnail"
);
+ await closePreviews();
+ thumbnailUpdated = BrowserTestUtils.waitForEvent(
+ previewPanel,
+ "previewThumbnailUpdated"
+ );
await openPreview(tab2);
+ await thumbnailUpdated;
Assert.equal(
- previewContainer.renderRoot.querySelectorAll("img,canvas").length,
+ previewPanel.querySelectorAll(
+ ".tab-preview-thumbnail-container img, .tab-preview-thumbnail-container canvas"
+ ).length,
0,
"Tab2 (selected) does not contain thumbnail"
);
- const previewHidden = BrowserTestUtils.waitForEvent(
- document.getElementById("tabbrowser-tab-preview"),
- "previewhidden"
+ const previewHidden = BrowserTestUtils.waitForPopupEvent(
+ previewPanel,
+ "hidden"
);
BrowserTestUtils.removeTab(tab1);
@@ -144,6 +239,102 @@ add_task(async function thumbnailTests() {
});
/**
+ * make sure delay is applied when mouse leaves tabstrip
+ * but not when moving between tabs on the tabstrip
+ */
+add_task(async function delayTests() {
+ const tabUrl1 =
+ "data:text/html,<html><head><title>First New Tab</title></head><body>Hello</body></html>";
+ const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
+ const tabUrl2 =
+ "data:text/html,<html><head><title>Second New Tab</title></head><body>Hello</body></html>";
+ const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl2);
+ const previewComponent = gBrowser.tabContainer.previewPanel;
+ const previewElement = document.getElementById("tab-preview-panel");
+
+ sinon.spy(previewComponent, "deactivate");
+
+ await openPreview(tab1);
+
+ // I can't fake this like in hoverTests, need to send an updated-tab signal
+ //await openPreview(tab2);
+
+ const previewHidden = BrowserTestUtils.waitForPopupEvent(
+ previewElement,
+ "hidden"
+ );
+ Assert.ok(
+ !previewComponent.deactivate.called,
+ "Delay is not reset when moving between tabs"
+ );
+
+ EventUtils.synthesizeMouseAtCenter(document.getElementById("reload-button"), {
+ type: "mousemove",
+ });
+
+ await previewHidden;
+
+ Assert.ok(
+ previewComponent.deactivate.called,
+ "Delay is reset when cursor leaves tabstrip"
+ );
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+ sinon.restore();
+});
+
+/**
+ * Dragging a tab should deactivate the preview
+ */
+add_task(async function dragTests() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["ui.tooltip.delay_ms", 1000]],
+ });
+ const tabUrl1 =
+ "data:text/html,<html><head><title>First New Tab</title></head><body>Hello</body></html>";
+ const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
+ const tabUrl2 =
+ "data:text/html,<html><head><title>Second New Tab</title></head><body>Hello</body></html>";
+ const tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl2);
+ const previewComponent = gBrowser.tabContainer.previewPanel;
+ const previewElement = document.getElementById("tab-preview-panel");
+
+ sinon.spy(previewComponent, "deactivate");
+
+ await openPreview(tab1);
+ const previewHidden = BrowserTestUtils.waitForPopupEvent(
+ previewElement,
+ "hidden"
+ );
+ let dragend = BrowserTestUtils.waitForEvent(tab1, "dragend");
+ EventUtils.synthesizePlainDragAndDrop({
+ srcElement: tab1,
+ destElement: tab2,
+ });
+
+ await previewHidden;
+
+ Assert.ok(
+ previewComponent.deactivate.called,
+ "delay is reset after drag started"
+ );
+
+ await dragend;
+
+ BrowserTestUtils.removeTab(tab1);
+ BrowserTestUtils.removeTab(tab2);
+ sinon.restore();
+
+ // Move the mouse outside of the tab strip.
+ EventUtils.synthesizeMouseAtCenter(document.documentElement, {
+ type: "mouseover",
+ });
+
+ await SpecialPowers.popPrefEnv();
+});
+
+/**
* Wheel events at the document-level of the window should hide the preview.
*/
add_task(async function wheelTests() {
@@ -155,9 +346,9 @@ add_task(async function wheelTests() {
await openPreview(tab1);
const tabs = document.getElementById("tabbrowser-tabs");
- const previewHidden = BrowserTestUtils.waitForEvent(
- document.getElementById("tabbrowser-tab-preview"),
- "previewhidden"
+ const previewHidden = BrowserTestUtils.waitForPopupEvent(
+ document.getElementById("tab-preview-panel"),
+ "hidden"
);
// Copied from apz_test_native_event_utils.js
diff --git a/browser/base/content/test/tabs/browser_tab_tooltips.js b/browser/base/content/test/tabs/browser_tab_tooltips.js
index ee82816bce..79be4d0a36 100644
--- a/browser/base/content/test/tabs/browser_tab_tooltips.js
+++ b/browser/base/content/test/tabs/browser_tab_tooltips.js
@@ -57,7 +57,7 @@ add_task(async function () {
);
is(
tooltip.getAttribute("position"),
- "",
+ null,
"tooltip position attribute for tab"
);
diff --git a/browser/base/content/test/tabs/browser_tabswitch_select.js b/browser/base/content/test/tabs/browser_tabswitch_select.js
index 3868764bed..b22a75c79c 100644
--- a/browser/base/content/test/tabs/browser_tabswitch_select.js
+++ b/browser/base/content/test/tabs/browser_tabswitch_select.js
@@ -35,7 +35,7 @@ add_task(async function () {
let fullScreenEntered = TestUtils.waitForCondition(
() => document.documentElement.getAttribute("sizemode") == "fullscreen"
);
- BrowserFullScreen();
+ BrowserCommands.fullScreen();
await fullScreenEntered;
tab2.linkedBrowser.focus();
@@ -54,7 +54,7 @@ add_task(async function () {
let fullScreenExited = TestUtils.waitForCondition(
() => document.documentElement.getAttribute("sizemode") != "fullscreen"
);
- BrowserFullScreen();
+ BrowserCommands.fullScreen();
await fullScreenExited;
BrowserTestUtils.removeTab(gBrowser.selectedTab);
diff --git a/browser/base/content/test/tabs/browser_tabswitch_updatecommands.js b/browser/base/content/test/tabs/browser_tabswitch_updatecommands.js
index b5d2762eec..82f9eb871b 100644
--- a/browser/base/content/test/tabs/browser_tabswitch_updatecommands.js
+++ b/browser/base/content/test/tabs/browser_tabswitch_updatecommands.js
@@ -8,7 +8,7 @@ add_task(async function () {
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
let updates = [];
- function countUpdates(event) {
+ function countUpdates() {
updates.push(new Error().stack);
}
let updater = document.getElementById("editMenuCommandSetAll");
diff --git a/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js b/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js
index b5ae94ce84..2c301a400d 100644
--- a/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js
+++ b/browser/base/content/test/tabs/browser_viewsource_of_data_URI_in_file_process.js
@@ -33,7 +33,7 @@ add_task(async function () {
// Make sure we can view-source on the data URI page.
let promiseTab = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI_SOURCE);
- BrowserViewSource(fileBrowser);
+ BrowserCommands.viewSource(fileBrowser);
let viewSourceTab = await promiseTab;
registerCleanupFunction(async function () {
BrowserTestUtils.removeTab(viewSourceTab);
diff --git a/browser/base/content/test/tabs/browser_visibleTabs_contextMenu.js b/browser/base/content/test/tabs/browser_visibleTabs_contextMenu.js
index 202c43ce47..06fdd27d9c 100644
--- a/browser/base/content/test/tabs/browser_visibleTabs_contextMenu.js
+++ b/browser/base/content/test/tabs/browser_visibleTabs_contextMenu.js
@@ -2,11 +2,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/. */
-const remoteClientsFixture = [
- { id: 1, name: "Foo" },
- { id: 2, name: "Bar" },
-];
-
add_task(async function test() {
// There should be one tab when we start the test
let [origTab] = gBrowser.visibleTabs;
@@ -16,9 +11,8 @@ add_task(async function test() {
// Check the context menu with two tabs
updateTabContextMenu(origTab);
- is(
- document.getElementById("context_closeTab").disabled,
- false,
+ ok(
+ !document.getElementById("context_closeTab").disabled,
"Close Tab is enabled"
);
@@ -29,11 +23,14 @@ add_task(async function test() {
// Check the context menu with one tab.
updateTabContextMenu(testTab);
- is(
- document.getElementById("context_closeTab").disabled,
- false,
+ ok(
+ !document.getElementById("context_closeTab").disabled,
"Close Tab is enabled when more than one tab exists"
);
+ ok(
+ !document.getElementById("context_closeDuplicateTabs").disabled,
+ "Close duplicate tabs is enabled when more than one tab with the same URL exists"
+ );
// Add a tab that will get pinned
// So now there's one pinned tab, one visible unpinned tab, and one hidden tab
diff --git a/browser/base/content/test/tabs/browser_window_open_modifiers.js b/browser/base/content/test/tabs/browser_window_open_modifiers.js
index b4376d6824..2ef951efef 100644
--- a/browser/base/content/test/tabs/browser_window_open_modifiers.js
+++ b/browser/base/content/test/tabs/browser_window_open_modifiers.js
@@ -97,7 +97,7 @@ add_task(async function () {
BrowserTestUtils.synthesizeMouseAtCenter(id, { ...event }, browser);
} else {
// Make sure the keyboard activates a simple button on the page.
- await ContentTask.spawn(browser, id, elementId => {
+ await ContentTask.spawn(browser, id, () => {
content.document.querySelector("#focus-result").value = "";
content.document.querySelector("#focus-check").focus();
});
diff --git a/browser/base/content/test/tabs/common_link_in_tab_title_and_url_prefilled.js b/browser/base/content/test/tabs/common_link_in_tab_title_and_url_prefilled.js
index a06b982615..bff14e5ced 100644
--- a/browser/base/content/test/tabs/common_link_in_tab_title_and_url_prefilled.js
+++ b/browser/base/content/test/tabs/common_link_in_tab_title_and_url_prefilled.js
@@ -244,7 +244,7 @@ async function synthesizeMouse(browser, link, event) {
async function waitForNewTabWithLoadRequest() {
return new Promise(resolve =>
gBrowser.addTabsProgressListener({
- onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
+ onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
gBrowser.removeTabsProgressListener(this);
resolve(gBrowser.getTabForBrowser(aBrowser));
diff --git a/browser/base/content/test/webextensions/browser_aboutaddons_blanktab.js b/browser/base/content/test/webextensions/browser_aboutaddons_blanktab.js
index 228fe71815..1e0814ea96 100644
--- a/browser/base/content/test/webextensions/browser_aboutaddons_blanktab.js
+++ b/browser/base/content/test/webextensions/browser_aboutaddons_blanktab.js
@@ -8,7 +8,7 @@ add_task(async function testBlankTabReusedAboutAddons() {
is(browser, gBrowser.selectedBrowser, "New tab is selected");
// Opening about:addons shouldn't change the selected tab.
- BrowserOpenAddonsMgr();
+ BrowserAddonUI.openAddonsMgr();
is(browser, gBrowser.selectedBrowser, "No new tab was opened");
diff --git a/browser/base/content/test/webextensions/browser_extension_sideloading.js b/browser/base/content/test/webextensions/browser_extension_sideloading.js
index 4e1fe07194..5d8f82a178 100644
--- a/browser/base/content/test/webextensions/browser_extension_sideloading.js
+++ b/browser/base/content/test/webextensions/browser_extension_sideloading.js
@@ -16,11 +16,14 @@ const kSideloaded = true;
async function createWebExtension(details) {
let options = {
manifest: {
+ manifest_version: details.manifest_version ?? 2,
+
browser_specific_settings: { gecko: { id: details.id } },
name: details.name,
permissions: details.permissions,
+ host_permissions: details.host_permissions,
},
};
@@ -86,9 +89,10 @@ add_task(async function test_sideloading() {
const ID2 = "addon2@tests.mozilla.org";
await createWebExtension({
+ manifest_version: 3,
id: ID2,
name: "Test 2",
- permissions: ["<all_urls>"],
+ host_permissions: ["<all_urls>"],
});
const ID3 = "addon3@tests.mozilla.org";
@@ -224,7 +228,7 @@ add_task(async function test_sideloading() {
// Close the hamburger menu and go directly to the addons manager
await gCUITestUtils.hideMainMenu();
- win = await BrowserOpenAddonsMgr(VIEW);
+ win = await BrowserAddonUI.openAddonsMgr(VIEW);
await waitAboutAddonsViewLoaded(win.document);
// about:addons addon entry element.
@@ -293,7 +297,7 @@ add_task(async function test_sideloading() {
// Close the hamburger menu and go to the detail page for this addon
await gCUITestUtils.hideMainMenu();
- win = await BrowserOpenAddonsMgr(
+ win = await BrowserAddonUI.openAddonsMgr(
`addons://detail/${encodeURIComponent(ID3)}`
);
diff --git a/browser/base/content/test/webextensions/browser_extension_update_background.js b/browser/base/content/test/webextensions/browser_extension_update_background.js
index 490544b2ec..5619bacb4d 100644
--- a/browser/base/content/test/webextensions/browser_extension_update_background.js
+++ b/browser/base/content/test/webextensions/browser_extension_update_background.js
@@ -87,7 +87,7 @@ async function backgroundUpdateTest(url, id, checkIconFn) {
let addonId = addon.id;
ok(addon, "Addon was installed");
- is(getBadgeStatus(), "", "Should not start out with an addon alert badge");
+ is(getBadgeStatus(), null, "Should not start out with an addon alert badge");
// Trigger an update check and wait for the update for this addon
// to be downloaded.
@@ -156,7 +156,7 @@ async function backgroundUpdateTest(url, id, checkIconFn) {
BrowserTestUtils.removeTab(tab);
// Alert badge and hamburger menu items should be gone
- is(getBadgeStatus(), "", "Addon alert badge should be gone");
+ is(getBadgeStatus(), null, "Addon alert badge should be gone");
await gCUITestUtils.openMainMenu();
addons = PanelUI.addonNotificationContainer;
@@ -205,7 +205,7 @@ async function backgroundUpdateTest(url, id, checkIconFn) {
BrowserTestUtils.removeTab(tab);
- is(getBadgeStatus(), "", "Addon alert badge should be gone");
+ is(getBadgeStatus(), null, "Addon alert badge should be gone");
await addon.uninstall();
await SpecialPowers.popPrefEnv();
diff --git a/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js b/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js
index a0b10c82e2..204e7fb44a 100644
--- a/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js
+++ b/browser/base/content/test/webextensions/browser_extension_update_background_noprompt.js
@@ -81,7 +81,7 @@ async function testNoPrompt(origUrl, id) {
await updatePromise;
// There should be no notifications about the update
- is(getBadgeStatus(), "", "Should not have addon alert badge");
+ is(getBadgeStatus(), null, "Should not have addon alert badge");
await gCUITestUtils.openMainMenu();
let addons = PanelUI.addonNotificationContainer;
diff --git a/browser/base/content/test/webextensions/browser_legacy_webext.xpi b/browser/base/content/test/webextensions/browser_legacy_webext.xpi
index a3bdf6f832..afd0a8bcee 100644
--- a/browser/base/content/test/webextensions/browser_legacy_webext.xpi
+++ b/browser/base/content/test/webextensions/browser_legacy_webext.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_permissions_installTrigger.js b/browser/base/content/test/webextensions/browser_permissions_installTrigger.js
index a227518ebb..36b4efff8b 100644
--- a/browser/base/content/test/webextensions/browser_permissions_installTrigger.js
+++ b/browser/base/content/test/webextensions/browser_permissions_installTrigger.js
@@ -9,6 +9,12 @@ async function installTrigger(filename) {
["extensions.InstallTriggerImpl.enabled", true],
// Relax the user input requirements while running this test.
["xpinstall.userActivation.required", false],
+ // This test asserts that the extension icon is in the install dialog
+ // and so it requires the signature checks to be enabled (otherwise the
+ // extension icon is expected to be replaced by a warning icon) and the
+ // two test extension used by this test (browser_webext_nopermissions.xpi
+ // and browser_webext_permissions.xpi) are signed using AMO stage signatures.
+ ["xpinstall.signatures.dev-root", true],
],
});
BrowserTestUtils.startLoadingURIString(
diff --git a/browser/base/content/test/webextensions/browser_permissions_local_file.js b/browser/base/content/test/webextensions/browser_permissions_local_file.js
index 7f8f256e14..731e8adea7 100644
--- a/browser/base/content/test/webextensions/browser_permissions_local_file.js
+++ b/browser/base/content/test/webextensions/browser_permissions_local_file.js
@@ -14,7 +14,9 @@ async function installFile(filename) {
MockFilePicker.setFiles([file]);
MockFilePicker.afterOpenCallback = MockFilePicker.cleanup;
- let { document } = await BrowserOpenAddonsMgr("addons://list/extension");
+ let { document } = await BrowserAddonUI.openAddonsMgr(
+ "addons://list/extension"
+ );
// Do the install...
await waitAboutAddonsViewLoaded(document);
@@ -32,9 +34,22 @@ add_task(async function test_install_extension_from_local_file() {
},
});
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // This test asserts that the extension icon is in the install dialog
+ // and so it requires the signature checks to be enabled (otherwise the
+ // extension icon is expected to be replaced by a warning icon) and the
+ // two test extension used by this test (browser_webext_nopermissions.xpi
+ // and browser_webext_permissions.xpi) are signed using AMO stage signatures.
+ ["xpinstall.signatures.dev-root", true],
+ ],
+ });
+
// Install the add-ons.
await testInstallMethod(installFile, "installLocal");
+ await SpecialPowers.popPrefEnv();
+
// Check we got an installId.
ok(
firstInstallId != null && !isNaN(firstInstallId),
diff --git a/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js b/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js
index 55a578221d..d54038bffe 100644
--- a/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js
+++ b/browser/base/content/test/webextensions/browser_permissions_mozAddonManager.js
@@ -9,6 +9,17 @@ async function installMozAM(filename) {
);
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // This test asserts that the extension icon is in the install dialog
+ // and so it requires the signature checks to be enabled (otherwise the
+ // extension icon is expected to be replaced by a warning icon) and the
+ // two test extension used by this test (browser_webext_nopermissions.xpi
+ // and browser_webext_permissions.xpi) are signed using AMO stage signatures.
+ ["xpinstall.signatures.dev-root", true],
+ ],
+ });
+
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[`${BASE}/${filename}`],
@@ -16,6 +27,8 @@ async function installMozAM(filename) {
await content.wrappedJSObject.installMozAM(url);
}
);
+
+ await SpecialPowers.popPrefEnv();
}
add_task(() => testInstallMethod(installMozAM, "installAmo"));
diff --git a/browser/base/content/test/webextensions/browser_permissions_pointerevent.js b/browser/base/content/test/webextensions/browser_permissions_pointerevent.js
index 188aa8e3bf..2809ffe9b4 100644
--- a/browser/base/content/test/webextensions/browser_permissions_pointerevent.js
+++ b/browser/base/content/test/webextensions/browser_permissions_pointerevent.js
@@ -9,15 +9,15 @@ add_task(async function test_pointerevent() {
e.preventDefault();
});
- document.addEventListener("mousedown", e => {
+ document.addEventListener("mousedown", () => {
browser.test.assertTrue(true, "Should receive mousedown");
});
- document.addEventListener("mouseup", e => {
+ document.addEventListener("mouseup", () => {
browser.test.assertTrue(true, "Should receive mouseup");
});
- document.addEventListener("pointerup", e => {
+ document.addEventListener("pointerup", () => {
browser.test.assertTrue(true, "Should receive pointerup");
browser.test.sendMessage("done");
});
diff --git a/browser/base/content/test/webextensions/browser_update_checkForUpdates.js b/browser/base/content/test/webextensions/browser_update_checkForUpdates.js
index b902527cae..c9e59556e1 100644
--- a/browser/base/content/test/webextensions/browser_update_checkForUpdates.js
+++ b/browser/base/content/test/webextensions/browser_update_checkForUpdates.js
@@ -3,7 +3,7 @@ function checkAll(win) {
triggerPageOptionsAction(win, "check-for-updates");
return new Promise(resolve => {
let observer = {
- observe(subject, topic, data) {
+ observe() {
Services.obs.removeObserver(observer, "EM-update-check-finished");
resolve();
},
diff --git a/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js b/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
index 0b0b912503..9ad3deaae1 100644
--- a/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
+++ b/browser/base/content/test/webextensions/browser_update_interactive_noprompt.js
@@ -36,7 +36,7 @@ async function testUpdateNoPrompt(
is(addon.version, initialVersion, "Version 1 of the addon is installed");
// Go to Extensions in about:addons
- let win = await BrowserOpenAddonsMgr("addons://list/extension");
+ let win = await BrowserAddonUI.openAddonsMgr("addons://list/extension");
await waitAboutAddonsViewLoaded(win.document);
diff --git a/browser/base/content/test/webextensions/browser_webext_nopermissions.xpi b/browser/base/content/test/webextensions/browser_webext_nopermissions.xpi
index ab97d96a11..87500ceb38 100644
--- a/browser/base/content/test/webextensions/browser_webext_nopermissions.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_nopermissions.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_permissions.xpi b/browser/base/content/test/webextensions/browser_webext_permissions.xpi
index a8c8c38ef8..8149ce7b6b 100644
--- a/browser/base/content/test/webextensions/browser_webext_permissions.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_permissions.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update1.xpi b/browser/base/content/test/webextensions/browser_webext_update1.xpi
index 086b3839b9..66ad3e1b31 100644
--- a/browser/base/content/test/webextensions/browser_webext_update1.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update1.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update2.xpi b/browser/base/content/test/webextensions/browser_webext_update2.xpi
index 19967c39c0..a120a64c6d 100644
--- a/browser/base/content/test/webextensions/browser_webext_update2.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update2.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update_icon1.xpi b/browser/base/content/test/webextensions/browser_webext_update_icon1.xpi
index 24cb7616d2..040f8f8c97 100644
--- a/browser/base/content/test/webextensions/browser_webext_update_icon1.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update_icon1.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update_icon2.xpi b/browser/base/content/test/webextensions/browser_webext_update_icon2.xpi
index fd9cf7eb0e..0b13e7c7dd 100644
--- a/browser/base/content/test/webextensions/browser_webext_update_icon2.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update_icon2.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update_perms1.xpi b/browser/base/content/test/webextensions/browser_webext_update_perms1.xpi
index f4942f9082..60b6643a12 100644
--- a/browser/base/content/test/webextensions/browser_webext_update_perms1.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update_perms1.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/browser_webext_update_perms2.xpi b/browser/base/content/test/webextensions/browser_webext_update_perms2.xpi
index 2c023edc9d..64c2afb473 100644
--- a/browser/base/content/test/webextensions/browser_webext_update_perms2.xpi
+++ b/browser/base/content/test/webextensions/browser_webext_update_perms2.xpi
Binary files differ
diff --git a/browser/base/content/test/webextensions/head.js b/browser/base/content/test/webextensions/head.js
index 84f7cd02d7..f364dbed88 100644
--- a/browser/base/content/test/webextensions/head.js
+++ b/browser/base/content/test/webextensions/head.js
@@ -302,7 +302,7 @@ function checkNotification(panel, checkIcon, permissions, sideloaded) {
*
* @returns {Promise}
*/
-async function testInstallMethod(installFn, telemetryBase) {
+async function testInstallMethod(installFn) {
const PERMS_XPI = "browser_webext_permissions.xpi";
const NO_PERMS_XPI = "browser_webext_nopermissions.xpi";
const ID = "permissions@test.mozilla.org";
@@ -508,7 +508,7 @@ async function interactiveUpdateTest(autoUpdate, checkFn) {
ok(addon, "Addon was installed");
is(addon.version, "1.0", "Version 1 of the addon is installed");
- let win = await BrowserOpenAddonsMgr("addons://list/extension");
+ let win = await BrowserAddonUI.openAddonsMgr("addons://list/extension");
await waitAboutAddonsViewLoaded(win.document);
diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
index dd20a672c3..f1052565b8 100644
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
@@ -58,7 +58,7 @@ var gTests = [
);
is(
gBrowser.selectedTab.getAttribute("sharing"),
- "",
+ null,
"the new tab doesn't have the 'sharing' attribute"
);
is(
@@ -89,7 +89,7 @@ var gTests = [
await TestUtils.waitForCondition(() => !tab.getAttribute("sharing"));
is(
tab.getAttribute("sharing"),
- "",
+ null,
"the tab no longer has the 'sharing' attribute after closing the stream"
);
}
diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_by_device_id.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_by_device_id.js
index 3e5ca0668a..9598bb565c 100644
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_by_device_id.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_by_device_id.js
@@ -49,7 +49,7 @@ add_task(async function test_get_user_media_by_device_id() {
.filter(d => d.kind == "videoinput")
.map(d => d.deviceId)[0];
- await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
+ await BrowserTestUtils.withNewTab(TEST_PAGE, async () => {
let promise = promisePopupNotificationShown("webRTC-shareDevices");
let observerPromise = expectObserverCalled("getUserMedia:request");
await promiseRequestDevice({ deviceId: { exact: audioId } });
diff --git a/browser/base/content/test/webrtc/browser_devices_get_user_media_grace.js b/browser/base/content/test/webrtc/browser_devices_get_user_media_grace.js
index 0df69bb9da..624bc07ce0 100644
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_grace.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_grace.js
@@ -171,7 +171,7 @@ var gTests = [
{
desc: "getUserMedia camera+mic survives page reload but not past grace",
- run: async function checkAudioVideoGracePastReload(browser) {
+ run: async function checkAudioVideoGracePastReload() {
await prompt(true, true);
await allow(true, true);
await closeStream();
@@ -240,7 +240,7 @@ var gTests = [
info("Open same page in a new tab");
await disableObserverVerification();
- await BrowserTestUtils.withNewTab(SAME_ORIGIN + PATH, async browser => {
+ await BrowserTestUtils.withNewTab(SAME_ORIGIN + PATH, async () => {
info("In new tab, gUM(camera+mic) causes a prompt.");
await prompt(true, true);
});
@@ -329,7 +329,7 @@ var gTests = [
{
desc: "getUserMedia camera+mic grace period cleared on permission block",
- run: async function checkAudioVideoGraceEndsNewTab(browser) {
+ run: async function checkAudioVideoGraceEndsNewTab() {
await SpecialPowers.pushPrefEnv({
set: [["privacy.webrtc.deviceGracePeriodTimeoutMs", 10000]],
});
diff --git a/browser/base/content/test/webrtc/browser_devices_select_audio_output.js b/browser/base/content/test/webrtc/browser_devices_select_audio_output.js
index fbced1f5cc..df75f39a1a 100644
--- a/browser/base/content/test/webrtc/browser_devices_select_audio_output.js
+++ b/browser/base/content/test/webrtc/browser_devices_select_audio_output.js
@@ -220,7 +220,7 @@ var gTests = [
gBrowser.selectedBrowser.browsingContext,
"getUserMedia:response:allow",
1,
- (aSubject, aTopic, aData) => {
+ aSubject => {
const device = aSubject
.QueryInterface(Ci.nsIArrayExtensions)
.GetElementAt(0).wrappedJSObject;
diff --git a/browser/base/content/test/webrtc/browser_webrtc_hooks.js b/browser/base/content/test/webrtc/browser_webrtc_hooks.js
index e980b15286..3fb2fc9f8d 100644
--- a/browser/base/content/test/webrtc/browser_webrtc_hooks.js
+++ b/browser/base/content/test/webrtc/browser_webrtc_hooks.js
@@ -122,7 +122,7 @@ var gTests = [
run: async function testDeferredBlocker(browser) {
Events.on();
- let blocker = params => Promise.resolve("allow");
+ let blocker = () => Promise.resolve("allow");
webrtcUI.addPeerConnectionBlocker(blocker);
await tryPeerConnection(browser);
@@ -138,7 +138,7 @@ var gTests = [
run: async function testBlockerDeny(browser) {
Events.on();
- let blocker = params => "deny";
+ let blocker = () => "deny";
webrtcUI.addPeerConnectionBlocker(blocker);
await tryPeerConnection(browser, "NotAllowedError");
@@ -156,14 +156,14 @@ var gTests = [
Events.on();
let blocker1Called = false,
- blocker1 = params => {
+ blocker1 = () => {
blocker1Called = true;
return "allow";
};
webrtcUI.addPeerConnectionBlocker(blocker1);
let blocker2Called = false,
- blocker2 = params => {
+ blocker2 = () => {
blocker2Called = true;
return "allow";
};
@@ -187,14 +187,14 @@ var gTests = [
Events.on();
let blocker1Called = false,
- blocker1 = params => {
+ blocker1 = () => {
blocker1Called = true;
return "allow";
};
webrtcUI.addPeerConnectionBlocker(blocker1);
let blocker2Called = false,
- blocker2 = params => {
+ blocker2 = () => {
blocker2Called = true;
return "deny";
};
@@ -218,14 +218,14 @@ var gTests = [
Events.on();
let blocker1Called = false,
- blocker1 = params => {
+ blocker1 = () => {
blocker1Called = true;
return "deny";
};
webrtcUI.addPeerConnectionBlocker(blocker1);
let blocker2Called = false,
- blocker2 = params => {
+ blocker2 = () => {
blocker2Called = true;
return "allow";
};
@@ -252,14 +252,14 @@ var gTests = [
Events.on();
let blocker1Called = false,
- blocker1 = params => {
+ blocker1 = () => {
blocker1Called = true;
return "allow";
};
webrtcUI.addPeerConnectionBlocker(blocker1);
let blocker2Called = false,
- blocker2 = params => {
+ blocker2 = () => {
blocker2Called = true;
return "allow";
};
@@ -283,14 +283,14 @@ var gTests = [
run: async function testBlockerThrows(browser) {
Events.on();
let blocker1Called = false,
- blocker1 = params => {
+ blocker1 = () => {
blocker1Called = true;
throw new Error("kaboom");
};
webrtcUI.addPeerConnectionBlocker(blocker1);
let blocker2Called = false,
- blocker2 = params => {
+ blocker2 = () => {
blocker2Called = true;
return "allow";
};
@@ -313,10 +313,10 @@ var gTests = [
run: async function testBlockerCancel(browser) {
let blocker,
blockerPromise = new Promise(resolve => {
- blocker = params => {
+ blocker = () => {
resolve();
// defer indefinitely
- return new Promise(innerResolve => {});
+ return new Promise(() => {});
};
});
webrtcUI.addPeerConnectionBlocker(blocker);
diff --git a/browser/base/content/test/webrtc/head.js b/browser/base/content/test/webrtc/head.js
index 639ae2e51a..694875bd21 100644
--- a/browser/base/content/test/webrtc/head.js
+++ b/browser/base/content/test/webrtc/head.js
@@ -146,7 +146,7 @@ async function assertWebRTCIndicatorStatus(expected) {
if (!expected) {
let win = Services.wm.getMostRecentWindow("Browser:WebRTCGlobalIndicator");
if (win) {
- await new Promise((resolve, reject) => {
+ await new Promise(resolve => {
win.addEventListener("unload", function listener(e) {
if (e.target == win.document) {
win.removeEventListener("unload", listener);
@@ -308,7 +308,7 @@ function expectObserverCalledOnClose(
{
topic: aTopic,
count: 1,
- filterFunctionSource: ((subject, topic, data) => {
+ filterFunctionSource: ((subject, topic) => {
Services.cpmm.sendAsyncMessage("WebRTCTest:ObserverCalled", {
topic,
});
@@ -1061,7 +1061,7 @@ async function promiseReloadFrame(aFrameId, aBrowsingContext) {
let loadedPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser,
true,
- arg => {
+ () => {
return true;
}
);
diff --git a/browser/base/content/test/zoom/browser.toml b/browser/base/content/test/zoom/browser.toml
index 281fb9329c..e2aa0c077a 100644
--- a/browser/base/content/test/zoom/browser.toml
+++ b/browser/base/content/test/zoom/browser.toml
@@ -34,7 +34,7 @@ https_first_disabled = true
["browser_sitespecific_video_zoom.js"]
https_first_disabled = true
-support-files = ["../general/video.ogg"]
+support-files = ["../general/video.webm"]
skip-if = [
"os == 'win' && debug", # Bug 1315042
"verify && debug && os == 'linux'", # Bug 1315042
diff --git a/browser/base/content/test/zoom/browser_sitespecific_video_zoom.js b/browser/base/content/test/zoom/browser_sitespecific_video_zoom.js
index 589e3d09cf..94fd0dee56 100644
--- a/browser/base/content/test/zoom/browser_sitespecific_video_zoom.js
+++ b/browser/base/content/test/zoom/browser_sitespecific_video_zoom.js
@@ -8,7 +8,7 @@ const TEST_PAGE =
"http://example.org/browser/browser/base/content/test/zoom/zoom_test.html";
const TEST_VIDEO =
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
- "http://example.org/browser/browser/base/content/test/general/video.ogg";
+ "http://example.org/browser/browser/base/content/test/general/video.webm";
var gTab1, gTab2, gLevel1;
diff --git a/browser/base/content/test/zoom/browser_zoom_commands.js b/browser/base/content/test/zoom/browser_zoom_commands.js
index 88b6f42059..ef49a5794e 100644
--- a/browser/base/content/test/zoom/browser_zoom_commands.js
+++ b/browser/base/content/test/zoom/browser_zoom_commands.js
@@ -65,7 +65,7 @@ function assertTextZoomCommandCheckedState(isChecked) {
* zoom levels and/or preferences on an individual browser.
*/
add_task(async function test_update_browser_zoom() {
- await BrowserTestUtils.withNewTab(TEST_PAGE_URL, async browser => {
+ await BrowserTestUtils.withNewTab(TEST_PAGE_URL, async () => {
let currentZoom = await FullZoomHelper.getGlobalValue();
Assert.equal(
currentZoom,
@@ -136,7 +136,7 @@ add_task(async function test_update_browser_zoom() {
* zoom levels when the default zoom is not at 1.0.
*/
add_task(async function test_update_browser_zoom() {
- await BrowserTestUtils.withNewTab(TEST_PAGE_URL, async browser => {
+ await BrowserTestUtils.withNewTab(TEST_PAGE_URL, async () => {
let currentZoom = await FullZoomHelper.getGlobalValue();
Assert.equal(
currentZoom,
diff --git a/browser/base/content/test/zoom/head.js b/browser/base/content/test/zoom/head.js
index 4a42aed98f..272303de95 100644
--- a/browser/base/content/test/zoom/head.js
+++ b/browser/base/content/test/zoom/head.js
@@ -34,7 +34,7 @@ var FullZoomHelper = {
parsedZoomValue,
nonPrivateLoadContext,
{
- handleCompletion(reason) {
+ handleCompletion() {
resolve();
},
}
@@ -72,7 +72,7 @@ var FullZoomHelper = {
value = parseFloat(pref.value);
}
},
- handleCompletion(reason) {
+ handleCompletion() {
resolve(value);
},
handleError(error) {
@@ -84,7 +84,7 @@ var FullZoomHelper = {
waitForLocationChange: function waitForLocationChange() {
return new Promise(resolve => {
- Services.obs.addObserver(function obs(subj, topic, data) {
+ Services.obs.addObserver(function obs(subj, topic) {
Services.obs.removeObserver(obs, topic);
resolve();
}, "browser-fullZoom:location-change");
@@ -124,7 +124,7 @@ var FullZoomHelper = {
let didLoad = false;
let didZoom = false;
- promiseTabLoadEvent(tab, url).then(event => {
+ promiseTabLoadEvent(tab, url).then(() => {
didLoad = true;
if (didZoom) {
resolve();
diff --git a/browser/base/content/titlebar-items.inc.xhtml b/browser/base/content/titlebar-items.inc.xhtml
index 057fd522a9..4fea3a1266 100644
--- a/browser/base/content/titlebar-items.inc.xhtml
+++ b/browser/base/content/titlebar-items.inc.xhtml
@@ -13,7 +13,7 @@
data-l10n-id="browser-window-maximize-button"
/>
<toolbarbutton class="titlebar-button titlebar-restore"
- oncommand="window.fullScreen ? BrowserFullScreen() : window.restore();"
+ oncommand="window.fullScreen ? BrowserCommands.fullScreen() : window.restore();"
data-l10n-id="browser-window-restore-down-button"
/>
<toolbarbutton class="titlebar-button titlebar-close"
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
index 5967c878b3..1d8637db2e 100644
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -113,11 +113,6 @@ function getRootEvent(aEvent) {
return BrowserUtils.getRootEvent(aEvent);
}
-// This is here for historical reasons. bug 1742889 covers cleaning this up.
-function whereToOpenLink(e, ignoreButton, ignoreAlt) {
- return BrowserUtils.whereToOpenLink(e, ignoreButton, ignoreAlt);
-}
-
function openTrustedLinkIn(url, where, params) {
URILoadingHelper.openTrustedLinkIn(window, url, where, params);
}
@@ -294,7 +289,7 @@ function closeMenus(node) {
* to check if the close command key was pressed in aEvent.
*/
function eventMatchesKey(aEvent, aKey) {
- let keyPressed = aKey.getAttribute("key").toLowerCase();
+ let keyPressed = (aKey.getAttribute("key") || "").toLowerCase();
let keyModifiers = aKey.getAttribute("modifiers");
let modifiers = ["Alt", "Control", "Meta", "Shift"];
@@ -341,7 +336,7 @@ function gatherTextUnder(root) {
} else if (HTMLImageElement.isInstance(node)) {
// If it has an "alt" attribute, add that.
var altText = node.getAttribute("alt");
- if (altText && altText != "") {
+ if (altText) {
text += " " + altText;
}
}
diff --git a/browser/base/content/webext-panels.js b/browser/base/content/webext-panels.js
index e8820f4ad4..787193ab7d 100644
--- a/browser/base/content/webext-panels.js
+++ b/browser/base/content/webext-panels.js
@@ -125,22 +125,16 @@ function getBrowser(panel) {
return readyPromise.then(initBrowser);
}
-// Stub tabbrowser implementation for use by the tab-modal alert code.
+// Stub tabbrowser implementation to make sure that links from inside
+// extension sidebar panels open in new tabs, see bug 1488055.
var gBrowser = {
get selectedBrowser() {
return document.getElementById("webext-panels-browser");
},
- getTabForBrowser(browser) {
+ getTabForBrowser() {
return null;
},
-
- getTabModalPromptBox(browser) {
- if (!browser.tabModalPromptBox) {
- browser.tabModalPromptBox = new TabModalPromptBox(browser);
- }
- return browser.tabModalPromptBox;
- },
};
function updatePosition() {
diff --git a/browser/base/content/webext-panels.xhtml b/browser/base/content/webext-panels.xhtml
index f421d9bf80..1b97794a8d 100644
--- a/browser/base/content/webext-panels.xhtml
+++ b/browser/base/content/webext-panels.xhtml
@@ -28,7 +28,7 @@
<html:link rel="localization" href="toolkit/branding/brandings.ftl"/>
<html:link rel="localization" href="toolkit/global/textActions.ftl"/>
<html:link rel="localization" href="browser/browserContext.ftl"/>
- <html:link rel="localization" href="preview/select-translations.ftl"/>
+ <html:link rel="localization" href="browser/translations.ftl"/>
</linkset>
<commandset id="mainCommandset">
diff --git a/browser/base/content/webrtcIndicator.js b/browser/base/content/webrtcIndicator.js
index f38c7446ba..c19bfe1f35 100644
--- a/browser/base/content/webrtcIndicator.js
+++ b/browser/base/content/webrtcIndicator.js
@@ -47,7 +47,7 @@ function closingInternally() {
* Main control object for the WebRTC global indicator
*/
const WebRTCIndicator = {
- init(event) {
+ init() {
addEventListener("load", this);
addEventListener("unload", this);