diff --git a/.github/workflows/auto-cleanup-bot.yml b/.github/workflows/auto-cleanup-bot.yml index 469b86eb50491a0..0abd0b962669cbb 100644 --- a/.github/workflows/auto-cleanup-bot.yml +++ b/.github/workflows/auto-cleanup-bot.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" package-manager-cache: false diff --git a/.github/workflows/interfacedata-updater.yml b/.github/workflows/interfacedata-updater.yml index ffc0c7b43ede7e3..01e2bebf11e0d56 100644 --- a/.github/workflows/interfacedata-updater.yml +++ b/.github/workflows/interfacedata-updater.yml @@ -23,7 +23,7 @@ jobs: persist-credentials: false - name: Setup node.js - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: "mdn-content/.nvmrc" package-manager-cache: false diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml index 2970fdf43c97ee7..89d8e305f1b7ec0 100644 --- a/.github/workflows/markdown-lint.yml +++ b/.github/workflows/markdown-lint.yml @@ -24,7 +24,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check-lint_content.yml b/.github/workflows/pr-check-lint_content.yml index e3f8d4b2038cbc6..a18bd92321b1779 100644 --- a/.github/workflows/pr-check-lint_content.yml +++ b/.github/workflows/pr-check-lint_content.yml @@ -108,7 +108,7 @@ jobs: - name: Setup Node.js environment if: steps.check.outputs.HAS_FILES == 'true' - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_cspell_lists.yml b/.github/workflows/pr-check_cspell_lists.yml index 984b4f30ff5db61..3117826a1fe7ee0 100644 --- a/.github/workflows/pr-check_cspell_lists.yml +++ b/.github/workflows/pr-check_cspell_lists.yml @@ -24,7 +24,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" diff --git a/.github/workflows/pr-check_javascript.yml b/.github/workflows/pr-check_javascript.yml index 3c39f81c7aa631f..d3acd78bfe4d8c8 100644 --- a/.github/workflows/pr-check_javascript.yml +++ b/.github/workflows/pr-check_javascript.yml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_json.yml b/.github/workflows/pr-check_json.yml index 748ce28111553e6..28a17566c9ae68d 100644 --- a/.github/workflows/pr-check_json.yml +++ b/.github/workflows/pr-check_json.yml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_redirects.yml b/.github/workflows/pr-check_redirects.yml index 5bbc484d61fd215..5ace1a0cdd9820e 100644 --- a/.github/workflows/pr-check_redirects.yml +++ b/.github/workflows/pr-check_redirects.yml @@ -16,7 +16,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_scripts.yml b/.github/workflows/pr-check_scripts.yml index 2cbb26359bd5128..1e9ae062fe25cc6 100644 --- a/.github/workflows/pr-check_scripts.yml +++ b/.github/workflows/pr-check_scripts.yml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm @@ -42,7 +42,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm @@ -85,7 +85,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm @@ -106,7 +106,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm @@ -131,7 +131,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_url-issues.yml b/.github/workflows/pr-check_url-issues.yml index addeea84b937dd0..e161040b833805a 100644 --- a/.github/workflows/pr-check_url-issues.yml +++ b/.github/workflows/pr-check_url-issues.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-check_yml.yml b/.github/workflows/pr-check_yml.yml index 7b28dc65a833f45..0ab8061f944bc08 100644 --- a/.github/workflows/pr-check_yml.yml +++ b/.github/workflows/pr-check_yml.yml @@ -21,7 +21,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/pr-review-companion.yml b/.github/workflows/pr-review-companion.yml index 4618d97a0bcb6bd..eb58cf0c4cf2193 100644 --- a/.github/workflows/pr-review-companion.yml +++ b/.github/workflows/pr-review-companion.yml @@ -117,7 +117,7 @@ jobs: persist-credentials: false - name: Setup (mdn/content) - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 if: steps.check.outputs.HAS_ARTIFACT with: node-version-file: "content/.nvmrc" diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml index e13bc879a441c38..d687962a03e7776 100644 --- a/.github/workflows/pr-test.yml +++ b/.github/workflows/pr-test.yml @@ -78,7 +78,7 @@ jobs: - name: Setup Node.js environment if: steps.check.outputs.HAS_FILES == 'true' - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" cache: npm diff --git a/.github/workflows/spelling-check-bot.yml b/.github/workflows/spelling-check-bot.yml index fb3198e9bb6f74a..00236ce7423ee21 100644 --- a/.github/workflows/spelling-check-bot.yml +++ b/.github/workflows/spelling-check-bot.yml @@ -23,7 +23,7 @@ jobs: persist-credentials: false - name: Setup Node.js environment - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version-file: ".nvmrc" package-manager-cache: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe35c16de2f0054..e81459edb201d4e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: Setup Node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: cache: npm node-version-file: .nvmrc diff --git a/files/en-us/mozilla/add-ons/webextensions/api/action/openpopup/index.md b/files/en-us/mozilla/add-ons/webextensions/api/action/openpopup/index.md index 27bce3020dd9ca4..42110b07819b969 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/action/openpopup/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/action/openpopup/index.md @@ -11,8 +11,6 @@ Open the browser action's popup. > [!NOTE] > This API is available in Manifest V3 or higher. -In stable versions of Firefox, you can only call this function from inside the handler for a [user action](/en-US/docs/Mozilla/Add-ons/WebExtensions/User_actions). See [Browser compatibility](#browser_compatibility) for details. - ## Syntax ```js-nolint diff --git a/files/en-us/mozilla/add-ons/webextensions/api/browseraction/openpopup/index.md b/files/en-us/mozilla/add-ons/webextensions/api/browseraction/openpopup/index.md index 1a5f30164e0bcff..9da50932b72dc50 100644 --- a/files/en-us/mozilla/add-ons/webextensions/api/browseraction/openpopup/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/api/browseraction/openpopup/index.md @@ -8,8 +8,6 @@ sidebar: addonsidebar Open the browser action's popup. -In stable versions of Firefox, you can only call this function from inside the handler for a [user action](/en-US/docs/Mozilla/Add-ons/WebExtensions/User_actions). See [Browser compatibility](#browser_compatibility) for details. - ## Syntax ```js-nolint diff --git a/files/en-us/mozilla/add-ons/webextensions/user_actions/index.md b/files/en-us/mozilla/add-ons/webextensions/user_actions/index.md index 2332f9e321c98a5..df5c2dc81cae5a1 100644 --- a/files/en-us/mozilla/add-ons/webextensions/user_actions/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/user_actions/index.md @@ -15,7 +15,7 @@ Some WebExtension APIs perform functions that usually occur as a result of a use The APIs enabled by a user action are: -- The {{WebExtAPIRef("action.openPopup")}}, {{WebExtAPIRef("browserAction.openPopup")}}, and {{WebExtAPIRef("pageAction.openPopup")}} APIs that open an extension's browser or page action popup. Users do the same by clicking the browser or page action. +- The {{WebExtAPIRef("pageAction.openPopup")}} APIs that opens an extension's page action popup. The user does this by clicking the page action. - The {{WebExtAPIRef("sidebarAction.open")}}, {{WebExtAPIRef("sidebarAction.close")}}, and {{WebExtAPIRef("sidebarAction.toggle")}} APIs open and close an extension's sidebar. The user does this from some part of the browser's built-in user interface, such as the **View** > **Sidebar** menu. - The {{WebExtAPIRef("downloads.open")}} API opens a downloaded file. The user does this from some part of the browser's built-in user interface, such as the **Tools** > **Downloads** menu. - The {{WebExtAPIRef("management.setEnabled")}} API. The user can turn off a theme extension from the extension's Add-on Manager page. diff --git a/files/en-us/mozilla/firefox/experimental_features/index.md b/files/en-us/mozilla/firefox/experimental_features/index.md index 83cd3e44472f71a..e66edfe444e27df 100644 --- a/files/en-us/mozilla/firefox/experimental_features/index.md +++ b/files/en-us/mozilla/firefox/experimental_features/index.md @@ -357,21 +357,6 @@ The [`color-mix()`](/en-US/docs/Web/CSS/Reference/Values/color_value/color-mix) ## APIs -### Removal of `beforescriptexecute` and `afterscriptexecute` events - -The non-standard events [`beforescriptexecute`](/en-US/docs/Web/API/Document/beforescriptexecute_event) and [`afterscriptexecute`](/en-US/docs/Web/API/Document/afterscriptexecute_event) on the {{domxref("Document")}} interface, and [`afterscriptexecute`](/en-US/docs/Web/API/Element/afterscriptexecute_event) and [`beforescriptexecute`](/en-US/docs/Web/API/Element/beforescriptexecute_event) on the {{domxref("Element")}} interface are on the path to removal. They have been disabled in Nightly. -([Firefox bug 1954685](https://bugzil.la/1954685)). - -| Release channel | Version added | Enabled by default? | -| ----------------- | ------------- | ------------------- | -| Nightly | 139 | No | -| Developer Edition | 139 | Yes | -| Beta | 139 | Yes | -| Release | 139 | Yes | - -- `dom.events.script_execute.enable` - - : Set to `true` to enable. - ### Notification actions and maxActions properties 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 in Nightly on desktop. diff --git a/files/en-us/mozilla/firefox/releases/149/index.md b/files/en-us/mozilla/firefox/releases/149/index.md index 396fb5942763839..2626338f28bdf95 100644 --- a/files/en-us/mozilla/firefox/releases/149/index.md +++ b/files/en-us/mozilla/firefox/releases/149/index.md @@ -92,6 +92,8 @@ Firefox 149 is the current [Beta version of Firefox](https://www.firefox.com/en- ## Changes for add-on developers +- A user gesture is no longer required for {{WebExtAPIRef("action.openPopup")}} and {{WebExtAPIRef("browserAction.openPopup")}} to open a popup. This feature was available behind the `extensions.openPopupWithoutUserGesture.enabled` preference from Firefox 108. This change aligns Firefox's behavior with Chrome and Safari. ([Firefox bug 1799344](https://bugzil.la/1799344)) + The ability of extensions to dynamically execute code in their `moz-extension:` documents with {{WebExtAPIRef("tabs.executeScript")}}, {{WebExtAPIRef("tabs.insertCSS")}}, {{WebExtAPIRef("tabs.removeCSS")}}, {{WebExtAPIRef("scripting.executeScript")}}, {{WebExtAPIRef("scripting.insertCSS")}}, and {{WebExtAPIRef("scripting.removeCSS")}} is deprecated. The feature is no longer available in Firefox Nightly, and the beta and release versions of Firefox provide a warning in the tab's console. This restriction will apply to all versions of Firefox 152 and later. As an alternative, an extension can run code in its documents dynamically by registering a {{WebExtAPIRef("runtime.onMessage")}} listener in the document's script, then sending a message to trigger execution of the required code.([Firefox bug 2011234](https://bugzil.la/2011234)) diff --git a/files/en-us/web/api/bufferedchangeevent/addedranges/index.md b/files/en-us/web/api/bufferedchangeevent/addedranges/index.md new file mode 100644 index 000000000000000..58c619e997492db --- /dev/null +++ b/files/en-us/web/api/bufferedchangeevent/addedranges/index.md @@ -0,0 +1,34 @@ +--- +title: "BufferedChangeEvent: addedRanges property" +short-title: addedRanges +slug: Web/API/BufferedChangeEvent/addedRanges +page-type: web-api-instance-property +browser-compat: api.BufferedChangeEvent.addedRanges +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`addedRanges`** read-only property of the {{domxref("BufferedChangeEvent")}} interface returns a {{domxref("TimeRanges")}} object representing the time ranges that were added to the associated {{domxref("ManagedSourceBuffer")}}. These are the ranges added between the last `updatestart` and `updateend` events, during the most recent run of the coded frame processing algorithm. + +## Value + +A {{domxref("TimeRanges")}} object. + +## Examples + +See the main {{domxref("BufferedChangeEvent")}} page for an example showing the use of `addedRanges`. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("BufferedChangeEvent.removedRanges")}} +- {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("TimeRanges")}} diff --git a/files/en-us/web/api/bufferedchangeevent/bufferedchangeevent/index.md b/files/en-us/web/api/bufferedchangeevent/bufferedchangeevent/index.md new file mode 100644 index 000000000000000..ed658cba664b76b --- /dev/null +++ b/files/en-us/web/api/bufferedchangeevent/bufferedchangeevent/index.md @@ -0,0 +1,65 @@ +--- +title: "BufferedChangeEvent: BufferedChangeEvent() constructor" +short-title: BufferedChangeEvent() +slug: Web/API/BufferedChangeEvent/BufferedChangeEvent +page-type: web-api-constructor +browser-compat: api.BufferedChangeEvent.BufferedChangeEvent +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`BufferedChangeEvent()`** constructor of the {{domxref("BufferedChangeEvent")}} interface creates a new `BufferedChangeEvent` object instance. + +## Syntax + +```js-nolint +new BufferedChangeEvent(type, options) +``` + +### Parameters + +- `type` + - : A string representing the type of event. In the case of `BufferedChangeEvent` this is always `bufferedchange`. +- `options` {{optional_inline}} + - : An object that, _in addition to the properties defined in {{domxref("Event/Event", "Event()")}}_, has the following properties: + + > [!NOTE] + > Although the spec marks `options` as optional, Safari (currently the only implementation) throws a `TypeError` if the argument is omitted entirely. Passing an empty object (`{}`) works correctly. + - `addedRanges` {{optional_inline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges added to the buffer. + - `removedRanges` {{optional_inline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges removed from the buffer. + +### Return value + +A new {{domxref("BufferedChangeEvent")}} object instance. + +## Examples + +### Inspecting a bufferedchange event + +The `BufferedChangeEvent()` constructor isn't generally called manually. When a {{domxref("ManagedSourceBuffer")}}'s `bufferedchange` event fires (meaning its buffered ranges change), the browser will construct a `BufferedChangeEvent` object to use as the event object. + +The event's properties describe what changed: + +```js +sourceBuffer.addEventListener("bufferedchange", (event) => { + console.log(event instanceof BufferedChangeEvent); // true + console.log(event.type); // "bufferedchange" + console.log(event.addedRanges); // TimeRanges — ranges added to the buffer + console.log(event.removedRanges); // TimeRanges — ranges removed from the buffer +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event diff --git a/files/en-us/web/api/bufferedchangeevent/index.md b/files/en-us/web/api/bufferedchangeevent/index.md new file mode 100644 index 000000000000000..4d4da18e72919c3 --- /dev/null +++ b/files/en-us/web/api/bufferedchangeevent/index.md @@ -0,0 +1,79 @@ +--- +title: BufferedChangeEvent +slug: Web/API/BufferedChangeEvent +page-type: web-api-interface +browser-compat: api.BufferedChangeEvent +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`BufferedChangeEvent`** interface of the {{domxref("Media Source Extensions API", "Media Source Extensions API", "", "nocode")}} represents the event object for the {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event fired on a {{domxref("ManagedSourceBuffer")}}. This event is fired whenever the buffered ranges of the `ManagedSourceBuffer` change, for example as a result of {{domxref("SourceBuffer.appendBuffer", "appendBuffer()")}}, {{domxref("SourceBuffer.remove", "remove()")}}, or {{domxref("MediaSource.endOfStream", "endOfStream()")}} calls, or when the user agent runs the memory cleanup algorithm. + +{{InheritanceDiagram}} + +## Constructor + +- {{domxref("BufferedChangeEvent.BufferedChangeEvent", "BufferedChangeEvent()")}} + - : Creates and returns a new `BufferedChangeEvent` object. + +## Instance properties + +_Also inherits properties from its parent interface, {{domxref("Event")}}._ + +- {{domxref("BufferedChangeEvent.addedRanges")}} {{ReadOnlyInline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges that were added to the {{domxref("ManagedSourceBuffer")}}'s buffer. +- {{domxref("BufferedChangeEvent.removedRanges")}} {{ReadOnlyInline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges that were removed from the {{domxref("ManagedSourceBuffer")}}'s buffer. + +## Examples + +### Handling buffered range changes + +This example creates a {{domxref("ManagedMediaSource")}}, attaches it to a {{htmlelement("video")}} element, fetches a fragmented MP4 file, and listens for the `bufferedchange` event. When the event fires, it logs the added time ranges. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", async () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + sourceBuffer.addEventListener("bufferedchange", (event) => { + for (let i = 0; i < event.addedRanges.length; i++) { + console.log( + `Added range: ${event.addedRanges.start(i)} - ${event.addedRanges.end(i)}`, + ); + } + }); + + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource")}} +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("MediaSource")}} +- {{domxref("SourceBuffer")}} diff --git a/files/en-us/web/api/bufferedchangeevent/removedranges/index.md b/files/en-us/web/api/bufferedchangeevent/removedranges/index.md new file mode 100644 index 000000000000000..15d70cd2f8aeee8 --- /dev/null +++ b/files/en-us/web/api/bufferedchangeevent/removedranges/index.md @@ -0,0 +1,76 @@ +--- +title: "BufferedChangeEvent: removedRanges property" +short-title: removedRanges +slug: Web/API/BufferedChangeEvent/removedRanges +page-type: web-api-instance-property +browser-compat: api.BufferedChangeEvent.removedRanges +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`removedRanges`** read-only property of the {{domxref("BufferedChangeEvent")}} interface returns a {{domxref("TimeRanges")}} object representing the time ranges that were removed from the associated {{domxref("ManagedSourceBuffer")}}. These are the ranges removed between the last `updatestart` and `updateend` events, during the most recent run of the coded frame removal or coded frame eviction algorithm, or as a consequence of the user agent running the memory cleanup algorithm. + +## Value + +A {{domxref("TimeRanges")}} object. + +## Examples + +### Logging removed ranges on buffer change + +This example creates a {{domxref("ManagedMediaSource")}}, attaches it to a {{htmlelement("video")}} element, fetches a fragmented MP4 file, and then removes a portion of the buffered data. The `bufferedchange` event handler logs any removed time ranges. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", async () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + sourceBuffer.addEventListener("bufferedchange", (event) => { + const removed = event.removedRanges; + for (let i = 0; i < removed.length; i++) { + console.log(`Removed range: ${removed.start(i)}s - ${removed.end(i)}s`); + } + }); + + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + + // Once appended, remove the first 5 seconds to trigger removedRanges + sourceBuffer.addEventListener( + "updateend", + () => { + sourceBuffer.remove(0, 5); + }, + { once: true }, + ); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("BufferedChangeEvent.addedRanges")}} +- {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("TimeRanges")}} diff --git a/files/en-us/web/api/managedmediasource/endstreaming_event/index.md b/files/en-us/web/api/managedmediasource/endstreaming_event/index.md new file mode 100644 index 000000000000000..6320e6b510e11f7 --- /dev/null +++ b/files/en-us/web/api/managedmediasource/endstreaming_event/index.md @@ -0,0 +1,83 @@ +--- +title: "ManagedMediaSource: endstreaming event" +short-title: endstreaming +slug: Web/API/ManagedMediaSource/endstreaming_event +page-type: web-api-event +browser-compat: api.ManagedMediaSource.endstreaming_event +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`endstreaming`** event of the {{domxref("ManagedMediaSource")}} interface is fired when the {{domxref("ManagedMediaSource.streaming", "streaming")}} property changes from `true` to `false`. This indicates that the user agent has enough data buffered to ensure uninterrupted playback, and the application can stop fetching new media segments. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js-nolint +addEventListener("endstreaming", (event) => {}); + +onendstreaming = (event) => {}; +``` + +## Event type + +A generic {{domxref("Event")}}. + +## Examples + +### Pausing fetches in response to endstreaming + +This example creates a {{domxref("ManagedMediaSource")}}, attaches it to a {{htmlelement("video")}} element, and uses the `startstreaming` and `endstreaming` events to control when media segments are fetched. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + let shouldFetch = false; + + source.addEventListener("sourceopen", () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + source.addEventListener("startstreaming", async () => { + console.log("startstreaming — fetching media data"); + shouldFetch = true; + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + if (shouldFetch) { + sourceBuffer.appendBuffer(data); + } + }); + + source.addEventListener("endstreaming", () => { + console.log("endstreaming — enough data buffered"); + shouldFetch = false; + }); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} event +- {{domxref("ManagedMediaSource.streaming")}} +- {{domxref("ManagedMediaSource")}} +- {{domxref("MediaSource")}} diff --git a/files/en-us/web/api/managedmediasource/index.md b/files/en-us/web/api/managedmediasource/index.md new file mode 100644 index 000000000000000..4d2c8f0f3a2a7a6 --- /dev/null +++ b/files/en-us/web/api/managedmediasource/index.md @@ -0,0 +1,103 @@ +--- +title: ManagedMediaSource +slug: Web/API/ManagedMediaSource +page-type: web-api-interface +browser-compat: api.ManagedMediaSource +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`ManagedMediaSource`** interface of the {{domxref("Media Source Extensions API", "Media Source Extensions API", "", "nocode")}} is a {{domxref("MediaSource")}} that actively manages its memory content. Unlike a regular `MediaSource`, the user agent can evict content from its {{domxref("ManagedSourceBuffer")}} objects at any time, for reasons such as memory or hardware limitations. This makes it suitable for power-efficient streaming scenarios where the user agent needs more control over buffered media data. + +When {{domxref("MediaSource.addSourceBuffer", "addSourceBuffer()")}} is called on a `ManagedMediaSource`, it creates {{domxref("ManagedSourceBuffer")}} objects (instead of {{domxref("SourceBuffer")}} objects), which fire {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} events to notify the application when buffered ranges are modified by the user agent. + +> [!NOTE] +> On Safari, `ManagedMediaSource` only activates when remote playback is explicitly disabled on the media element (by setting {{domxref("HTMLMediaElement.disableRemotePlayback")}} to `true`), or when an AirPlay source alternative is provided (for example, an HLS {{htmlelement("source")}} element). Without either of these, the {{domxref("MediaSource.sourceopen_event", "sourceopen")}} event will not fire. + +{{InheritanceDiagram}} + +## Constructor + +- {{domxref("ManagedMediaSource.ManagedMediaSource", "ManagedMediaSource()")}} + - : Creates and returns a new `ManagedMediaSource` object instance with no associated source buffers. + +## Instance properties + +_Also inherits properties from its parent interface, {{domxref("MediaSource")}}._ + +- {{domxref("ManagedMediaSource.streaming")}} {{ReadOnlyInline}} + - : A boolean indicating whether the `ManagedMediaSource` object is currently streaming. When `true`, the application should actively fetch and append media data. When `false`, the application can stop fetching new data. + +## Instance methods + +_Inherits methods from its parent interface, {{domxref("MediaSource")}}._ + +## Events + +_Also inherits events from its parent interface, {{domxref("MediaSource")}}._ + +- {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} + - : Fired when the `ManagedMediaSource`'s {{domxref("ManagedMediaSource.streaming", "streaming")}} property changes from `false` to `true`, meaning the media source has started streaming. +- {{domxref("ManagedMediaSource.endstreaming_event", "endstreaming")}} + - : Fired when the `ManagedMediaSource`'s {{domxref("ManagedMediaSource.streaming", "streaming")}} property changes from `true` to `false`, meaning the media source has stopped streaming. + +## Examples + +### Setting up a managed media source + +The following example sets up a `ManagedMediaSource`, connects it to a {{htmlelement("video")}} element, and listens for the {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} and {{domxref("ManagedMediaSource.endstreaming_event", "endstreaming")}} events to control when media data is fetched. {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} events are logged below the video. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; +const video = document.querySelector("video"); + +if (!window.ManagedMediaSource?.isTypeSupported(mediaType)) { + console.log("ManagedMediaSource is not supported in this browser."); +} else { + const source = new ManagedMediaSource(); + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + + source.addEventListener("sourceopen", () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + sourceBuffer.addEventListener("bufferedchange", (event) => { + for (let i = 0; i < event.addedRanges.length; i++) { + console.log( + `Buffered: ${event.addedRanges.start(i).toFixed(2)}s – ${event.addedRanges.end(i).toFixed(2)}s`, + ); + } + }); + + source.addEventListener("startstreaming", async () => { + console.log("startstreaming — fetching media data…"); + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); + + source.addEventListener("endstreaming", () => { + console.log("endstreaming — enough data buffered"); + }); + }); +} +``` + +{{EmbedGHLiveSample("dom-examples/media-source-extensions/managed-media-source/", '100%', 470)}} + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("MediaSource")}} +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("BufferedChangeEvent")}} +- {{domxref("SourceBuffer")}} diff --git a/files/en-us/web/api/managedmediasource/managedmediasource/index.md b/files/en-us/web/api/managedmediasource/managedmediasource/index.md new file mode 100644 index 000000000000000..bbeae4ab13f1e1b --- /dev/null +++ b/files/en-us/web/api/managedmediasource/managedmediasource/index.md @@ -0,0 +1,72 @@ +--- +title: "ManagedMediaSource: ManagedMediaSource() constructor" +short-title: ManagedMediaSource() +slug: Web/API/ManagedMediaSource/ManagedMediaSource +page-type: web-api-constructor +browser-compat: api.ManagedMediaSource.ManagedMediaSource +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`ManagedMediaSource()`** constructor of the {{domxref("ManagedMediaSource")}} interface constructs and returns a new `ManagedMediaSource` object instance with no associated source buffers. + +## Syntax + +```js-nolint +new ManagedMediaSource() +``` + +### Parameters + +None. + +### Return value + +A new {{domxref("ManagedMediaSource")}} object instance. + +## Examples + +### Creating a ManagedMediaSource and attaching it to a video element + +The following example creates a new `ManagedMediaSource`, attaches it to a {{htmlelement("video")}} element, and uses the {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} event to begin fetching media data. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const source = new ManagedMediaSource(); + const video = document.createElement("video"); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + source.addEventListener("startstreaming", async () => { + console.log("startstreaming — fetching media data"); + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource")}} +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("MediaSource.MediaSource", "MediaSource()")}} diff --git a/files/en-us/web/api/managedmediasource/startstreaming_event/index.md b/files/en-us/web/api/managedmediasource/startstreaming_event/index.md new file mode 100644 index 000000000000000..c18a837fbfee90f --- /dev/null +++ b/files/en-us/web/api/managedmediasource/startstreaming_event/index.md @@ -0,0 +1,73 @@ +--- +title: "ManagedMediaSource: startstreaming event" +short-title: startstreaming +slug: Web/API/ManagedMediaSource/startstreaming_event +page-type: web-api-event +browser-compat: api.ManagedMediaSource.startstreaming_event +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`startstreaming`** event of the {{domxref("ManagedMediaSource")}} interface is fired when the {{domxref("ManagedMediaSource.streaming", "streaming")}} property changes from `false` to `true`. This indicates that the user agent needs more data to ensure uninterrupted playback, and the application should begin fetching and appending media segments. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js-nolint +addEventListener("startstreaming", (event) => {}); + +onstartstreaming = (event) => {}; +``` + +## Event type + +A generic {{domxref("Event")}}. + +## Examples + +### Fetching data in response to startstreaming + +This example creates a {{domxref("ManagedMediaSource")}}, attaches it to a {{htmlelement("video")}} element, and uses the `startstreaming` event to begin fetching and appending media data. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + source.addEventListener("startstreaming", async () => { + console.log("startstreaming — fetching media data"); + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource.endstreaming_event", "endstreaming")}} event +- {{domxref("ManagedMediaSource.streaming")}} +- {{domxref("ManagedMediaSource")}} +- {{domxref("MediaSource")}} diff --git a/files/en-us/web/api/managedmediasource/streaming/index.md b/files/en-us/web/api/managedmediasource/streaming/index.md new file mode 100644 index 000000000000000..c27e85b73b5f9ab --- /dev/null +++ b/files/en-us/web/api/managedmediasource/streaming/index.md @@ -0,0 +1,66 @@ +--- +title: "ManagedMediaSource: streaming property" +short-title: streaming +slug: Web/API/ManagedMediaSource/streaming +page-type: web-api-instance-property +browser-compat: api.ManagedMediaSource.streaming +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`streaming`** read-only property of the {{domxref("ManagedMediaSource")}} interface is a boolean indicating whether the application should actively fetch and append media data. + +The value of this property is updated by the user agent's monitoring algorithm. When it changes, the corresponding {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} or {{domxref("ManagedMediaSource.endstreaming_event", "endstreaming")}} event is fired. + +## Value + +A boolean, initially `false`. When `true`, the user agent needs more data to ensure uninterrupted playback. When `false`, the user agent has enough data buffered and the application can stop fetching new segments. + +## Examples + +### Checking the streaming state + +This example creates a {{domxref("ManagedMediaSource")}}, attaches it to a {{htmlelement("video")}} element, and logs the value of `streaming` whenever it changes between `true` and `false`. + +```js +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + console.log(source.streaming); // false + + source.addEventListener("startstreaming", () => { + console.log(source.streaming); // true — start fetching data + }); + + source.addEventListener("endstreaming", () => { + console.log(source.streaming); // false — stop fetching data + }); + + source.addEventListener("sourceopen", () => { + source.addSourceBuffer(mediaType); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource.startstreaming_event", "startstreaming")}} event +- {{domxref("ManagedMediaSource.endstreaming_event", "endstreaming")}} event +- {{domxref("ManagedMediaSource")}} +- {{domxref("MediaSource")}} diff --git a/files/en-us/web/api/managedsourcebuffer/bufferedchange_event/index.md b/files/en-us/web/api/managedsourcebuffer/bufferedchange_event/index.md new file mode 100644 index 000000000000000..63d95bdda410b1a --- /dev/null +++ b/files/en-us/web/api/managedsourcebuffer/bufferedchange_event/index.md @@ -0,0 +1,96 @@ +--- +title: "ManagedSourceBuffer: bufferedchange event" +short-title: bufferedchange +slug: Web/API/ManagedSourceBuffer/bufferedchange_event +page-type: web-api-event +browser-compat: api.ManagedSourceBuffer.bufferedchange_event +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`bufferedchange`** event of the {{domxref("ManagedSourceBuffer")}} interface is fired when the `ManagedSourceBuffer`'s buffered range changes. This can occur following a call to {{domxref("SourceBuffer.appendBuffer", "appendBuffer()")}}, {{domxref("SourceBuffer.remove", "remove()")}}, {{domxref("MediaSource.endOfStream", "endOfStream()")}}, or as a consequence of the user agent running the memory cleanup algorithm. + +This event is important for applications using a {{domxref("ManagedMediaSource")}}, because the user agent can evict buffered content at any time. By listening for this event, applications can detect when buffered data has been removed and respond by fetching replacement segments to avoid playback stalls. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js-nolint +addEventListener("bufferedchange", (event) => {}); + +onbufferedchange = (event) => {}; +``` + +## Event type + +A {{domxref("BufferedChangeEvent")}}. Inherits from {{domxref("Event")}}. + +{{InheritanceDiagram("BufferedChangeEvent")}} + +## Event properties + +_In addition to the properties listed below, properties from the parent interface, {{domxref("Event")}}, are available._ + +- {{domxref("BufferedChangeEvent.addedRanges", "addedRanges")}} {{ReadOnlyInline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges that were added to the buffer. +- {{domxref("BufferedChangeEvent.removedRanges", "removedRanges")}} {{ReadOnlyInline}} + - : A {{domxref("TimeRanges")}} object representing the time ranges that were removed from the buffer. + +## Examples + +### Tracking buffered range changes + +This example sets up a {{domxref("ManagedMediaSource")}}, adds a source buffer, fetches a fragmented MP4 file, and listens for the `bufferedchange` event to log any changes to the buffered ranges. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const source = new ManagedMediaSource(); + const video = document.createElement("video"); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", async () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + sourceBuffer.addEventListener("bufferedchange", (event) => { + for (let i = 0; i < event.addedRanges.length; i++) { + console.log( + `Added: ${event.addedRanges.start(i)}s - ${event.addedRanges.end(i)}s`, + ); + } + for (let i = 0; i < event.removedRanges.length; i++) { + console.log( + `Removed: ${event.removedRanges.start(i)}s - ${event.removedRanges.end(i)}s`, + ); + } + }); + + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("BufferedChangeEvent")}} +- {{domxref("ManagedMediaSource")}} +- {{domxref("ManagedSourceBuffer")}} +- {{domxref("SourceBuffer")}} diff --git a/files/en-us/web/api/managedsourcebuffer/index.md b/files/en-us/web/api/managedsourcebuffer/index.md new file mode 100644 index 000000000000000..a78a12701214ed4 --- /dev/null +++ b/files/en-us/web/api/managedsourcebuffer/index.md @@ -0,0 +1,82 @@ +--- +title: ManagedSourceBuffer +slug: Web/API/ManagedSourceBuffer +page-type: web-api-interface +browser-compat: api.ManagedSourceBuffer +--- + +{{APIRef("Media Source Extensions")}}{{AvailableInWorkers("window_and_dedicated")}} + +The **`ManagedSourceBuffer`** interface of the {{domxref("Media Source Extensions API", "Media Source Extensions API", "", "nocode")}} is a {{domxref("SourceBuffer")}} that is created by a {{domxref("ManagedMediaSource")}} when {{domxref("MediaSource.addSourceBuffer", "addSourceBuffer()")}} is called. It inherits all the properties and methods of `SourceBuffer`, and additionally fires a {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event whenever the buffered ranges change — including when the user agent evicts content as part of its memory cleanup algorithm. + +Applications should listen for the `bufferedchange` event to track changes to buffered data, since a `ManagedMediaSource` may evict content at any time for reasons such as memory or hardware limitations. + +{{InheritanceDiagram}} + +## Instance properties + +_Inherits properties from its parent interface, {{domxref("SourceBuffer")}}._ + +## Instance methods + +_Inherits methods from its parent interface, {{domxref("SourceBuffer")}}._ + +## Events + +_Also inherits events from its parent interface, {{domxref("SourceBuffer")}}._ + +- {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} + - : Fired when the `ManagedSourceBuffer`'s buffered range changes, following a call to {{domxref("SourceBuffer.appendBuffer", "appendBuffer()")}}, {{domxref("SourceBuffer.remove", "remove()")}}, {{domxref("MediaSource.endOfStream", "endOfStream()")}}, or as a consequence of the user agent running the memory cleanup algorithm. + +## Examples + +### Listening for buffered range changes + +This example sets up a {{domxref("ManagedMediaSource")}}, adds a `ManagedSourceBuffer`, fetches a fragmented MP4 file, and listens for the `bufferedchange` event to log any changes to the buffered ranges. + +```js +const videoUrl = + "https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4"; +const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'; + +if (ManagedMediaSource.isTypeSupported(mediaType)) { + const source = new ManagedMediaSource(); + const video = document.createElement("video"); + + video.controls = true; + video.disableRemotePlayback = true; + video.src = URL.createObjectURL(source); + document.body.appendChild(video); + + source.addEventListener("sourceopen", async () => { + const sourceBuffer = source.addSourceBuffer(mediaType); + + sourceBuffer.addEventListener("bufferedchange", (event) => { + for (let i = 0; i < event.addedRanges.length; i++) { + console.log( + `Added: ${event.addedRanges.start(i)}s - ${event.addedRanges.end(i)}s`, + ); + } + }); + + const response = await fetch(videoUrl); + const data = await response.arrayBuffer(); + sourceBuffer.appendBuffer(data); + }); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{domxref("ManagedMediaSource")}} +- {{domxref("BufferedChangeEvent")}} +- {{domxref("SourceBuffer")}} +- {{domxref("MediaSource")}} diff --git a/files/en-us/web/api/media_source_extensions_api/index.md b/files/en-us/web/api/media_source_extensions_api/index.md index 4cf0d5877096f61..6c03855e613baf4 100644 --- a/files/en-us/web/api/media_source_extensions_api/index.md +++ b/files/en-us/web/api/media_source_extensions_api/index.md @@ -51,6 +51,12 @@ See [MSE-in-Workers Demo by Matt Wolenetz](https://wolenetz.github.io/mse-in-wor - : Represents a chunk of media to be passed into an {{domxref("HTMLMediaElement")}} via a `MediaSource` object. - {{domxref("SourceBufferList")}} - : A simple container list for multiple `SourceBuffer` objects. +- {{domxref("ManagedMediaSource")}} + - : A {{domxref("MediaSource")}} that actively manages its memory content. Unlike a regular `MediaSource`, a `ManagedMediaSource` can evict content from its source buffers at any time for reasons such as memory or hardware limitations. +- {{domxref("ManagedSourceBuffer")}} + - : A {{domxref("SourceBuffer")}} created by a `ManagedMediaSource`. Fires {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} events to notify the application when buffered ranges are modified, including when the user agent evicts content. +- {{domxref("BufferedChangeEvent")}} + - : The event object for the {{domxref("ManagedSourceBuffer.bufferedchange_event", "bufferedchange")}} event, which contains {{domxref("TimeRanges")}} representing the added and removed buffered ranges. - {{domxref("VideoPlaybackQuality")}} - : Contains information about the quality of video being played by a {{htmlelement("video")}} element, such as number of dropped or corrupted frames. Returned by the {{domxref("HTMLVideoElement.getVideoPlaybackQuality()")}} method. diff --git a/files/en-us/web/api/window/pageshow_event/index.md b/files/en-us/web/api/window/pageshow_event/index.md index aeb365015d29dc3..4add2845a0225d1 100644 --- a/files/en-us/web/api/window/pageshow_event/index.md +++ b/files/en-us/web/api/window/pageshow_event/index.md @@ -8,14 +8,23 @@ browser-compat: api.Window.pageshow_event {{APIRef("HTML DOM")}} -The **`pageshow`** event is sent to a {{domxref("Window")}} when the browser displays the window's document due to navigation. +The **`pageshow`** event is sent to a {{domxref("Window")}} when the browser navigates to a new document. This includes: -- Initially loading the page -- Navigating to the page from another page in the same window or tab -- Restoring a frozen page on mobile OSes -- Returning to the page using the browser's forward or back buttons +- Initially loading the page. +- Navigating to the page from another page in the same window or tab. +- Restoring a frozen page on mobile OSes. +- Returning to the page using the browser's forward or back buttons (including when restored from the {{Glossary("bfcache")}}). +- Opening a page in a background tab. +- {{Glossary("Prerender", "Prerendering")}} a page, even before it is activated. + +> [!WARNING] +> Despite the name, the `pageshow` event does not fire when the page is actually _shown_ to the user. For example, it may be opened in a background tab or prerendered. If you are interested in responding to the page being shown to the user, use the following events: +> +> - {{domxref("window/pagereveal_event", "pagereveal")}}: Sent when a page is first rendered. +> - {{domxref("document/visibilitychange_event", "visibilitychange")}}: Sent each time a page's visibility changes. +> - {{domxref("document/prerenderingchange_event", "prerenderingchange")}}: Sent when a prerendered page is activated. > [!NOTE] > During the initial page load, the `pageshow` event fires _after_ the {{domxref("Window/load_event", "load")}} event. diff --git a/files/en-us/web/css/guides/conditional_rules/container_scroll-state_queries/index.md b/files/en-us/web/css/guides/conditional_rules/container_scroll-state_queries/index.md index f969c853ac34b61..ad694aa42aa8f51 100644 --- a/files/en-us/web/css/guides/conditional_rules/container_scroll-state_queries/index.md +++ b/files/en-us/web/css/guides/conditional_rules/container_scroll-state_queries/index.md @@ -14,6 +14,7 @@ This article explains how to use container scroll-state queries, walking through There are three `@container` descriptors you can use in a `scroll-state()` query: - `scrollable`: Queries whether a container can be scrolled in the given direction via user-initiated scrolling (for example by dragging the scrollbar or using a trackpad gesture). In other words, is there any overflowing content in the given direction that can be scrolled to? This is useful for applying styling related to the scroll position of a scroll container. For example, you could display a hint that encourages people to scroll down and see more content when the scrollbar is up at the top, and hide it when the user has actually started scrolling. +- `scrolled`: Queries whether a container was most recently scrolled in the given direction. This allows you to selectively apply styles based on the user's scroll direction, for example a top menu bar that only displays when the user is scrolling upwards. - `snapped`: Queries whether a container is going to be snapped to a [scroll snap](/en-US/docs/Web/CSS/Guides/Scroll_snap) container ancestor along a given axis. This is useful for applying styles when an element is snapped to a scroll snap container. For example, you might want to highlight a snapped element in some way, or reveal some of its content that was previously hidden. - `stuck`: Queries whether a container with a {{cssxref("position")}} value of `sticky` is stuck to an edge of its scroll container ancestor. This is useful for styling `position: sticky` elements differently when stuck — for example, you could give them a different color scheme or layout. @@ -43,9 +44,9 @@ Here, we query only containers named `my-container` to determine whether the con ## Using `scrollable` queries -Scroll-state [`scrollable`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrollable) queries, written as `scroll-state(scrollable: value)`, test whether a container's scrolling ancestor can be scrolled in the given direction via user-initiated scrolling. If not, the query returns false. +Scroll-state [`scrollable`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrollable) queries, written as `scroll-state(scrollable: )`, test whether a container's scrolling ancestor can be scrolled in the given direction via user-initiated scrolling. If not, the query returns false. -The `value` indicates the direction you are testing for scrolling availability in, for example: +The keyword value indicates the direction you are testing for scrolling availability in, for example: - `top`: Tests whether the container can be scrolled towards its top edge. - `inline-end`: Tests whether the container can be scrolled towards its inline-end edge. @@ -325,11 +326,304 @@ We've hidden the rest of the example CSS for brevity. Try scrolling the document down, and note how the "back-to-top" link appears as a result, animating smoothly from the right side of the viewport due to the `transition`. If you scroll back to the top by activating the link or manually scrolling, the "back-to-top" link transitions off-screen. +## Using `scrolled` queries + +Scroll-state [`scrolled`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrolled) queries, written as `scroll-state(scrolled: )`, test whether a container's scrolling ancestor was most recently scrolled in the given direction. If not, the query returns false. + +The keyword value indicates the direction you are testing. For example: + +- `block-start`: Tests whether the container was most recently scrolled towards its block-start edge. +- `right`: Tests whether the container was most recently scrolled towards its right-hand edge. +- `y`: Tests whether the container was most recently scrolled up or down along the y axis. +- `none`: Tests whether the container is not a {{glossary("scroll container")}} or has not been scrolled in any direction since rendering. + +If the test returns true, the rules inside the `@container` block are applied to the descendants of the matching scroll container. + +Let's look at an example of a scroll container with a `scrolled` query that displays top and bottom content "bars" only when the user is scrolling up or down, respectively. + +### HTML + +In our HTML, we have an {{htmlelement("article")}} element containing enough content to cause the document to scroll, preceded by two {{htmlelement("div")}} elements that represent our top and bottom "bars": + +```html +
You're currently scrolling towards the top.
+
+ You're currently scrolling towards the bottom. +
+
+

