From 197ffc94f46780b40a8105a624f51be4badda028 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 21 Jul 2023 07:55:52 -0400 Subject: [PATCH 1/2] Use abbreviation DOM --- aspnetcore/blazor/components/data-binding.md | 8 ++++---- aspnetcore/blazor/components/event-handling.md | 8 ++++---- aspnetcore/blazor/components/index.md | 2 +- aspnetcore/blazor/components/lifecycle.md | 8 ++++---- aspnetcore/blazor/fundamentals/index.md | 9 +++++++++ aspnetcore/blazor/fundamentals/routing.md | 2 +- aspnetcore/blazor/hosting-models.md | 2 +- .../blazor/includes/js-interop/circuit-disconnection.md | 2 +- aspnetcore/blazor/includes/prerendering.md | 4 ++-- aspnetcore/blazor/index.md | 6 +++--- .../call-dotnet-from-javascript.md | 6 +++--- .../call-javascript-from-dotnet.md | 8 ++++---- aspnetcore/blazor/javascript-interoperability/index.md | 8 ++++---- aspnetcore/blazor/security/server/threat-mitigation.md | 2 +- aspnetcore/mvc/views/tag-helpers/intro.md | 2 +- aspnetcore/tutorials/choose-web-ui.md | 2 +- 16 files changed, 44 insertions(+), 35 deletions(-) diff --git a/aspnetcore/blazor/components/data-binding.md b/aspnetcore/blazor/components/data-binding.md index 93b923771428..72c7a823a925 100644 --- a/aspnetcore/blazor/components/data-binding.md +++ b/aspnetcore/blazor/components/data-binding.md @@ -1,7 +1,7 @@ --- title: ASP.NET Core Blazor data binding author: guardrex -description: Learn about data binding features for Razor components and Document Object Model (DOM) elements in Blazor apps. +description: Learn about data binding features for Razor components and DOM elements in Blazor apps. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc @@ -12,7 +12,7 @@ uid: blazor/components/data-binding [!INCLUDE[](~/includes/not-latest-version.md)] -This article explains data binding features for Razor components and Document Object Model (DOM) elements in Blazor apps. +This article explains data binding features for Razor components and DOM elements in Blazor apps. Razor components provide data binding features with the [`@bind`](xref:mvc/views/razor#bind) Razor directive attribute with a field, property, or Razor expression value. @@ -81,7 +81,7 @@ As a demonstration of how data binding composes in HTML, the following example b When the `BindTheory` component is rendered, the `value` of the HTML demonstration `` element comes from the `InputValue` property. When the user enters a value in the text box and changes element focus, the `onchange` event is fired and the `InputValue` property is set to the changed value. In reality, code execution is more complex because [`@bind`](xref:mvc/views/razor#bind) handles cases where type conversions are performed. In general, [`@bind`](xref:mvc/views/razor#bind) associates the current value of an expression with the `value` attribute of the `` and handles changes using the registered handler. -Bind a property or field on other [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) events by including an `@bind:event="{EVENT}"` attribute with a DOM event for the `{EVENT}` placeholder. The following example binds the `InputValue` property to the `` element's value when the element's `oninput` event ([`input`](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event)) is triggered. Unlike the `onchange` event ([`change`](https://developer.mozilla.org/docs/Web/API/HTMLElement/change_event)), which fires when the element loses focus, `oninput` ([`input`](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event)) fires when the value of the text box changes. +Bind a property or field on other DOM events by including an `@bind:event="{EVENT}"` attribute with a DOM event for the `{EVENT}` placeholder. The following example binds the `InputValue` property to the `` element's value when the element's `oninput` event ([`input`](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event)) is triggered. Unlike the `onchange` event ([`change`](https://developer.mozilla.org/docs/Web/API/HTMLElement/change_event)), which fires when the element loses focus, `oninput` ([`input`](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event)) fires when the value of the text box changes. `Page/BindEvent.razor`: @@ -267,7 +267,7 @@ Two-way data binding isn't possible to implement with an event handler. Use `@bi The `OnInput` event handler updates the value of `inputValue` to `Long!` after a fourth character is provided. However, the user can continue adding characters to the element value in the UI. The value of `inputValue` isn't bound back to the element's value with each keystroke. The preceding example is only capable of one-way data binding. -The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core 7.0 or later, `@bind:get`/`@bind:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates. +The reason for this behavior is that Blazor isn't aware that your code intends to modify the value of `inputValue` in the event handler. Blazor doesn't try to force DOM element values and .NET variable values to match unless they're bound with `@bind` syntax. In earlier versions of Blazor, two-way data binding is implemented by [binding the element to a property and controlling the property's value with its setter](#binding-to-a-property-with-c-get-and-set-accessors). In ASP.NET Core 7.0 or later, `@bind:get`/`@bind:set` modifier syntax is used to implement two-way data binding, as the next example demonstrates. Consider the following ***correct approach*** using `@bind:get`/`@bind:set` for two-way data binding: diff --git a/aspnetcore/blazor/components/event-handling.md b/aspnetcore/blazor/components/event-handling.md index 5a90728e1a7d..d83fa804edc9 100644 --- a/aspnetcore/blazor/components/event-handling.md +++ b/aspnetcore/blazor/components/event-handling.md @@ -16,7 +16,7 @@ This article explains Blazor's event handling features, including event argument Specify delegate event handlers in Razor component markup with [`@on{DOM EVENT}="{DELEGATE}"`](xref:mvc/views/razor#onevent) Razor syntax: -* The `{DOM EVENT}` placeholder is a [Document Object Model (DOM) event](https://developer.mozilla.org/docs/Web/Events) (for example, `click`). +* The `{DOM EVENT}` placeholder is a [DOM event](https://developer.mozilla.org/docs/Web/Events) (for example, `click`). * The `{DELEGATE}` placeholder is the C# delegate event handler. For event handling: @@ -119,7 +119,7 @@ For events that support an event argument type, specifying an event parameter in Supported are shown in the following table. -| Event | Class | [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) notes | +| Event | Class | DOM notes | | ---------------- | ------ | --- | | Clipboard | | | | Drag | | and hold dragged item data.

Implement drag and drop in Blazor apps using [JS interop](xref:blazor/js-interop/call-javascript-from-dotnet) with [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). | @@ -493,7 +493,7 @@ Prefer the strongly typed ` element, the counter increments with the key sequence Shift++. The `+` character isn't assigned to the `` element's value. For more information on `keydown`, see [`MDN Web Docs: Document: keydown` event](https://developer.mozilla.org/docs/Web/API/Document/keydown_event). @@ -539,7 +539,7 @@ An expression is also a permitted value of the attribute. In the following examp ## Stop event propagation -Use the [`@on{DOM EVENT}:stopPropagation`](xref:mvc/views/razor#oneventstoppropagation) directive attribute to stop event propagation within the Blazor scope. `{DOM EVENT}` is a placeholder for a [Document Object Model (DOM) event](https://developer.mozilla.org/docs/Web/Events). +Use the [`@on{DOM EVENT}:stopPropagation`](xref:mvc/views/razor#oneventstoppropagation) directive attribute to stop event propagation within the Blazor scope. `{DOM EVENT}` is a placeholder for a [DOM event](https://developer.mozilla.org/docs/Web/Events). The `stopPropagation` directive attribute's effect is limited to the Blazor scope and doesn't extend to the HTML DOM. Events must propagate to the HTML DOM root before Blazor can act upon them. For a mechanism to prevent HTML DOM event propagation, consider the following approach: diff --git a/aspnetcore/blazor/components/index.md b/aspnetcore/blazor/components/index.md index 8773ef2c401a..a8e0cc196cfb 100644 --- a/aspnetcore/blazor/components/index.md +++ b/aspnetcore/blazor/components/index.md @@ -374,7 +374,7 @@ Component members are used in rendering logic using C# expressions that start wi > [!NOTE] > Examples throughout the Blazor documentation specify the [`private` access modifier](/dotnet/csharp/language-reference/keywords/private) for private members. Private members are scoped to a component's class. However, C# assumes the `private` access modifier when no access modifier is present, so explicitly marking members "`private`" in your own code is optional. For more information on access modifiers, see [Access Modifiers (C# Programming Guide)](/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers). -The Blazor framework processes a component internally as a [*render tree*](https://developer.mozilla.org/docs/Web/Performance/How_browsers_work#render), which is the combination of a component's [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) and [Cascading Style Sheet Object Model (CSSOM)](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model). After the component is initially rendered, the component's render tree is regenerated in response to events. Blazor compares the new render tree against the previous render tree and applies any modifications to the browser's DOM for display. For more information, see . +The Blazor framework processes a component internally as a [*render tree*](https://developer.mozilla.org/docs/Web/Performance/How_browsers_work#render), which is the combination of a component's DOM and [Cascading Style Sheet Object Model (CSSOM)](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model). After the component is initially rendered, the component's render tree is regenerated in response to events. Blazor compares the new render tree against the previous render tree and applies any modifications to the browser's DOM for display. For more information, see . Razor syntax for C# control structures, directives, and directive attributes are lowercase (examples: [`@if`](xref:mvc/views/razor#conditionals-if-else-if-else-and-switch), [`@code`](xref:mvc/views/razor#code), [`@bind`](xref:mvc/views/razor#bind)). Property names are uppercase (example: `@Body` for ). diff --git a/aspnetcore/blazor/components/lifecycle.md b/aspnetcore/blazor/components/lifecycle.md index 58a810c4dd0b..ca02a9932b95 100644 --- a/aspnetcore/blazor/components/lifecycle.md +++ b/aspnetcore/blazor/components/lifecycle.md @@ -40,13 +40,13 @@ A parent component renders before its children components because rendering is w ![Component lifecycle events of a Razor component in Blazor](~/blazor/components/lifecycle/_static/lifecycle1.png) -Document Object Model (DOM) event processing: +DOM event processing: 1. The event handler is run. 1. If an incomplete is returned, the is awaited and then the component is rerendered. 1. Render for all synchronous work and complete s. -![Document Object Model (DOM) event processing](~/blazor/components/lifecycle/_static/lifecycle2.png) +![DOM event processing](~/blazor/components/lifecycle/_static/lifecycle2.png) The `Render` lifecycle: @@ -394,9 +394,9 @@ JS interop object references are implemented as a map keyed by an identifier on At a minimum, always dispose objects created on the .NET side to avoid leaking .NET managed memory. -### Document Object Model (DOM) cleanup tasks during component disposal +### DOM cleanup tasks during component disposal -For more information, see . +For more information, see . For guidance on in Blazor Server apps when a circuit is disconnected, see . For general JavaScript interop error handling guidance, see the *JavaScript interop* section in . diff --git a/aspnetcore/blazor/fundamentals/index.md b/aspnetcore/blazor/fundamentals/index.md index b198909912a2..2bfbe9222542 100644 --- a/aspnetcore/blazor/fundamentals/index.md +++ b/aspnetcore/blazor/fundamentals/index.md @@ -66,6 +66,15 @@ The preceding `Counter` component: * Renders the current count with `@currentCount`. `currentCount` is an integer variable defined in the C# code of the `@code` block. * Displays a button to trigger the `IncrementCount` method, which is also found in the `@code` block and increases the value of the `currentCount` variable. +## Document Object Model (DOM) + +In Blazor documentation, references to the *Document Object Model* use the abbreviation *DOM*. + +For more information, see the following resources: + +* [Introduction to the DOM (MDN documentation)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) +* [Level 1 Document Object Model Specification (W3C)](https://www.w3.org/TR/WD-DOM/) + ## Sample apps Documentation sample apps are available for inspection and download: diff --git a/aspnetcore/blazor/fundamentals/routing.md b/aspnetcore/blazor/fundamentals/routing.md index 963b25b4630f..a8354024a274 100644 --- a/aspnetcore/blazor/fundamentals/routing.md +++ b/aspnetcore/blazor/fundamentals/routing.md @@ -1210,7 +1210,7 @@ Handlers are only executed for internal navigation within the app. If the user s Implement and dispose registered handlers to unregister them. For more information, see . > [!IMPORTANT] -> Don't attempt to execute Document Object Model (DOM) cleanup tasks via JavaScript (JS) interop when handling location changes. Use the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver) pattern in JS on the client. For more information, see . +> Don't attempt to execute DOM cleanup tasks via JavaScript (JS) interop when handling location changes. Use the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver) pattern in JS on the client. For more information, see . In the following example, a location changing handler is registered for navigation events. diff --git a/aspnetcore/blazor/hosting-models.md b/aspnetcore/blazor/hosting-models.md index e0670064dafd..acb83e7101dc 100644 --- a/aspnetcore/blazor/hosting-models.md +++ b/aspnetcore/blazor/hosting-models.md @@ -123,7 +123,7 @@ Blazor WebAssembly includes support for trimming unused code from .NET Core fram Blazor can also be used to build native client apps using a hybrid approach. Hybrid apps are native apps that leverage web technologies for their functionality. In a Blazor Hybrid app, Razor components run directly in the native app (not on WebAssembly) along with any other .NET code and render web UI based on HTML and CSS to an embedded Web View control through a local interop channel. -![Hybrid apps with .NET and Blazor render UI in a Web View control, where the HTML Document Object Model (DOM) interacts with Blazor and .NET of the native desktop or mobile app.](~/blazor/hosting-models/_static/hybrid-apps-1.png) +![Hybrid apps with .NET and Blazor render UI in a Web View control, where the HTML DOM interacts with Blazor and .NET of the native desktop or mobile app.](~/blazor/hosting-models/_static/hybrid-apps-1.png) Blazor Hybrid apps can be built using different .NET native app frameworks, including .NET MAUI, WPF, and Windows Forms. Blazor provides `BlazorWebView` controls for adding Razor components to apps built with these frameworks. Using Blazor with .NET MAUI offers a convenient way to build cross-platform Blazor Hybrid apps for mobile and desktop, while Blazor integration with WPF and Windows Forms can be a great way to modernize existing apps. diff --git a/aspnetcore/blazor/includes/js-interop/circuit-disconnection.md b/aspnetcore/blazor/includes/js-interop/circuit-disconnection.md index 92e335151edc..735c86dc09a8 100644 --- a/aspnetcore/blazor/includes/js-interop/circuit-disconnection.md +++ b/aspnetcore/blazor/includes/js-interop/circuit-disconnection.md @@ -37,6 +37,6 @@ If you must clean up your own JS objects or execute other JS code on the client For more information, see the following articles: -* : Includes a code example of the `MutationObserver` pattern. +* : Includes a code example of the `MutationObserver` pattern. * : The *JavaScript interop* section discusses error handling in JS interop scenarios. * : The *Component disposal with `IDisposable` and `IAsyncDisposable`* section describes how to implement disposal patterns in Razor components. diff --git a/aspnetcore/blazor/includes/prerendering.md b/aspnetcore/blazor/includes/prerendering.md index 8687ef2f7242..786cd617ffa1 100644 --- a/aspnetcore/blazor/includes/prerendering.md +++ b/aspnetcore/blazor/includes/prerendering.md @@ -14,7 +14,7 @@ For the following example, the `setElementText1` function is placed inside the ` ``` > [!WARNING] -> **The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . +> **The preceding example modifies the DOM directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . The [`OnAfterRender{Async}` lifecycle event](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync) isn't called during the prerendering process on the server. Override the `OnAfterRender{Async}` method to delay JS interop calls until after the component is rendered and interactive on the client after prerendering. @@ -48,7 +48,7 @@ For the following example, the `setElementText2` function is placed inside the ` ``` > [!WARNING] -> **The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . +> **The preceding example modifies the DOM directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . Where is called, the is only used in and not in any earlier lifecycle method because there's no JS element until after the component is rendered. diff --git a/aspnetcore/blazor/index.md b/aspnetcore/blazor/index.md index 4e5a7275d603..2701934e1bc8 100644 --- a/aspnetcore/blazor/index.md +++ b/aspnetcore/blazor/index.md @@ -107,7 +107,7 @@ The dialog is rendered when the `Index` component is accessed in a browser. When ![Dialog component rendered in the browser nested inside of the Index component. The browser developer tools console shows the message written by C# code when the user selects the Yes! button in the UI.](~/blazor/index/_static/dialog.png) -Components render into an in-memory representation of the browser's [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) called a *render tree*, which is used to update the UI in a flexible and efficient way. +Components render into an in-memory representation of the browser's DOM called a *render tree*, which is used to update the UI in a flexible and efficient way. ## Blazor Server @@ -127,7 +127,7 @@ Blazor Server apps render content differently than traditional models for render When a Razor Page or view is rendered, every line of Razor code emits HTML in text form. After rendering, the server disposes of the page or view instance, including any state that was produced. When another request for the page occurs, the entire page is rerendered to HTML again and sent to the client. -Blazor Server produces a graph of components to display similar to an HTML or XML [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction). The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering the content on the server makes the app feel more responsive on the client. +Blazor Server produces a graph of components to display similar to an HTML or XML DOM. The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering the content on the server makes the app feel more responsive on the client. After the components are interactive on the client, UI updates are triggered by user interaction and app events. When an update occurs, the component graph is rerendered, and a UI *diff* (difference) is calculated. This diff is the smallest set of DOM edits required to update the UI on the client. The diff is sent to the client in a binary format and applied by the browser. @@ -147,7 +147,7 @@ When a Blazor WebAssembly app is built and run: * C# code files and Razor files are compiled into .NET assemblies. * The assemblies and the [.NET runtime](/dotnet/framework/get-started/overview) are downloaded to the browser. -* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) manipulation and browser API calls. +* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle DOM manipulation and browser API calls. The size of the published app, its *payload size*, is a critical performance factor for an app's usability. A large app takes a relatively long time to download to a browser, which diminishes the user experience. Blazor WebAssembly optimizes payload size to reduce download times: diff --git a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md index 48bdd6aeffda..63bf00bd8d33 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md +++ b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md @@ -1338,9 +1338,9 @@ JS interop object references are implemented as a map keyed by an identifier on At a minimum, always dispose objects created on the .NET side to avoid leaking .NET managed memory. -## Document Object Model (DOM) cleanup tasks during component disposal +## DOM cleanup tasks during component disposal -For more information, see . +For more information, see . ## JavaScript interop calls without a circuit @@ -1350,7 +1350,7 @@ For more information, see * [`InteropComponent.razor` example (dotnet/AspNetCore GitHub repository `main` branch)](https://github.com/dotnet/AspNetCore/blob/main/src/Components/test/testassets/BasicTestApp/InteropComponent.razor): The `main` branch represents the product unit's current development for the next release of ASP.NET Core. To select the branch for a different release (for example, `release/5.0`), use the **Switch branches or tags** dropdown list to select the branch. -* [Interaction with the Document Object Model (DOM)](xref:blazor/js-interop/index#interaction-with-the-document-object-model-dom) +* [Interaction with the DOM](xref:blazor/js-interop/index#interaction-with-the-dom) * [Blazor samples GitHub repository (`dotnet/blazor-samples`)](https://github.com/dotnet/blazor-samples) * (*JavaScript interop* section) * [Blazor Server threat mitigation: .NET methods invoked from the browser](xref:blazor/security/server/threat-mitigation#net-methods-invoked-from-the-browser) diff --git a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md index ca36031e2f19..52d7cda1fa9c 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md +++ b/aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md @@ -459,7 +459,7 @@ The following example shows capturing a reference to the `username` `` el ``` > [!WARNING] -> Only use an element reference to mutate the contents of an empty element that doesn't interact with Blazor. This scenario is useful when a third-party API supplies content to the element. Because Blazor doesn't interact with the element, there's no possibility of a conflict between Blazor's representation of the element and the Document Object Model (DOM). +> Only use an element reference to mutate the contents of an empty element that doesn't interact with Blazor. This scenario is useful when a third-party API supplies content to the element. Because Blazor doesn't interact with the element, there's no possibility of a conflict between Blazor's representation of the element and the DOM. > > In the following example, it's *dangerous* to mutate the contents of the unordered list (`ul`) using `MyList` via JS interop because Blazor interacts with the DOM to populate this element's list items (`
  • `) from the `Todos` object: > @@ -810,7 +810,7 @@ Objects that contain circular references can't be serialized on the client for e ## JavaScript libraries that render UI -Sometimes you may wish to use JavaScript (JS) libraries that produce visible user interface elements within the browser Document Object Model (DOM). At first glance, this might seem difficult because Blazor's diffing system relies on having control over the tree of DOM elements and runs into errors if some external code mutates the DOM tree and invalidates its mechanism for applying diffs. This isn't a Blazor-specific limitation. The same challenge occurs with any diff-based UI framework. +Sometimes you may wish to use JavaScript (JS) libraries that produce visible user interface elements within the browser DOM. At first glance, this might seem difficult because Blazor's diffing system relies on having control over the tree of DOM elements and runs into errors if some external code mutates the DOM tree and invalidates its mechanism for applying diffs. This isn't a Blazor-specific limitation. The same challenge occurs with any diff-based UI framework. Fortunately, it's straightforward to embed externally-generated UI within a Razor component UI reliably. The recommended technique is to have the component's code (`.razor` file) produce an empty element. As far as Blazor's diffing system is concerned, the element is always empty, so the renderer does not recurse into the element and instead leaves its contents alone. This makes it safe to populate the element with arbitrary externally-managed content. @@ -1268,9 +1268,9 @@ JS interop object references are implemented as a map keyed by an identifier on At a minimum, always dispose objects created on the .NET side to avoid leaking .NET managed memory. -## Document Object Model (DOM) cleanup tasks during component disposal +## DOM cleanup tasks during component disposal -For more information, see . +For more information, see . ## JavaScript interop calls without a circuit diff --git a/aspnetcore/blazor/javascript-interoperability/index.md b/aspnetcore/blazor/javascript-interoperability/index.md index 06ab69987f62..89aad923f1fd 100644 --- a/aspnetcore/blazor/javascript-interoperability/index.md +++ b/aspnetcore/blazor/javascript-interoperability/index.md @@ -42,9 +42,9 @@ Additional resources for writing JS interop scripts in TypeScript: * [Tutorial: Create an ASP.NET Core app with TypeScript in Visual Studio](/visualstudio/javascript/tutorial-aspnet-with-typescript) * [Manage npm packages in Visual Studio](/visualstudio/javascript/npm-package-management) -## Interaction with the Document Object Model (DOM) +## Interaction with the DOM -Only mutate the Document Object Model (DOM) with JavaScript (JS) when the object doesn't interact with Blazor. Blazor maintains representations of the DOM and interacts directly with DOM objects. If an element rendered by Blazor is modified externally using JS directly or via JS Interop, the DOM may no longer match Blazor's internal representation, which can result in undefined behavior. Undefined behavior may merely interfere with the presentation of elements or their functions but may also introduce security risks to the app or server. +Only mutate the DOM with JavaScript (JS) when the object doesn't interact with Blazor. Blazor maintains representations of the DOM and interacts directly with DOM objects. If an element rendered by Blazor is modified externally using JS directly or via JS Interop, the DOM may no longer match Blazor's internal representation, which can result in undefined behavior. Undefined behavior may merely interfere with the presentation of elements or their functions but may also introduce security risks to the app or server. This guidance not only applies to your own JS interop code but also to any JS libraries that the app uses, including anything provided by a third-party framework, such as [Bootstrap JS](https://getbootstrap.com/) and [jQuery](https://jquery.com/). @@ -100,9 +100,9 @@ Blazor supports unmarshalled JS interop when a high volume of .NET objects are r :::moniker-end -## Document Object Model (DOM) cleanup tasks during component disposal +## DOM cleanup tasks during component disposal -Don't execute JS interop code for [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) cleanup tasks during component disposal. Instead, use the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver) pattern in JavaScript (JS) on the client for the following reasons: +Don't execute JS interop code for DOM cleanup tasks during component disposal. Instead, use the [`MutationObserver`](https://developer.mozilla.org/docs/Web/API/MutationObserver) pattern in JavaScript (JS) on the client for the following reasons: * The component may have been removed from the DOM by the time your cleanup code executes in `Dispose{Async}`. * In a Blazor Server app, the Blazor renderer may have been disposed by the framework by the time your cleanup code executes in `Dispose{Async}`. diff --git a/aspnetcore/blazor/security/server/threat-mitigation.md b/aspnetcore/blazor/security/server/threat-mitigation.md index db6d81df0615..8c5a2a7e5b8b 100644 --- a/aspnetcore/blazor/security/server/threat-mitigation.md +++ b/aspnetcore/blazor/security/server/threat-mitigation.md @@ -171,7 +171,7 @@ Don't trust calls from JavaScript to .NET methods. When a .NET method is exposed * Take into account that static and instance methods can be exposed to JavaScript clients. Avoid sharing state across sessions unless the design calls for sharing state with appropriate constraints. * For instance methods exposed through objects that are originally created through dependency injection (DI), the objects should be registered as scoped objects. This applies to any DI service that the Blazor Server app uses. * For static methods, avoid establishing state that can't be scoped to the client unless the app is explicitly sharing state by-design across all users on a server instance. - * Avoid passing user-supplied data in parameters to JavaScript calls. If passing data in parameters is absolutely required, ensure that the JavaScript code handles passing the data without introducing [Cross-site scripting (XSS)](#cross-site-scripting-xss) vulnerabilities. For example, don't write user-supplied data to the Document Object Model (DOM) by setting the `innerHTML` property of an element. Consider using [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP) to disable `eval` and other unsafe JavaScript primitives. For more information, see . + * Avoid passing user-supplied data in parameters to JavaScript calls. If passing data in parameters is absolutely required, ensure that the JavaScript code handles passing the data without introducing [Cross-site scripting (XSS)](#cross-site-scripting-xss) vulnerabilities. For example, don't write user-supplied data to the DOM by setting the `innerHTML` property of an element. Consider using [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP) to disable `eval` and other unsafe JavaScript primitives. For more information, see . * Avoid implementing custom dispatching of .NET invocations on top of the framework's dispatching implementation. Exposing .NET methods to the browser is an advanced scenario, not recommended for general Blazor development. ### Events diff --git a/aspnetcore/mvc/views/tag-helpers/intro.md b/aspnetcore/mvc/views/tag-helpers/intro.md index 0cf3b3314f8f..8c147caea934 100644 --- a/aspnetcore/mvc/views/tag-helpers/intro.md +++ b/aspnetcore/mvc/views/tag-helpers/intro.md @@ -275,7 +275,7 @@ The Visual Studio editor helps you write **all** of the markup in the Tag Helper * ASP.NET Web Server Controls have a non-trivial lifecycle that can make developing and debugging difficult. -* Web Server controls allow you to add functionality to the client Document Object Model (DOM) elements by using a client control. Tag Helpers have no DOM. +* Web Server controls allow you to add functionality to the client DOM elements by using a client control. Tag Helpers have no DOM. * Web Server controls include automatic browser detection. Tag Helpers have no knowledge of the browser. diff --git a/aspnetcore/tutorials/choose-web-ui.md b/aspnetcore/tutorials/choose-web-ui.md index b8b99acca239..b62331a9ad53 100644 --- a/aspnetcore/tutorials/choose-web-ui.md +++ b/aspnetcore/tutorials/choose-web-ui.md @@ -138,7 +138,7 @@ When a Blazor WebAssembly app is built and run: * C# code files and Razor files are compiled into .NET assemblies. * The assemblies and the [.NET runtime](/dotnet/framework/get-started/overview) are downloaded to the browser. -* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) manipulation and browser API calls. +* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle DOM manipulation and browser API calls. For more information, see and . The server-rendered Blazor hosting model is described in the [Blazor Server](#blazor-server) section earlier in this article. From d13fc7a471b8f53be98d3cfd13f9257319a9273c Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 21 Jul 2023 08:03:47 -0400 Subject: [PATCH 2/2] Updates --- aspnetcore/blazor/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnetcore/blazor/index.md b/aspnetcore/blazor/index.md index 2701934e1bc8..4e5a7275d603 100644 --- a/aspnetcore/blazor/index.md +++ b/aspnetcore/blazor/index.md @@ -107,7 +107,7 @@ The dialog is rendered when the `Index` component is accessed in a browser. When ![Dialog component rendered in the browser nested inside of the Index component. The browser developer tools console shows the message written by C# code when the user selects the Yes! button in the UI.](~/blazor/index/_static/dialog.png) -Components render into an in-memory representation of the browser's DOM called a *render tree*, which is used to update the UI in a flexible and efficient way. +Components render into an in-memory representation of the browser's [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) called a *render tree*, which is used to update the UI in a flexible and efficient way. ## Blazor Server @@ -127,7 +127,7 @@ Blazor Server apps render content differently than traditional models for render When a Razor Page or view is rendered, every line of Razor code emits HTML in text form. After rendering, the server disposes of the page or view instance, including any state that was produced. When another request for the page occurs, the entire page is rerendered to HTML again and sent to the client. -Blazor Server produces a graph of components to display similar to an HTML or XML DOM. The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering the content on the server makes the app feel more responsive on the client. +Blazor Server produces a graph of components to display similar to an HTML or XML [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction). The component graph includes state held in properties and fields. Blazor evaluates the component graph to produce a binary representation of the markup, which is sent to the client for rendering. After the connection is made between the client and the server, the component's static prerendered elements are replaced with interactive elements. Prerendering the content on the server makes the app feel more responsive on the client. After the components are interactive on the client, UI updates are triggered by user interaction and app events. When an update occurs, the component graph is rerendered, and a UI *diff* (difference) is calculated. This diff is the smallest set of DOM edits required to update the UI on the client. The diff is sent to the client in a binary format and applied by the browser. @@ -147,7 +147,7 @@ When a Blazor WebAssembly app is built and run: * C# code files and Razor files are compiled into .NET assemblies. * The assemblies and the [.NET runtime](/dotnet/framework/get-started/overview) are downloaded to the browser. -* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle DOM manipulation and browser API calls. +* Blazor WebAssembly bootstraps the .NET runtime and configures the runtime to load the assemblies for the app. The Blazor WebAssembly runtime uses JavaScript interop to handle [Document Object Model (DOM)](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) manipulation and browser API calls. The size of the published app, its *payload size*, is a critical performance factor for an app's usability. A large app takes a relatively long time to download to a browser, which diminishes the user experience. Blazor WebAssembly optimizes payload size to reduce download times: