Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add mathml docs #1347

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Typically, the component's `render()` method returns a single `TemplateResult` o
* The sentinel values [`nothing`](/docs/v3/templates/conditionals/#conditionally-rendering-nothing) and [`noChange`](/docs/v3/templates/custom-directives/#signaling-no-change).
* Arrays or iterables of any of the supported types.

This is *almost identical* to the set of values that can be rendered to a Lit [child expression](/docs/v3/templates/expressions/#child-expressions). The one difference is that a child expression can render an `SVGTemplateResult`, returned by the [`svg`](/docs/v3/api/templates/#svg) function. This kind of template result can only be rendered as the descendant of an `<svg>` element.
This is *almost identical* to the set of values that can be rendered to a Lit [child expression](/docs/v3/templates/expressions/#child-expressions). The one difference is that a child expression can render an `SVGTemplateResult` or `MathMLTemplateResult`, returned by the [`svg`](/docs/v3/api/templates/#svg) or [`mathml`](/docs/v3/api/templates/#mathml) functions. These kind of template results can only be rendered as the descendant of `<svg>` or `<math>` elements.

## Writing a good render() method

Expand Down
146 changes: 129 additions & 17 deletions packages/lit-dev-content/site/docs/v3/templates/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ Lit includes a number of built-in directives to help with a variety of rendering
<tr>
<td>

[`unsafeMathML`](#unsafemathml)

</td>
<td>Renders a string as MathML rather than text.</td>
</tr>

<tr>
<td>

[`unsafeSVG`](#unsafesvg)

</td>
Expand Down Expand Up @@ -1436,20 +1445,26 @@ Child expression
</tbody>
</table>

A key feature of Lit's templating syntax is that only strings originating in
template literals are parsed as HTML. Because template literals can only be
authored in trusted script files, this acts as a natural safeguard against XSS
attacks injecting untrusted HTML. However, there may be cases when HTML not
originating in script files needs to be rendered in a Lit template, for example
trusted HTML content fetched from a database. The `unsafeHTML` directive will
parse such a string as HTML and render it in a Lit template.
A key security feature of Lit's templating syntax is that only strings
originating in Lit's tagged template literals are parsed as HTML. Because these
tagged template literals can only be contained in trusted script files, this
acts as a natural safeguard against XSS attacks injecting untrusted HTML. All
other strings strings, including user controlled content, are treated as plain
text and cannot create HTML.

However, there may be cases when HTML text not authored directly in script files
needs to be rendered in a Lit template, for example trusted HTML content fetched
from a database. The `unsafeHTML` directive will parse such a string as HTML and
render it in a Lit template expression.

<div class="alert alert-warning">

Note, the string passed to `unsafeHTML` must be developer-controlled and not
include untrusted content. Examples of untrusted content include query string
parameters and values from user inputs. Untrusted content rendered with this
directive could lead to [cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerabilities.
Note, the string passed to `unsafeHTML` must be developer-controlled or
sanitized and not include untrusted content. Examples of untrusted content
include query string parameters, values from user inputs, or user-controlled and
unsanitized data. Untrusted content rendered with this directive could lead to
[cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting)
vulnerabilities.

</div>

Expand Down Expand Up @@ -1490,6 +1505,99 @@ customElements.define('my-element', MyElement);

Explore `unsafeHTML` more in the [playground](/playground/#sample=examples/directive-unsafe-html).

### unsafeMathML

Renders a string as MathML rather than text.

<table>
<thead><tr><th></th><th></th></tr></thead>
<tbody>
<tr>
<td class="no-wrap-cell vcenter-cell">Import</td>
<td class="wide-cell">

```js
import {unsafeMathML} from 'lit/directives/unsafe-mathml.js';
```

</td>
</tr>
<tr>
<td class="no-wrap-cell vcenter-cell">Signature</td>
<td class="wide-cell">

```ts
unsafeMathML(value: string | typeof nothing | typeof noChange)
```

</td>
</tr>
<tr>
<td class="no-wrap-cell vcenter-cell">Usable location</td>
<td class="wide-cell">

Child expression

</td>
</tr>
</tbody>
</table>

The `unsafeMathML` directive will parse a string as MathML and render it in a
Lit template expression.

Similar to with [`unsafeHTML`](#unsafeHTML), there may be cases when MathML content
not originating in script files needs to be rendered in a Lit template, for
example trusted MathML content fetched from a database.

<div class="alert alert-warning">

Note, the string passed to `unsafeMathML` must be developer-controlled or
sanitized and not include untrusted content. Examples of untrusted content
include query string parameters, values from user inputs, or user-controlled and
unsanitized data. Untrusted content rendered with this directive could lead to
[cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting)
vulnerabilities.

</div>

{% switchable-sample %}

```ts
const mathmlString = '<mn>1</mn>';

@customElement('my-element')
class MyElement extends LitElement {

render() {
return html`
Look out, potentially unsafe MathML ahead:
<math>
${unsafeMathML(mathmlString)}
</math> `;
}
}
```

```js
const mathmlString = '<mn>1</mn>';

class MyElement extends LitElement {

render() {
return html`
Look out, potentially unsafe MathML ahead:
<math>
${unsafeMathML(mathmlString)}
</math> `;
}
}
customElements.define('my-element', MyElement);
```

{% endswitchable-sample %}


### unsafeSVG

Renders a string as SVG rather than text.
Expand Down Expand Up @@ -1528,17 +1636,21 @@ Child expression
</tbody>
</table>

The `unsafeSVG` directive will parse a string as SVG and render it in a Lit
template expression.

Similar to with [`unsafeHTML`](#unsafeHTML), there may be cases when SVG content
not originating in script files needs to be rendered in a Lit template, for
example trusted SVG content fetched from a database. The `unsafeSVG` directive
will parse such a string as SVG and render it in a Lit template.
example trusted SVG content fetched from a database.

<div class="alert alert-warning">

Note, the string passed to `unsafeSVG` must be developer-controlled and not
include untrusted content. Examples of untrusted content include query string
parameters and values from user inputs. Untrusted content rendered with this
directive could lead to [cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerabilities.
Note, the string passed to `unsafeSVG` must be developer-controlled or
sanitized and not include untrusted content. Examples of untrusted content
include query string parameters, values from user inputs, or user-controlled and
unsanitized data. Untrusted content rendered with this directive could lead to
[cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting)
vulnerabilities.

</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ html`<main>${bodyText}</main>`
Expressions in the child position can take many kinds of values:

* Primitive values likes strings, numbers, and booleans.
* `TemplateResult` objects created with the [`html`](/docs/v3/api/templates/#html) function (or the [`svg`](/docs/v3/api/templates/#svg) function, if the expression is inside an `<svg>` element).
* `TemplateResult` objects created with the [`html`](/docs/v3/api/templates/#html) function (or the [`svg`](/docs/v3/api/templates/#svg) or [`mathml`](/docs/v3/api/templates/#mathml)functions, if the expression is inside an `<svg>` or `<mathml>` element).
* DOM nodes.
* The sentinel values [`nothing`](/docs/v3/templates/conditionals/#conditionally-rendering-nothing) and [`noChange`](/docs/v3/templates/custom-directives/#signaling-no-change).
* Arrays or iterables of any of the supported types.
Expand Down Expand Up @@ -448,13 +448,13 @@ Note that expressions in all the invalid cases above are valid when using [stati

Static expressions return special values that are interpolated into the template _before_ the template is processed as HTML by Lit. Because they become part of the template's static HTML, they can be placed anywhere in the template - even where expressions would normally be disallowed, such as in attribute and tag names.

To use static expressions, you must import a special version of the `html` or `svg` template tags from Lit's `static-html` module:
To use static expressions, you must import a special version of the `html`, `svg`, or `mathml` template tags from Lit's `static-html` module:

```ts
import {html, literal} from 'lit/static-html.js';
```

The `static-html` module contains `html` and `svg` tag functions which support static expressions and should be used instead of the standard versions provided in the `lit` module. Use the `literal` tag function to create static expressions.
The `static-html` module contains `html`, `svg`, and `mathml` tag functions which support static expressions and should be used instead of the standard versions provided in the `lit` module. Use the `literal` tag function to create static expressions.

You can use static expressions for configuration options that are unlikely to change or for customizing parts of the template you cannot with normal expressions - see the section on [Valid expression locations](#expression-locations) for details. For example, a `my-button` component might render a `<button>` tag, but a subclass might render an `<a>` tag, instead. This is a good place to use a static expression because the setting does not change frequently and customizing an HTML tag cannot be done with a normal expression.

Expand Down
Loading