diff options
Diffstat (limited to 'browser')
5 files changed, 185 insertions, 28 deletions
diff --git a/browser/base/content/browser-fullScreenAndPointerLock.js b/browser/base/content/browser-fullScreenAndPointerLock.js index 82d5727f14..cc5fefff68 100644 --- a/browser/base/content/browser-fullScreenAndPointerLock.js +++ b/browser/base/content/browser-fullScreenAndPointerLock.js @@ -275,11 +275,24 @@ var PointerlockFsWarning = { }; var PointerLock = { + _isActive: false, + + /** + * @returns {boolean} - true if pointer lock is currently active for the + * associated window. + */ + get isActive() { + return this._isActive; + }, + entered(originNoSuffix) { + this._isActive = true; + Services.obs.notifyObservers(null, "pointer-lock-entered"); PointerlockFsWarning.showPointerLock(originNoSuffix); }, exited() { + this._isActive = false; PointerlockFsWarning.close("pointerlock-warning"); }, }; 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 515895f35a..600456640b 100644 --- a/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js +++ b/browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js @@ -294,3 +294,104 @@ add_task(async function test_notificationReshowTabSwitch() { "Should not longer see the notification." ); }); + +/** + * 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); +}); diff --git a/browser/components/search/schema/search-telemetry-schema.json b/browser/components/search/schema/search-telemetry-schema.json index 8bca1f30fb..872166d44c 100644 --- a/browser/components/search/schema/search-telemetry-schema.json +++ b/browser/components/search/schema/search-telemetry-schema.json @@ -130,17 +130,9 @@ "type": "object", "properties": { "type": { - "enum": [ - "ad_carousel", - "ad_image_row", - "ad_link", - "ad_sitelink", - "ad_sidebar", - "incontent_searchbox", - "refined_search_buttons", - "shopping_tab" - ], - "description": "The type of component the anchor or DOM element should belong to." + "type": "string", + "description": "The type of component the anchor or DOM element should belong to.", + "pattern": "^[a-z](?:_?[a-z])*$" }, "included": { "type": "object", @@ -154,6 +146,12 @@ "selector": { "description": "If topDown is true for this component, then this will be the value used in querySelectorAll(). Otherwise, it will be the value to in closest() from the context of an anchor.", "type": "string" + }, + "eventListeners": { + "$ref": "#/definitions/eventListeners" + }, + "skipCount": { + "$ref": "#/definitions/skipCount" } }, "required": ["selector"] @@ -170,21 +168,19 @@ "description": "The selector to use querySelectorAll from the context of the parent." }, "type": { - "enum": [ - "ad_carousel", - "ad_image_row", - "ad_link", - "ad_sitelink", - "ad_sidebar", - "incontent_searchbox", - "refined_search_buttons", - "shopping_tab" - ], - "description": "The component type to use if this child is present." + "type": "string", + "description": "The component type to use if this child is present.", + "pattern": "^[a-z](?:_?[a-z])*$" }, "countChildren": { "type": "boolean", "description": "Whether we should count all instances of the child element instead of anchor links found inside of the parent. Defaults to false." + }, + "eventListeners": { + "$ref": "#/definitions/eventListeners" + }, + "skipCount": { + "$ref": "#/definitions/skipCount" } }, "required": ["selector"] @@ -233,6 +229,15 @@ } } }, + "ignoreLinkRegexps": { + "type": "array", + "title": "Ignore links matching regular expressions", + "description": "Regular expressions matching links that should be ignored by the network observer.", + "items": { + "type": "string", + "description": "The matching regular expression." + } + }, "nonAdsLinkRegexps": { "type": "array", "title": "Non-ads link matching regular expressions", @@ -270,22 +275,55 @@ "type": "array", "description": "An array of methods for extracting domains from ads.", "items": { - "$ref": "/schemas/extraction" + "$ref": "#/definitions/extraction" } }, "nonAds": { "type": "array", "description": "An array of methods for extracting domains from non-ads.", "items": { - "$ref": "/schemas/extraction" + "$ref": "#/definitions/extraction" } } } } }, - "$defs": { + "definitions": { + "eventListener": { + "title": "Event Listener", + "type": "object", + "description": "Event listeners attached to a component.", + "properties": { + "eventType": { + "title": "Event Type", + "description": "The type of event to listen for. Custom events, especially those with special logic like keydownEnter, can be used if the Desktop code has been updated.", + "type": "string", + "pattern": "^[a-z][A-Za-z]*$" + }, + "target": { + "title": "Target", + "description": "The component type to report when the event is triggered. Uses the child component type (if exists), otherwise uses the parent component type.", + "type": "string", + "pattern": "^[a-z](?:_?[a-z])*$" + }, + "action": { + "title": "Action", + "description": "The action to report when the event is triggered. If the event type is 'click', defaults to clicked. Otherwise, this should be provided.", + "type": "string", + "pattern": "^[a-z](?:_?[a-z])*$" + } + }, + "required": ["eventType"] + }, + "eventListeners": { + "title": "Event Listeners", + "description": "An array of Event Listeners to apply to elements.", + "type": "array", + "items": { + "$ref": "#/definitions/eventListener" + } + }, "extraction": { - "$id": "/schemas/extraction", "anyOf": [ { "type": "object", @@ -337,5 +375,10 @@ } ] } + }, + "skipCount": { + "title": "Skip Count", + "description": "Whether to skip reporting of the count of these elements to ad_impressions. Defaults to false.", + "type": "boolean" } } diff --git a/browser/config/version.txt b/browser/config/version.txt index f5a13d6b75..9423409c32 100644 --- a/browser/config/version.txt +++ b/browser/config/version.txt @@ -1 +1 @@ -115.8.0 +115.9.0 diff --git a/browser/config/version_display.txt b/browser/config/version_display.txt index 86a7ee43ba..f95bb6139e 100644 --- a/browser/config/version_display.txt +++ b/browser/config/version_display.txt @@ -1 +1 @@ -115.8.0esr +115.9.0esr |