Document with scrolled container query

+
+
+

This first section is interesting

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+ + ... +
+ + ... +
+``` + +We have hidden most of the HTML for brevity. + +```html hidden live-sample___scrolled +
You're currently scrolling towards the top.
+
+ You're currently scrolling towards the bottom. +
+
+

Document with scrolled container query

+
+
+

This first section is interesting

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+
+ +

+ Mauris non malesuada est, sed vestibulum nibh. Duis vestibulum iaculis + lectus, eu sagittis dolor dignissim iaculis. Nunc et orci sed sapien + eleifend placerat. Curabitur dapibus risus eget odio sollicitudin, sit + amet luctus justo pellentesque. +

+ +

+ Morbi non pharetra quam. Fusce vestibulum sem diam, ac + consequat augue consectetur ut. Donec at augue viverra, tempus urna sit + amet, porta augue. + Phasellus fringilla tincidunt sem ullamcorper varius. Aenean + gravida feugiat sem nec ultricies. +

+ + Placeholder + +

+ Sed pellentesque placerat mi sed maximus. Sed vitae dui vitae mi pulvinar + gravida sed et libero. + Duis nec venenatis dolor, sed tristique felis. + Integer dapibus facilisis leo elementum vulputate. Curabitur a urna quis + nulla vulputate tincidunt quis ac enim. +

+ +

+ Cras non elit vel leo dignissim convallis. Duis eros urna, varius sit amet + lorem vel, feugiat euismod est. + Aliquam ornare eu elit ut iaculis. + Suspendisse vulputate tempor leo, non rhoncus risus aliquam vel. +

+
+
+
+

This one, not so much

+ +

Suspendisse varius est ac turpis mollis cursus.

+
+ +

+ Curabitur faucibus condimentum eros, ut auctor felis lacinia + sed. + Praesent vitae scelerisque eros. +

+ +

+ Ut vitae suscipit augue. Cras et orci condimentum ante dignissim + iaculis. Sed consectetur quis est sed dignissim. Nulla egestas orci erat, + et commodo arcu feugiat ut. +

+ + Placeholder + +

+ Sed non tempor massa, at accumsan ante. Pellentesque habitant morbi + tristique senectus et netus et malesuada fames ac turpis + egestas. +

+ +

+ Pellentesque placerat luctus tempor. Nunc congue dapibus eros, at + vulputate nulla. Sed rutrum eleifend magna vel porta. Integer cursus orci + faucibus turpis scelerisque, nec pharetra arcu molestie. +

+
+
+
+

Hopefully this section provides some clarity?

+ +

Curabitur facilisis ornare lorem et eleifend.

