diff --git a/files/en-us/glossary/mvc/index.md b/files/en-us/glossary/mvc/index.md index 879d01d37875299..f2554347c47abc4 100644 --- a/files/en-us/glossary/mvc/index.md +++ b/files/en-us/glossary/mvc/index.md @@ -41,7 +41,7 @@ You might however also want to just update the view to display the data in a dif ## MVC on the web -As a web developer, this pattern will probably be quite familiar even if you've never consciously used it before. Your data model is probably contained in some kind of database (be it a traditional server-side database like MySQL, or a client-side solution such as [IndexedDB \[en-US\]](/en-US/docs/Web/API/IndexedDB_API).) Your app's controlling code is probably written in HTML/JavaScript, and your user interface is probably written using HTML/CSS/whatever else you like. This sounds very much like MVC, but MVC makes these components follow a more rigid pattern. +As a web developer, this pattern will probably be quite familiar even if you've never consciously used it before. Your data model is probably contained in some kind of database (be it a traditional server-side database like MySQL, or a client-side solution such as [IndexedDB](/en-US/docs/Web/API/IndexedDB_API).) Your app's controlling code is probably written in HTML/JavaScript, and your user interface is probably written using HTML/CSS/whatever else you like. This sounds very much like MVC, but MVC makes these components follow a more rigid pattern. In the early days of the Web, MVC architecture was mostly implemented on the server-side, with the client requesting updates via forms or links, and receiving updated views back to display in the browser. However, these days, more of the logic is pushed to the client with the advent of client-side data stores, and the [Fetch API](/en-US/docs/Web/API/Fetch_API) enabling partial page updates as required. diff --git a/files/en-us/mozilla/firefox/releases/151/index.md b/files/en-us/mozilla/firefox/releases/151/index.md index 9879abe7e332464..f35482742103161 100644 --- a/files/en-us/mozilla/firefox/releases/151/index.md +++ b/files/en-us/mozilla/firefox/releases/151/index.md @@ -41,8 +41,6 @@ No notable changes. - The [`options.keyboardLock`](/en-US/docs/Web/API/Element/requestFullscreen#keyboardlock) property can now be passed as an option to {{domxref("Element.requestFullscreen()")}}, allowing websites to request keyboard lock when the element is displayed in fullscreen mode. This stops the Esc key from causing the element to leave fullscreen (a long-press is required instead), and some formerly-reserved browser hotkeys can now be intercepted and their default action prevented. ([Firefox bug 2032302](https://bugzil.la/2032302)). -- The {{domxref("CanvasRenderingContext2D.lang")}} property is now supported, allowing the rendering language of an offscreen canvas to be explicitly specified and changed after the rendering context is created. - ([Firefox bug 1943070](https://bugzil.la/1943070)). - The `maxStorageBuffersInFragmentStage`, `maxStorageBuffersInVertexStage`, `maxStorageTexturesInFragmentStage`, and `maxStorageTexturesInVertexStage` properties on {{domxref("GPUSupportedLimits")}} are now partially supported. These properties report the value of the `maxStorageBuffersPerShaderStage` and `maxStorageTexturesPerShaderStage` limits. When creating a device, requested values for the *In*Stage limits are ignored. diff --git a/files/en-us/mozilla/firefox/releases/152/index.md b/files/en-us/mozilla/firefox/releases/152/index.md index 8ae3ec89b1a9d67..333aa5c5125e5ca 100644 --- a/files/en-us/mozilla/firefox/releases/152/index.md +++ b/files/en-us/mozilla/firefox/releases/152/index.md @@ -57,6 +57,9 @@ Firefox 152 is the current [Beta version of Firefox](https://www.firefox.com/en- - The {{domxref("Notification/actions","actions")}} read-only property and the [`maxActions`](/en-US/docs/Web/API/Notification/maxActions_static) static read-only property of the {{domxref("Notification")}} interface are supported. These contain the notification actions set with {{domxref("ServiceWorkerRegistration.showNotification()")}}, and the platform-dependent maximum number of actions that can be set for a notification, respectively. ([Firefox bug 1959931](https://bugzil.la/1959931)). +- The {{domxref("Element.getAnimations()")}} method can now accept the [`options.pseudoElement`](/en-US/docs/Web/API/Element/getAnimations#pseudoelement) parameter. + This allows you to directly target a specific pseudo-element, rather than filtering the results of `{ subtree: true }`. + ([Firefox bug 1935557](https://bugzil.la/1935557)). #### Media, WebRTC, and Web Audio diff --git a/files/en-us/web/api/element/getanimations/index.md b/files/en-us/web/api/element/getanimations/index.md index a926386fc4226d5..15354fc4e91d604 100644 --- a/files/en-us/web/api/element/getanimations/index.md +++ b/files/en-us/web/api/element/getanimations/index.md @@ -8,11 +8,8 @@ browser-compat: api.Element.getAnimations {{APIRef("Web Animations")}} -The `getAnimations()` method of the {{domxref("Element")}} interface -(specified on the `Animatable` mixin) returns an array of all -{{domxref("Animation")}} objects affecting this element or which are scheduled to do so -in future. It can optionally return {{domxref("Animation")}} objects for descendant -elements too. +The `getAnimations()` method of the {{domxref("Element")}} interface returns an array of all {{domxref("Animation")}} objects affecting this element, or that are scheduled to do so in the future. +It can optionally return {{domxref("Animation")}} objects either for descendant elements and their [pseudo-elements](/en-US/docs/Web/CSS/Reference/Selectors/Pseudo-elements) or just for the specified pseudo-element. > [!NOTE] > This array includes [CSS Animations](/en-US/docs/Web/CSS/Guides/Animations), [CSS Transitions](/en-US/docs/Web/CSS/Guides/Transitions), and [Web Animations](/en-US/docs/Web/API/Web_Animations_API). @@ -27,23 +24,33 @@ getAnimations(options) ### Parameters - `options` {{optional_inline}} - - : An options object containing the following property: + - : An options object containing the following properties: - `subtree` - - : A boolean value which, if `true`, causes animations that target - descendants of _Element_ to be returned as well. This includes animations - that target any CSS [pseudo-elements](/en-US/docs/Web/CSS/Reference/Selectors/Pseudo-elements) attached to - _Element_ or one of its descendants. Defaults to `false`. + - : A boolean value, which if `true`, causes animations that target descendants of _Element_ to be returned as well. + This includes animations that target any CSS [pseudo-elements](/en-US/docs/Web/CSS/Reference/Selectors/Pseudo-elements) attached to _Element_ or one of its descendants. + Defaults to `false`. + - `pseudoElement` + - : A string that specifies a [pseudo-element](/en-US/docs/Web/CSS/Reference/Selectors/Pseudo-elements) to be the target element, such as [`::after`](/en-US/docs/Web/CSS/Reference/Selectors/::after). + + Note that specifying both `pseudoElement` and `subtree` is equivalent to specifying just `pseudoElement`. ### Return value -An {{jsxref("Array")}} of {{domxref("Animation")}} objects, each representing an -animation currently targeting the {{domxref("Element")}} on which this method is called, -or one of its descendant elements if `{ subtree: true }` is specified. +An {{jsxref("Array")}} of {{domxref("Animation")}} objects, each representing an animation currently targeting the {{domxref("Element")}}. + +If the `{ subtree: true }` parameter is specified, the returned value also includes animation objects targeting descendant elements, including pseudo-elements. +If `options.pseudoElement` is specified, the return value includes just the animation objects that match the selected pseudo-element. + +### Exceptions + +- `SyntaxError` {{domxref("DOMException")}} + - : An invalid pseudo-element was passed in the [`options.pseudoElement`](#pseudoelement) parameter. ## Examples -The following code snippet will wait for all animations on `elem` and its -descendants to finish before removing the element from the document. +### Wait for all animations on an element and its descendants + +The following code snippet will wait for all animations on `elem` and its descendants to finish before removing the element from the document. ```js Promise.all( @@ -51,6 +58,111 @@ Promise.all( ).then(() => elem.remove()); ``` +### Get animations for a pseudo-element target + +This example displays a progress bar using a pseudo-element. +It uses `getAnimations()` to return the animations for the pseudo-element, starts them, and then removes the progress bar once the animation is complete. + +Note that the code uses a fallback approach to get the animations in case the `pseudoElement` option is not supported. +There is also hidden code to display a "Restart" button. + +#### HTML + +```html +
+``` + +#### CSS + +The CSS styles the progress bar element to animate across the width of its container in 3 seconds. +The animation is initially paused so that we can start it in JavaScript. + +```css +.progress-bar { + width: 100%; + height: 20px; + background: #eee; + border-radius: 4px; + overflow: hidden; +} + +.progress-bar::after { + content: ""; + display: block; + height: 100%; + width: 0%; + background: #4f46e5; + border-radius: 4px; + animation: fill-progress 3s ease-in-out forwards paused; +} + +@keyframes fill-progress { + from { + width: 0%; + } + to { + width: 100%; + } +} +``` + +#### JavaScript + +First we define a function to get the animations associated with a specified element and pseudo-element. +It calls `getAnimations()` with the [`pseudoElement`](#pseudoelement) option, and if that doesn't return any animations, falls back to filtering the animations returned by [`subtree`](#subtree). + +```js +function getAnimationsForPseudo(element, pseudo) { + // Try the spec-compliant way first (Firefox) + try { + const anims = element.getAnimations({ pseudoElement: pseudo }); + // If it returned something, the option is supported, so return the result + if (anims.length > 0) return anims; + } catch (e) { + // invalid selector etc + return []; + } + + // Fallback for browsers that only support subtree + return element + .getAnimations({ subtree: true }) + .filter((anim) => anim.effect?.pseudoElement === pseudo); +} +``` + +We use this function to get all the animations associated with the progress bar pseudo element. +The code iterates through the animations to start them, and then removes the progress bar when all animations have finished. +Note that we run the code in `requestAnimationFrame()` to ensure that the animation is ready to run before our JavaScript is executed. + +```js +const bar = document.getElementById("bar"); + +requestAnimationFrame(() => { + const anims = getAnimationsForPseudo(bar, "::after"); + anims.forEach((a) => a.play()); + Promise.all(anims.map((a) => a.finished)).then(() => bar.remove()); +}); +``` + +```html hidden + +``` + +```js hidden +const reload = document.querySelector("#reset"); + +reload.addEventListener("click", () => { + window.location.reload(true); +}); +``` + +#### Result + +The bar should progress across the width of its container and then disappear. +You can restart it by pressing the "Restart" button. + +{{EmbedLiveSample("Get animations for a pseudo-element target", "100%", "50px")}} + ## Specifications {{Specifications}} diff --git a/files/en-us/web/api/notification/actions/index.md b/files/en-us/web/api/notification/actions/index.md index 4581ead9941b7a8..8e70305ce1363a3 100644 --- a/files/en-us/web/api/notification/actions/index.md +++ b/files/en-us/web/api/notification/actions/index.md @@ -8,16 +8,12 @@ browser-compat: api.Notification.actions {{APIRef("Web Notifications")}}{{SecureContext_Header}} {{AvailableInWorkers}} -The **`actions`** read-only property of the {{domxref("Notification")}} interface provides the actions available for users to choose from for interacting with the notification. - -The actions are set using the `actions` option of the second argument for the {{DOMxref("ServiceWorkerRegistration.showNotification", "showNotification()")}} method and {{DOMxref("Notification/Notification", "Notification()")}} constructor. - -> [!NOTE] -> Browsers typically limit the maximum number of actions they will display for a particular notification. Check the static {{DOMxref("Notification.maxActions_static", "Notification.maxActions")}} property to determine the limit. +The **`actions`** read-only property of the {{domxref("Notification")}} interface provides the actions available for users to select when interacting with the notification. ## Value -A read-only array of actions. Each element in the array is an object with the following members: +A read-only array of actions. +Each element in the array is an object with the following members: - `action` - : A string identifying a user action to be displayed on the notification. @@ -25,6 +21,43 @@ A read-only array of actions. Each element in the array is an object with the fo - : A string containing action text to be shown to the user. - `icon` - : A string containing the URL of an icon to display with the action. +- `navigate` {{optional_inline}} {{experimental_inline}} + - : A string containing a URL to navigate to when the user activates this action. + When set, the user agent navigates to this URL instead of firing the {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event. + See {{domxref("Notification.navigate")}} for more information. + +## Description + +Notification actions are buttons or controls that appear within [persistent notifications](/en-US/docs/Web/API/Notifications_API#persistent_and_non-persistent_notifications). +They are set using the [`actions`](/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#actions) option of the second argument of the {{domxref("ServiceWorkerRegistration.showNotification", "showNotification()")}} method. +Note that actions are not available for non-persistent notifications. +If you pass an `options` object with an `actions` property that is anything other than `null` to the {{domxref("Notification/Notification", "Notification()")}} constructor, a `TypeError` is thrown. + +Clicking the button associated with an action navigates to the URL set in the [`navigate`](#navigate) option if one is specified. +Otherwise, it fires a [`notificationclick`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) event on the service worker that includes the action that was selected (and the associated `Notification` instance), so the worker can handle it without the user ever switching to your page. + +> [!NOTE] +> Browsers typically limit the maximum number of actions they will display for a particular notification. +> Check the static {{domxref("Notification.maxActions_static", "Notification.maxActions")}} property to determine the limit. + +## Examples + +### Basic usage + +The following code shows how a service worker might listen for the `notificationclick` event and use it to retrieve both the clicked action and an array of all actions. + +```js +// sw.js +self.addEventListener("notificationclick", (event) => { + const clickedAction = event.action; // e.g. "reply" or "" if body was clicked + + // Read all defined actions + const notification = event.notification; // the Notification object + console.log(notification.actions); // full array of action objects + + notification.close(); +}); +``` ## Specifications @@ -37,4 +70,4 @@ A read-only array of actions. Each element in the array is an object with the fo ## See also - [Using the Notifications API](/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API) -- {{DOMxref("Notification.maxActions_static", "Notification.maxActions")}} +- {{domxref("Notification.maxActions_static", "Notification.maxActions")}} diff --git a/files/en-us/web/api/notification/maxactions_static/index.md b/files/en-us/web/api/notification/maxactions_static/index.md index e53c18a9eef3e01..593a4e14a45a780 100644 --- a/files/en-us/web/api/notification/maxactions_static/index.md +++ b/files/en-us/web/api/notification/maxactions_static/index.md @@ -6,20 +6,26 @@ page-type: web-api-static-property browser-compat: api.Notification.maxActions_static --- -{{APIRef("Web Notifications")}}{{SecureContext_Header}} {{AvailableInWorkers}} +{{APIRef("Web Notifications")}}{{SecureContext_Header}}{{SeeCompatTable}} {{AvailableInWorkers}} -The **`maxActions`** read-only static property of the -{{domxref("Notification")}} interface returns the maximum number of actions supported by -the device and the User Agent. Effectively, this is the maximum number of elements in -{{domxref("Notification.actions")}} array which will be respected by the User Agent. +The **`maxActions`** read-only static property of the {{domxref("Notification")}} interface returns the maximum number of actions that can be displayed in a notification. ## Value -An integer number which indicates the largest number of notification -actions that can be presented to the user by the User Agent and the device. +An integer. + +## Description + +Notification actions are buttons or controls that appear within [persistent notifications](/en-US/docs/Web/API/Notifications_API#persistent_and_non-persistent_notifications). +Actions are set using the [`actions`](/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification#actions) option of the second argument of the {{domxref("ServiceWorkerRegistration.showNotification", "showNotification()")}} method. + +Browsers typically limit the maximum number of actions they will display for a particular notification. +The `maxActions` property returns that limit, which is the maximum number of elements in the {{domxref("Notification.actions")}} array that will be respected by the user agent. ## Examples +### Log the maximum possible number of actions + The following snippet logs the maximum number of supported actions. ```js diff --git a/files/en-us/web/api/notification/notification/index.md b/files/en-us/web/api/notification/notification/index.md index 7439c63fc02a27c..6a5f00ae350577a 100644 --- a/files/en-us/web/api/notification/notification/index.md +++ b/files/en-us/web/api/notification/notification/index.md @@ -10,15 +10,9 @@ browser-compat: api.Notification.Notification The **`Notification()`** constructor creates a new {{domxref("Notification")}} object instance, which represents a user notification. -Trying to create a notification inside the {{domxref("ServiceWorkerGlobalScope")}} using the `Notification()` constructor will throw a `TypeError`. -Use {{domxref("ServiceWorkerRegistration.showNotification()")}} instead. - -You must first get permission before being able to display notifications, using {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}}. -The permission may not be grantable, for example if the page is in private browsing mode. - -This constructor throws a {{jsxref("TypeError")}} when called in nearly all mobile browsers and this is unlikely to change, because web pages on mobile devices almost never "run in the background", which is the main use case for notifications. -Instead, you need to register a service worker and use {{domxref("ServiceWorkerRegistration.showNotification()")}}. -See [Chrome issue](https://crbug.com/481856) for more information. +> [!WARNING] +> This constructor throws a {{jsxref("TypeError")}} when called in nearly all mobile browsers. +> Instead, you need to register a service worker and use {{domxref("ServiceWorkerRegistration.showNotification()")}}. ## Syntax @@ -39,7 +33,7 @@ new Notification(title, options) `actions` is only supported for [persistent notifications](/en-US/docs/Web/API/Notifications_API#persistent_and_non-persistent_notifications) fired from a service worker using {{domxref("ServiceWorkerRegistration.showNotification()")}}. - `badge` {{optional_inline}} - : A string containing the URL of the image used to represent the notification when there isn't enough space to display the notification itself; for example, the Android Notification Bar. - On Android devices, the badge should accommodate devices up to 4x resolution, about 96x96px, and the image will be automatically masked. + On Android devices, the badge should support devices with up to 4x resolution, about 96x96px, and the image will be automatically masked. - `body` {{optional_inline}} - : A string representing the body text of the notification, which is displayed below the title. The default is the empty string. @@ -65,7 +59,7 @@ new Notification(title, options) - `renotify` {{optional_inline}} - : A boolean value specifying whether the user should be notified after a new notification replaces an old one. The default is `false`, which means they won't be notified. - If `true`, then `tag` also must be set. + If `true`, `tag` must also be set. - `requireInteraction` {{optional_inline}} - : Indicates that a notification should remain active until the user clicks or dismisses it, rather than closing automatically. The default value is `false`. @@ -97,10 +91,25 @@ An instance of the {{domxref("Notification")}} object. - `DataCloneError` {{domxref("DOMException")}} - : Thrown if serializing the `data` option failed for some reason. +## Description + +The constructor creates a new {{domxref("Notification")}} object instance, which represents a user notification. + +You must get permission to display notifications using {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}}. +The permission may not be grantable, for example if the page is in private browsing mode. + +This constructor throws a {{jsxref("TypeError")}} when called in nearly all mobile browsers, and this is unlikely to change, because web pages on mobile devices almost never "run in the background", which is the main use case for notifications. +Instead, you need to register a service worker and use {{domxref("ServiceWorkerRegistration.showNotification()")}}. +See [Chrome issue #481856](https://crbug.com/481856) for more information. + ## Examples -Here is a most basic example to only show a notification if permission is already granted. -For more complete examples, see the {{domxref("Notification")}} page. +For more examples, see the {{domxref("Notification")}} page and [Using the Notifications API](/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API). + +### Basic example + +This is a basic example that shows a notification if permission is already granted. +This will not work on mobile devices. ```js if (Notification.permission === "granted") { @@ -108,6 +117,35 @@ if (Notification.permission === "granted") { } ``` +### Using Notification() as a fallback + +This example shows a more robust approach that allows showing notifications on both desktop and mobile devices. + +First we check if {{domxref("Notification")}} is supported, and if permission has been granted, returning early if either condition is not met. +We then check if there is an active service worker. +If so, we use it to call {{domxref("ServiceWorkerRegistration.showNotification()")}}; if not, we fall back to calling the constructor. + +```js +async function showNotification(title, options = {}) { + if (!("Notification" in window)) return; + if (Notification.permission !== "granted") return; + + // Only use SW if one is already active — don't hang waiting + const swReg = navigator.serviceWorker?.controller + ? await navigator.serviceWorker.getRegistration() + : null; + + if (swReg) { + await swReg.showNotification(title, options); + } else { + new Notification(title, options); + } +} +``` + +Note that this will still throw an error on a mobile device if the page does not have a service worker ready. +Depending on your application, you might wrap this code in a `try...catch` block. + ## Specifications {{Specifications}} diff --git a/files/en-us/web/api/notifications_api/index.md b/files/en-us/web/api/notifications_api/index.md index 1d134d26bdbec52..fd0dc1b20cb7e5f 100644 --- a/files/en-us/web/api/notifications_api/index.md +++ b/files/en-us/web/api/notifications_api/index.md @@ -12,12 +12,28 @@ spec-urls: https://notifications.spec.whatwg.org/ {{DefaultAPISidebar("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}} The Notifications API allows web pages to control the display of system notifications to the end user. -These are outside the top-level browsing context viewport, so therefore can be displayed even when the user has switched tabs or moved to a different app. -The API is designed to be compatible with existing notification systems, across different platforms. ## Concepts and usage -Showing a system notification generally involves first requesting permission to use the feature, and then creating a notification. +A web notification is a message box used to inform users when events occur on web apps. Web notifications are rendered by the operating system's native notification system, making them display identically to notifications from any other app on the platform. +Because the underlying OS renders web notifications, they are outside the top-level browsing context viewport, and can be shown even when the user has switched tabs or moved to a different app. + +### Persistent and non-persistent notifications + +The Notifications API supports two types of notifications: + +- **Non-persistent notifications** are created in a browsing context, such as a web page or tab. + Their lifetime is tied to the lifetime of the page — if the page is closed, the notification can no longer be interacted with. + + They are created using the {{domxref("Notification.Notification","Notification()")}} constructor and fire events such as {{domxref("Notification/click_event", "click")}} directly on the `Notification` instance. + +- **Persistent notifications** are created from a service worker, and can remain interactive beyond the lifetime of an individual page. + + They are created by calling {{domxref("ServiceWorkerRegistration.showNotification()")}} from inside a service worker and fire {{domxref("ServiceWorkerGlobalScope/notificationclick_event", "notificationclick")}} and {{domxref("ServiceWorkerGlobalScope/notificationclose_event", "notificationclose")}} events on the {{domxref("ServiceWorkerGlobalScope")}}. + +> [!NOTE] +> If your code needs to run on mobile devices then you **must** use persistent notifications! +> The {{domxref("Notification.Notification","Notification()")}} constructor will throw a {{jsxref("TypeError")}} on most mobile browsers. ### Notifications require user permission @@ -45,7 +61,7 @@ Once a choice has been made, the setting will generally persist for the current Notifications are created using the {{domxref("Notification.Notification","Notification()")}} constructor. This must be passed a title argument, and can optionally be passed a parameter to specify options such as text direction, body text, icon to display, notification sound to play, and more. -For example, the following code shows how you might create a notification that sets the [`navigate`](/en-US/docs/Web/API/Notification/Notification#navigate) option, specifying a URL that will be opened if the notification is accepted (you can also defined click handlers to process notification actions). +For example, the following code shows how you might create a notification that sets the [`navigate`](/en-US/docs/Web/API/Notification/Notification#navigate) option, specifying a URL that will be opened if the notification is accepted (you can also define click handlers to process notification actions). ```js if (Notification.permission === "granted") { @@ -58,19 +74,6 @@ if (Notification.permission === "granted") { For more usage examples see [Using the Notifications API](/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API). -### Persistent and non-persistent notifications - -The Notifications API supports two types of notifications: - -- **Non-persistent notifications** are created in a browsing context, such as a web page or tab. - Their lifetime is tied to the lifetime of the page — if the page is closed, the notification can no longer be interacted with. - - They are created using the {{domxref("Notification.Notification","Notification()")}} constructor and fire events such as {{domxref("Notification/click_event", "click")}} directly on the `Notification` instance - -- **Persistent notifications** are created from a service worker, and can remain interactive beyond the lifetime of an individual page. - - They are created using {{domxref("ServiceWorkerRegistration.showNotification()")}} from a service worker and fire {{domxref("ServiceWorkerGlobalScope/notificationclick_event", "notificationclick")}} and {{domxref("ServiceWorkerGlobalScope/notificationclose_event", "notificationclose")}} events on the {{domxref("ServiceWorkerGlobalScope")}}. - ## Interfaces - {{domxref("Notification")}} diff --git a/files/en-us/web/api/serviceworkerregistration/shownotification/index.md b/files/en-us/web/api/serviceworkerregistration/shownotification/index.md index a8554e20898d330..d2336ed1315978d 100644 --- a/files/en-us/web/api/serviceworkerregistration/shownotification/index.md +++ b/files/en-us/web/api/serviceworkerregistration/shownotification/index.md @@ -30,7 +30,10 @@ showNotification(title, options) - : An array of actions to display in the notification, for which the default is an empty array. Each element in the array can be an object with the following members: - `action` - - : A string identifying a user action to be displayed on the notification. + - : A string that uniquely identifies this particular action within the array of actions. + + When an action button without a `navigate` URL is clicked, you can determine which button was selected by checking `event.action` inside your {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event listener. + - `title` - : A string containing action text to be shown to the user. - `icon` {{optional_inline}} @@ -40,8 +43,6 @@ showNotification(title, options) When set, the user agent navigates to this URL instead of firing the {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event See {{domxref("Notification.navigate")}} for more information. - Appropriate responses are built using `event.action` within the {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event. - - `badge` {{optional_inline}} {{experimental_inline}} - : A string containing the URL of the image used to represent the notification when there isn't enough space to display the notification itself; for example, the Android Notification Bar. On Android devices, the badge should accommodate devices up to 4x resolution, about 96x96px, and the image will be automatically masked. @@ -105,31 +106,84 @@ A {{jsxref('Promise')}} that resolves to `undefined`. ## Examples +### Basic usage + +This example shows a function running in a service worker that displays a notification after first requesting, and being granted, permission. +Code to actually call the function is not shown. + ```js navigator.serviceWorker.register("sw.js"); -function showNotification() { - Notification.requestPermission().then((result) => { - if (result === "granted") { - navigator.serviceWorker.ready.then((registration) => { - registration.showNotification("Vibration Sample", { - body: "Buzz! Buzz!", - icon: "../images/touch/chrome-touch-icon-192x192.png", - vibrate: [200, 100, 200, 100, 200, 100, 200], - tag: "vibration-sample", - }); - }); - } - }); +async function showNotification() { + const result = await Notification.requestPermission(); + + if (result === "granted") { + const registration = await navigator.serviceWorker.ready; + + registration.showNotification("Vibration Sample", { + body: "Buzz! Buzz!", + icon: "../images/touch/chrome-touch-icon-192x192.png", + vibrate: [200, 100, 200, 100, 200, 100, 200], + tag: "vibration-sample", + }); + } } ``` -To invoke the above function at an appropriate time, you could listen to the -{{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event. +The following code shows how you might listen to the {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "notificationclick")}} event in order to handle user interaction with this particular notification. + +```js +self.addEventListener("notificationclick", (event) => { + const notification = event.notification; + + // Close notification if we don't need it any more. + notification.close(); + + // Process our particular notification + if (notification.tag === "vibration-sample") { + // Use event.waitUntil to keep the service worker alive until the promise resolves + event + .waitUntil + // Code to handle the particular event. + (); + } +}); +``` + +You can also retrieve details of the {{domxref("Notification")}}s that have been fired from the current service worker using {{domxref("ServiceWorkerRegistration.getNotifications()")}}. + +### Notifications with actions and action handlers + +This example shows how you might display a persistent notification, which might be triggered by a push message when an email is received, for example. + +The code to generate the notification includes two `actions` that will be displayed on the notification: one to reply to the message, and the other to dismiss the notification. +Each action includes a `title`, which is usually rendered as button text on the notification, and an `action`, which is used to identify the action that was selected if a user interacts with the notification. + +```js +registration.showNotification("New Message", { + body: "You've got mail.", + icon: "/images/icon.png", + actions: [ + { action: "reply", title: "Reply" }, + { action: "dismiss", title: "Dismiss" }, + ], +}); +``` + +The following code shows how you can listen for `notificationclick` events from the notification, and then use the value of the `event.action` property to determine which action was selected. +Note that if the user clicks the notification body instead of an action button, `event.action` will be an empty string. -You can also retrieve details of the {{domxref("Notification")}}s that have been fired -from the current service worker using -{{domxref("ServiceWorkerRegistration.getNotifications()")}}. +```js +self.addEventListener("notificationclick", (event) => { + event.notification.close(); + + if (event.action === "reply") { + // handle reply + } else if (event.action === "dismiss") { + // handle dismiss + } +}); +``` ## Specifications diff --git a/files/en-us/web/css/guides/cascade/shorthand_properties/index.md b/files/en-us/web/css/guides/cascade/shorthand_properties/index.md index 1b187d9d9bff9bb..b911cdc4b892095 100644 --- a/files/en-us/web/css/guides/cascade/shorthand_properties/index.md +++ b/files/en-us/web/css/guides/cascade/shorthand_properties/index.md @@ -47,10 +47,6 @@ Shorthands handling properties related to the sides of the box, like {{cssxref(" - **1-value syntax:** `border-width: 1em` — A single value represents all sides: ![Box edges with one-value syntax](border1.png) -- **2-value syntax:** `border-width: 1em 2em` — The first value represents the top and bottom edges, and the second value represents the left and right edges: ![Box edges with two-value syntax](border2.png) - -- **3-value syntax:** `border-width: 1em 2em 3em` — The first value represents the top edge, the second value represents the left and right edges, and the third value represents the bottom edge: ![Box edges with three-value syntax](border3.png) - - **2-value syntax:** `border-width: 1em 2em` — The first value represents the top and bottom sides, and the second value represents the left and right sides: ![Box edges with two-value syntax](border2.png) - **3-value syntax:** `border-width: 1em 2em 3em` — The first value represents the top side, the second value represents the left and right sides, and the third value represents the bottom side: ![Box edges with three-value syntax](border3.png) diff --git a/files/en-us/web/css/reference/values/ident/index.md b/files/en-us/web/css/reference/values/ident/index.md index d537005f39196a3..db2f864bb2131b0 100644 --- a/files/en-us/web/css/reference/values/ident/index.md +++ b/files/en-us/web/css/reference/values/ident/index.md @@ -7,7 +7,7 @@ spec-urls: https://drafts.csswg.org/css-values/#typedef-ident sidebar: cssref --- -The **``** [CSS](/en-US/docs/Web/CSS) [data type](/en-US/docs/Web/CSS/Reference/Values/Data_types) denotes an arbitrary string used as an {{glossary("identifier")}}. +The **``** [CSS](/en-US/docs/Web/CSS) [data type](/en-US/docs/Web/CSS/Reference/Values/Data_types) denotes an arbitrary unquoted string of characters used as an {{glossary("identifier")}}. ## Syntax