+
+ +

+ Aenean mollis non neque sed finibus. Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Suspendisse sagittis viverra urna. + In hac habitasse platea dictumst. Vestibulum neque orci, mollis sagittis + augue et, pharetra vehicula diam. +

+ + Placeholder + +

+ Pellentesque sollicitudin nunc quis nisl condimentum, ac + iaculis libero feugiat. + Nullam ultrices purus a nulla dignissim hendrerit. In + molestie consectetur est quis pulvinar. +

+ +

+ Vivamus ac erat eu est lobortis commodo. Orci varius natoque penatibus et + magnis dis parturient montes, nascetur ridiculus mus. In nulla turpis, + mollis et est tempor, dignissim aliquam metus. Proin eu + arcu quis erat mollis pulvinar. Vivamus at facilisis neque. +

+ +

+ Integer bibendum laoreet erat, quis vulputate mauris bibendum nec. Class + aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos + himenaeos. Nam ut est in arcu interdum hendrerit. +

+
+
+
+

A summary of sorts

+ +

Nunc facilisis augue quis ex porta aliquam.

+
+ + Placeholder + +

+ Fusce nisi enim, venenatis a est vel, varius placerat lacus. + Nunc tempus rutrum nisl bibendum aliquet. Pellentesque vitae nunc sed nisl + tincidunt elementum a sit amet nisi. Morbi pretium at dolor in pulvinar. + Curabitur dapibus eleifend accumsan. +

+ +

+ Donec rhoncus, leo vitae mollis maximus, tellus lorem interdum arcu, eu + tempor lectus libero in risus. Ut sit amet magna vitae mauris + tempor bibendum. Integer id mauris ut ex mattis finibus. +

+ +

+ Curabitur dui felis, elementum et tellus id, blandit facilisis lorem. + Aliquam sed posuere ligula, at auctor ipsum. Morbi dignissim accumsan + tellus pretium iaculis. +

+
+
+``` + +### CSS + +The "bars" are given some rudimentary styling. Most significantly, they are given a {{cssxref("position")}} value of `fixed`, which we offset from either side using {{cssxref("left")}} and {{cssxref("right")}} values. + +```css hidden live-sample___scrolled +/* General styling */ + +* { + box-sizing: border-box; +} + +html { + font-family: Arial, Helvetica, sans-serif; + height: 100%; +} + +body { + height: inherit; + width: 90%; + margin: 0 auto; +} + +p { + line-height: 1.5; +} + +img { + display: block; + width: 90%; + margin: 30px auto; + padding: 20px; + border: 2px solid gray; + aspect-ratio: 3/2; +} +``` + +```css live-sample___scrolled +.bar { + border-radius: 10px; + border: 1px solid #000; + background-color: #0009; + padding: 10px; + color: white; + text-shadow: 1px 1px 1px black; + display: flex; + justify-content: center; + align-items: center; + + position: fixed; + left: 5px; + right: 5px; +} +``` + +Next, we set negative {{cssxref("top")}} and {{cssxref("bottom")}} length values on the top and bottom bars so they are hidden above and below the viewport by default. We add a {{cssxref("transition")}} to smoothly animate them into view when their {{cssxref("translate")}} values change. + +```css live-sample___scrolled +#top-bar { + top: -50px; + transition: 0.6s translate; +} + +#bottom-bar { + bottom: -50px; + transition: 0.6s translate; +} +``` + +The {{glossary("scroll container")}} in this example is the `` element itself, denoted as a scroll-state query container with a {{cssxref("container-type")}} value of `scroll-state`. The {{cssxref("container-name")}} isn't strictly necessary, but it is useful when a codebase has multiple scroll-state query containers targeted with different queries. + +```css live-sample___scrolled +html { + container-type: scroll-state; + container-name: scroller; +} +``` + +Next, we define two {{cssxref("@container")}} blocks, both of which target the `scroller` container name. The first block defines a query `scrolled: block-end` and the second defines a query `scrolled: block-start`. Respectively, these queries apply the rules contained within their block only if the `` element was most recently scrolled toward its block-end edge or block-start edge. In other words, when the container is scrolled down or up. When either condition becomes true, the bar referenced inside the block has a `translate` value set to cause it to transition on-screen. The bar referenced in the `@condition` that is no longer true transitions off-screen. + +```css live-sample___scrolled +@container scroller scroll-state(scrolled: block-start) { + #top-bar { + translate: 0 55px; + } +} + +@container scroller scroll-state(scrolled: block-end) { + #bottom-bar { + translate: 0 -55px; + } +} +``` + +We've hidden the rest of the example CSS for brevity. + +### Result + +{{EmbedLiveSample("scrolled", "100%", "400px")}} + +Try scrolling the document up and down, and note how the different bars appear as a result, animating smoothly on- and off-screen. + ## Using `snapped` queries -Relevant only when [scroll snapping](/en-US/docs/Web/CSS/Guides/Scroll_snap) is implemented, scroll-state [`snapped`](/en-US/docs/Web/CSS/Reference/At-rules/@container#snapped) queries (written as `scroll-state(snapped: value)`) test whether a container is going to be snapped to a [scroll snap container](/en-US/docs/Glossary/Scroll_snap#scroll_snap_container) ancestor along the given axis. If not, the query returns false. +Relevant only when [scroll snapping](/en-US/docs/Web/CSS/Guides/Scroll_snap) is implemented, scroll-state [`snapped`](/en-US/docs/Web/CSS/Reference/At-rules/@container#snapped) queries, written as `scroll-state(snapped: )`, test whether a container is going to be snapped to a [scroll snap container](/en-US/docs/Glossary/Scroll_snap#scroll_snap_container) ancestor along the given axis. If not, the query returns false. -The `value` in this case indicates the direction you are testing the element's ability to snap in, for example: +The keyword value in this case indicates the direction you are testing the element's ability to snap in, for example: - `x`: Tests whether the container is snapping horizontally to its scroll-snap container ancestor. - `inline`: Tests whether the container is snapping to its scroll-snap container ancestor in the inline direction. @@ -549,9 +843,9 @@ The rendered result is shown below. Try scrolling the container up and down, and ## Using `stuck` queries -Scroll-state [`stuck`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrollable) queries, written as `scroll-state(stuck: value)`, test whether a container with a {{cssxref("position")}} value of `sticky` is stuck to an edge of its scroll container ancestor. If not, the query returns false. +Scroll-state [`stuck`](/en-US/docs/Web/CSS/Reference/At-rules/@container#scrollable) queries, written as `scroll-state(stuck: )`, test whether a container with a {{cssxref("position")}} value of `sticky` is stuck to an edge of its scroll container ancestor. If not, the query returns false. -The `value` in this case indicates the scroll container edge you are testing, for example: +The keyword value in this case indicates the scroll container edge you are testing, for example: - `top`: Tests whether the container is stuck to the top edge of its scroll container ancestor. - `block-end`: Tests whether the container is stuck to the block-end edge of its scroll container ancestor. @@ -826,6 +1120,23 @@ Next, we define a {{cssxref("@container")}} block that sets the container name w } ``` +```css hidden live-sample___scrollable live-sample___scrolled live-sample___snapped live-sample___stuck +@supports not (container-type: scroll-state) { + body::before { + content: "Your browser does not support `scroll-state` container queries."; + color: black; + background-color: wheat; + position: fixed; + left: 0; + right: 0; + top: 40%; + text-align: center; + padding: 1rem 0; + z-index: 1; + } +} +``` + We have hidden the rest of the CSS for brevity. ### Result diff --git a/files/en-us/web/css/reference/at-rules/@container/index.md b/files/en-us/web/css/reference/at-rules/@container/index.md index 15a18b6a170343c..d26f8c3595b9db6 100644 --- a/files/en-us/web/css/reference/at-rules/@container/index.md +++ b/files/en-us/web/css/reference/at-rules/@container/index.md @@ -167,6 +167,9 @@ Scroll-state container descriptors are specified inside the ` + This paragraph has emphasized text, strong text, and + a link to top. +

+

+ This paragraph has emphasized text, strong text, and + a link to top. +

+``` + +#### CSS + +We don't style the inline elements in the first paragraph, so they use their default browser styles. +In the second paragraph, we set properties on each inline element to `inherit`, so they get the computed styles from the parent {{htmlelement("p")}} element. ```css -/* Make second-level headers green */ -h2 { - color: green; +p:nth-of-type(2) { + a { + text-decoration: inherit; + color: inherit; + } + em { + font-style: inherit; + } + strong { + font-weight: inherit; + } } +``` -/* Leave those in the sidebar alone so they use their parent's color */ -#sidebar h2 { - color: inherit; +#### Result + +{{EmbedLiveSample("Basic usage", "100%", 100)}} + +### Inheriting all property values + +In this example, we use the same HTML as in the previous example to demonstrate the issues that can occur when the `inherit` keyword is applied to all properties. + +```html hidden +

+ This paragraph has emphasized text, strong text, and + a link to top. +

+

+ This paragraph has emphasized text, strong text, and + a link to top. +

+``` + +#### CSS + +In the second paragraph, instead of setting individual properties to `inherit`, we set the {{cssxref("all")}} property on all inline elements to `inherit`, so they all get computed styles from their parent {{htmlelement("p")}}. + +```css +p:nth-of-type(2) > * { + all: inherit; } ``` -In this example, the `h2` elements inside the sidebar might be different colors. For example, consider one of them that would by the child of a `div` matched by the rule: +#### Result + +{{EmbedLiveSample("Inheriting all property values", "100%", 270)}} + +Notice how the inline element inherit all the properties of the parent `

`, including the paragraph's block-level {{cssxref("display")}} value. This is likely not the effect you would want. + +### Excluding selected elements from a rule + +This example demonstrates how the `inherit` keyword can be used to exclude selected elements from a color rule, allowing them to use their parent's color instead. + +#### HTML + +We include some semantically structured content. + +```html +

+

This is my blog

+

This is the subtitle of my blog in the HEADER

+

My blog is not very interesting

+
+
+

This first blog post in MAIN

+

I really have nothing to say.

+
+

This second blog post is in a SECTION within MAIN

+

+ It is in a section because it is important even though it isn't the least + bit interesting. +

+
+
+
+

Contact in FOOTER

+

Find me on Mastodon

+
+

Copyright in SECTION within FOOTER

+

1996

+
+
+``` + +#### CSS + +We set the text color of the `
` element to `blue` and all `

` elements to `green` in `monospace` font. The `

` elements inside a `
` are set to `inherit` their parent's text color. ```css -div#current { +main { color: blue; } + +h2 { + color: green; + font-family: monospace; +} + +section h2 { + color: inherit; +} ``` -Then, it would be blue. +#### Result + +{{EmbedLiveSample("Exclude selected elements from a rule", "100%", 470)}} + +The `

` elements are all `green`. However, if they are nested in a {{htmlelement("section")}} element, they inherit their color from their parent, which is `blue` within {{htmlelement("main")}}. The default text color is black otherwise. ## Specifications @@ -49,9 +159,5 @@ Then, it would be blue. ## See also +- {{cssxref("initial")}}, {{cssxref("revert")}}, {{cssxref("revert-layer")}}, and {{cssxref("unset")}} keywords - [Inheritance](/en-US/docs/Web/CSS/Guides/Cascade/Inheritance) -- Use the {{cssxref("initial")}} keyword to set a property to its initial value. -- Use the {{cssxref("revert")}} keyword to reset a property to the value established by the user-agent stylesheet (or by user styles, if any exist). -- Use the {{cssxref("revert-layer")}} keyword to reset a property to the value established in a previous cascade layer. -- Use the {{cssxref("unset")}} keyword to set a property to its inherited value if it inherits or to its initial value if not. -- The {{cssxref("all")}} property lets you reset all properties to their initial, inherited, reverted, or unset state at once. diff --git a/files/en-us/web/css/reference/values/initial/index.md b/files/en-us/web/css/reference/values/initial/index.md index 781515ee53a2f60..5e842846470880a 100644 --- a/files/en-us/web/css/reference/values/initial/index.md +++ b/files/en-us/web/css/reference/values/initial/index.md @@ -12,27 +12,36 @@ On [inherited properties](/en-US/docs/Web/CSS/Guides/Cascade/Inheritance#inherit ## Examples -### Using initial to reset color for an element +### Basic usage + +In this example, we use the `initial` keyword to reset an element's {{cssxref("color")}} and {{cssxref("font-size")}} property values. #### HTML ```html

- This text is red. - This text is in the initial color (typically black). - This is red again. + This text is red and large. + This text is in the initial color (typically black) and initial size + (typically 16px). + This is red and large again.

``` #### CSS +We set `color` and `font-size` on the `

` element, then set those properties to `initial` on the {{htmlelement("em")}} element to reset them. + ```css p { color: red; + font-size: 2rem; } em { color: initial; + font-size: initial; } ``` @@ -40,7 +49,7 @@ em { {{EmbedLiveSample('Using_initial_to_reset_color_for_an_element')}} -With the `initial` keyword in this example, `color` value on the `em` element is restored to the initial value of [`color`](/en-US/docs/Web/CSS/Reference/Properties/color#formal_definition), as defined in the specification. +With the `initial` keyword in this example, the `color` and `font-size` values on the `em` element are restored to the initial values for [`color`](/en-US/docs/Web/CSS/Reference/Properties/color#formal_definition) and [`font-size`](/en-US/docs/Web/CSS/Reference/Properties/font-size#formal_definition), respectively. ## Specifications @@ -52,8 +61,6 @@ With the `initial` keyword in this example, `color` value on the `em` element is ## See also -- Use the {{cssxref("inherit")}} keyword to make an element's property the same as its parent. -- Use the {{cssxref("revert")}} keyword to reset a property to the value established by the user-agent stylesheet (or by user styles, if any exist). -- Use the {{cssxref("revert-layer")}} keyword to reset a property to the value established in a previous cascade layer. -- Use the {{cssxref("unset")}} keyword to set a property to its inherited value if it inherits or to its initial value if not. -- The {{cssxref("all")}} property lets you reset all properties to their initial, inherited, reverted, or unset state at once. +- {{cssxref("inherit")}}, {{cssxref("revert")}}, {{cssxref("revert-layer")}}, and {{cssxref("unset")}} keywords +- {{cssxref("all")}} +- [Inheritance](/en-US/docs/Web/CSS/Guides/Cascade/Inheritance) diff --git a/package-lock.json b/package-lock.json index a28bc33fac188a2..ddd02c8cb6f2739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "cspell-group-by-file-reporter": "^1.0.1", "env-cmd": "11.0.0", "fdir": "^6.5.0", - "file-type": "^21.3.0", + "file-type": "^21.3.1", "fs-extra": "^11.3.4", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", @@ -31,7 +31,7 @@ "imagemin-pngquant": "^10.0.0", "imagemin-svgo": "^12.0.0", "is-svg": "^6.1.0", - "lefthook": "^2.1.2", + "lefthook": "^2.1.3", "markdownlint-cli2": "0.21.0", "markdownlint-rule-search-replace": "1.2.0", "node-html-parser": "^7.1.0", @@ -4358,9 +4358,9 @@ } }, "node_modules/file-type": { - "version": "21.3.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", - "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.1.tgz", + "integrity": "sha512-SrzXX46I/zsRDjTb82eucsGg0ODq2NpGDp4HcsFKApPy8P8vACjpJRDoGGMfEzhFC0ry61ajd7f72J3603anBA==", "dev": true, "license": "MIT", "dependencies": { @@ -6303,9 +6303,9 @@ } }, "node_modules/lefthook": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-2.1.2.tgz", - "integrity": "sha512-HdAMl4g47kbWSkrUkCx3Kucq54omFS6piMJtXwXNtmCAfB40UaybTJuYtFW4hNzZ5SvaEimtxTp7P/MNIkEfsA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-2.1.3.tgz", + "integrity": "sha512-2W8PP/EGCvyS/x+Xza0Lgvn/EM3FKnr6m6xkfzpl6RKHl8TwPvs9iYZFQL99CnWTTvO+1mtQvIxGE/bD05038Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6313,22 +6313,22 @@ "lefthook": "bin/index.js" }, "optionalDependencies": { - "lefthook-darwin-arm64": "2.1.2", - "lefthook-darwin-x64": "2.1.2", - "lefthook-freebsd-arm64": "2.1.2", - "lefthook-freebsd-x64": "2.1.2", - "lefthook-linux-arm64": "2.1.2", - "lefthook-linux-x64": "2.1.2", - "lefthook-openbsd-arm64": "2.1.2", - "lefthook-openbsd-x64": "2.1.2", - "lefthook-windows-arm64": "2.1.2", - "lefthook-windows-x64": "2.1.2" + "lefthook-darwin-arm64": "2.1.3", + "lefthook-darwin-x64": "2.1.3", + "lefthook-freebsd-arm64": "2.1.3", + "lefthook-freebsd-x64": "2.1.3", + "lefthook-linux-arm64": "2.1.3", + "lefthook-linux-x64": "2.1.3", + "lefthook-openbsd-arm64": "2.1.3", + "lefthook-openbsd-x64": "2.1.3", + "lefthook-windows-arm64": "2.1.3", + "lefthook-windows-x64": "2.1.3" } }, "node_modules/lefthook-darwin-arm64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-2.1.2.tgz", - "integrity": "sha512-AgHu93YuJtj1l9bcKlCbo4Tg8N8xFl9iD6BjXCGaGMu46LSjFiXbJFlkUdpgrL8fIbwoCjJi5FNp3POpqs4Wdw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-2.1.3.tgz", + "integrity": "sha512-VMSQK5ZUh66mKrEpHt5U81BxOg5xAXLoLZIK6e++4uc28tj8zGBqV9+tZqSRElXXzlnHbfdDVCMaKlTuqUy0Rg==", "cpu": [ "arm64" ], @@ -6340,9 +6340,9 @@ ] }, "node_modules/lefthook-darwin-x64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-2.1.2.tgz", - "integrity": "sha512-exooc9Ectz13OLJJOXM9AzaFQbqzf9QCF8JuVvGfbr4RYABYK+BwwtydjlPQrA76/n/h4tsS11MH5bBULnLkYA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-2.1.3.tgz", + "integrity": "sha512-4QhepF4cf+fa7sDow29IEuCfm/6LuV+oVyQGpnr5it1DEZIEEoa6vdH/x4tutYhAg/HH7I2jHq6FGz96HRiJEQ==", "cpu": [ "x64" ], @@ -6354,9 +6354,9 @@ ] }, "node_modules/lefthook-freebsd-arm64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-2.1.2.tgz", - "integrity": "sha512-E1QMlJPEU21n9eewv6ePfh+JmoTSg5R1jaYcKCky10kfbMdohNucI3xV91F2LcerE+p3UejKDqr/1wWO2RMGeQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-2.1.3.tgz", + "integrity": "sha512-kysx/9pjifOgcTZOj1bR0i74FAbMv3BDfrpZDKniBOo4Dp0hXhyOtUmRn4nWKL0bN+cqc4ZePAq4Qdm4fxWafA==", "cpu": [ "arm64" ], @@ -6368,9 +6368,9 @@ ] }, "node_modules/lefthook-freebsd-x64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-2.1.2.tgz", - "integrity": "sha512-/5zp+x8055Thj46x9S7hgnneZxvWhHQvPWkkgISCab1Lh6eLrbxvhE1qTb1lU3DqTnNmH9NeXdq1xPHc9uGluA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-2.1.3.tgz", + "integrity": "sha512-TLuPHQNg6iihShchrh5DrHvoCZO8FajZBMAEwLIKWlm6bkCcXbYNxy4dBaVK8lzHtS/Kv1bnH0D3BcK65iZFVQ==", "cpu": [ "x64" ], @@ -6382,9 +6382,9 @@ ] }, "node_modules/lefthook-linux-arm64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-2.1.2.tgz", - "integrity": "sha512-UK5FvDTkwKO7tOznY8iEZzuTsM1jXMZAG5BMRs7olN1k1K6m2unR6oKABP0hCd0wDErK6DZKDJDJfB564Rzqtw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-2.1.3.tgz", + "integrity": "sha512-e5x4pq1aZAXc0C642V4HaUoKtcHVmGW1HBIDNfWUhtsThBKjhZBXPspecaAHIRA/8VtsXS3RnJ4VhQpgfrCbww==", "cpu": [ "arm64" ], @@ -6396,9 +6396,9 @@ ] }, "node_modules/lefthook-linux-x64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-2.1.2.tgz", - "integrity": "sha512-4eOtz4PNh8GbJ+nA8YVDfW/eMirQWdZqMP/V/MVtoVBGobf6oXvvuDOySvAPOgNYEFN0Boegytmuji/851Vstg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-2.1.3.tgz", + "integrity": "sha512-yeVAiV5hoE6Qq8dQDB4XC14x4N9mhn+FetxzqDu5LVci0/sOPqyPq2b0YUtNwJ1ZUKawTz4I/oqnUsHkQrGH0w==", "cpu": [ "x64" ], @@ -6410,9 +6410,9 @@ ] }, "node_modules/lefthook-openbsd-arm64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-2.1.2.tgz", - "integrity": "sha512-lJXRJ6iJIBKwomuNBA3CUNSclj2/rKuxGAQoUra214B92VB6jL9zaY5YEs6h/ie9jQrzSnllEeg7xyDIsuVCrQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-2.1.3.tgz", + "integrity": "sha512-8QVvRxIosV6NL2XrbifOPGVhMFE43h02BUNEHYhZhyad7BredfAakg9dA9J/NO0I3eMdvCYU50ubFyDGIqUJog==", "cpu": [ "arm64" ], @@ -6424,9 +6424,9 @@ ] }, "node_modules/lefthook-openbsd-x64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-2.1.2.tgz", - "integrity": "sha512-GyOje4W0DIqkmR7/Of5D+mZ0vWqMvtGAVedtJR6d1239xNeMzCS8Q+/a3O1xigceZa5xhlqq0BWlssB/QYPQnA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-2.1.3.tgz", + "integrity": "sha512-YTS9qeW9PzzKg9Rk55mQprLIl1OdAIIjeOH8DF+MPWoAPkRqeUyq8Q2Bdlf3+Swy+kJOjoiU1pKvpjjc8upv9Q==", "cpu": [ "x64" ], @@ -6438,9 +6438,9 @@ ] }, "node_modules/lefthook-windows-arm64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-2.1.2.tgz", - "integrity": "sha512-MZKMqTULEpX/8N3fKXAR0A9RjsGKkEEY0japLqrHOIpxsJXry1DRz0FvQo2kkY4WW3rtFegV9m6eesOymuDrUg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-2.1.3.tgz", + "integrity": "sha512-Nlp80pWyF67GmxgM5NQmL7JTTccbJAvCNtS5QwHmKq3pJ9Xi0UegP9pGME520n06Rhp+gX7H4boXhm2D5hAghg==", "cpu": [ "arm64" ], @@ -6452,9 +6452,9 @@ ] }, "node_modules/lefthook-windows-x64": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-2.1.2.tgz", - "integrity": "sha512-NZUgObuaSxc0EXAwC/CzkMf7TuQc++GGIk6TLPdaUpoSsNSJSZEwBVz5DtFB1cG+eMkfO/wOKplls+yjimTTtQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-2.1.3.tgz", + "integrity": "sha512-KByBhvqgUNhjO/03Mr0y66D9B1ZnII7AB0x17cumwHMOYoDaPJh/AlgmEduqUpatqli3lnFzWD0DUkAY6pq/SA==", "cpu": [ "x64" ], @@ -9378,9 +9378,9 @@ } }, "node_modules/tar": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", - "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.10.tgz", + "integrity": "sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { diff --git a/package.json b/package.json index 620eb64db18b35a..669b6960cba2bf0 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "cspell-group-by-file-reporter": "^1.0.1", "env-cmd": "11.0.0", "fdir": "^6.5.0", - "file-type": "^21.3.0", + "file-type": "^21.3.1", "fs-extra": "^11.3.4", "gray-matter": "^4.0.3", "imagemin": "^9.0.1", @@ -65,7 +65,7 @@ "imagemin-pngquant": "^10.0.0", "imagemin-svgo": "^12.0.0", "is-svg": "^6.1.0", - "lefthook": "^2.1.2", + "lefthook": "^2.1.3", "markdownlint-cli2": "0.21.0", "markdownlint-rule-search-replace": "1.2.0", "node-html-parser": "^7.1.0",