-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
馃摉 Fix amp-script doc #29582
馃摉 Fix amp-script doc #29582
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ formats: | |
- websites | ||
teaser: | ||
text: Runs custom JavaScript in a Web Worker. | ||
experimental: true | ||
--- | ||
|
||
<!--- | ||
|
@@ -32,7 +31,7 @@ An `amp-script` element can load JavaScript in two ways: | |
- remotely, from a URL | ||
- locally, from a `<script>` element on the page | ||
|
||
#### Load JavaScript from a remote URL | ||
### Load JavaScript from a remote URL | ||
|
||
Use the `src` attribute to load JavaScript from a URL: | ||
|
||
|
@@ -42,7 +41,7 @@ Use the `src` attribute to load JavaScript from a URL: | |
</amp-script> | ||
``` | ||
|
||
#### Load JavaScript from a local element | ||
### Load JavaScript from a local element | ||
|
||
You can also include your JavaScript inline, in a `script` tag. You must: | ||
|
||
|
@@ -78,7 +77,7 @@ You can also include your JavaScript inline, in a `script` tag. You must: | |
For security reasons, `amp-script` elements with a `script` or cross-origin `src` attribute require a [script hash](#script-hash) in a `<meta name="amp-script-src" content="...">` tag. Also, same-origin `src` files must have [`Content-Type`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type): `application/javascript` or `text/javascript`. | ||
[/tip] | ||
|
||
### How does it work? | ||
## How does it work? | ||
|
||
`amp-script` runs your custom JavaScript in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) that has access to a virtual DOM. When your JavaScript code modifies this virtual DOM, `amp-script` forwards these changes to the main thread and applies them to the `amp-script` element subtree. | ||
|
||
|
@@ -101,7 +100,7 @@ Will be reflected on the page as a new child of the `amp-script` element: | |
|
||
Under the hood, `amp-script` uses [@ampproject/worker-dom](https://github.com/ampproject/worker-dom/). For design details, see the ["Intent to Implement" issue](https://github.com/ampproject/amphtml/issues/13471). | ||
|
||
### State manipulation | ||
## State manipulation | ||
|
||
`amp-script` supports getting and setting [`amp-state`](https://amp.dev/documentation/components/amp-bind/#initializing-state-with-amp-state) JSON via JavaScript. | ||
|
||
|
@@ -126,7 +125,7 @@ AMP.setState(json) {} | |
AMP.getState(expr) {} | ||
``` | ||
|
||
##### Example with WebSocket and AMP.setState() | ||
### Example with WebSocket and AMP.setState() | ||
|
||
```html | ||
<amp-script width="1" height="1" script="webSocketDemo"> </amp-script> | ||
|
@@ -143,22 +142,22 @@ AMP.getState(expr) {} | |
</script> | ||
``` | ||
|
||
### Restrictions | ||
## Restrictions | ||
|
||
#### Allowed APIs | ||
### Allowed APIs | ||
|
||
Currently, most DOM elements and their properties are supported. DOM query APIs like `querySelector` have partial support. Browser APIs like `History` are not implemented yet. See the [API compatibility table](https://github.com/ampproject/worker-dom/blob/master/web_compat_table.md) for details. | ||
|
||
If there's an API you'd like to see supported, please [file an issue](https://github.com/ampproject/amphtml/issues/new) and mention `@choumx` and `@kristoferbaxter`. | ||
|
||
#### Size of JavaScript code <a name="size-of-javascript-code"></a> | ||
### Size of JavaScript code <a name="size-of-javascript-code"></a> | ||
|
||
`amp-script` has the following restrictions on JavaScript file size: | ||
|
||
- Maximum of 10,000 bytes per `amp-script` element that uses a local script via `script[type=text/plain][target=amp-script]`. | ||
- Maximum total of 150,000 bytes for all `amp-script` elements on the page. | ||
|
||
#### User gestures <a name="user-gestures"></a> | ||
### User gestures <a name="user-gestures"></a> | ||
|
||
In some cases, `amp-script` requires a user gesture to apply changes triggered by your JavaScript code (we call these "mutations") to the `amp-script`'s DOM children. This helps avoid poor user experience from unexpected content jumping. | ||
|
||
|
@@ -167,11 +166,11 @@ The rules for mutations are as follows: | |
1. For `amp-script` elements with [non-container layout](https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/control_layout#supported-values-for-the-layout-attribute), mutations are always allowed. | ||
2. For `amp-script` elements with container layout, mutations are allowed for five seconds following a user gesture. This five second window is extended once if a `fetch()` is triggered. | ||
|
||
#### Creating AMP elements | ||
### Creating AMP elements | ||
|
||
With regard to dynamic creation of AMP elements (e.g. via `document.createElement()`), only `amp-img` and `amp-layout` are currently allowed. Please upvote or comment on {{'[% raw %]'}}[#{{'{% endraw %}'}}25344](https://github.com/ampproject/amphtml/issues/25344) with your use case. | ||
With regard to dynamic creation of AMP elements (e.g. via `document.createElement()`), only `amp-img` and `amp-layout` are currently allowed. Please upvote or comment on [#25344](https://github.com/ampproject/amphtml/issues/25344) with your use case. | ||
|
||
### Calculating the script hash <a name="script-hash"></a> | ||
## Calculating the script hash <a name="script-hash"></a> | ||
|
||
Since custom JS run in `amp-script` is not subject to normal [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), you need to add this script hash: | ||
|
||
|
@@ -188,11 +187,13 @@ Include the script hash in a `meta[name=amp-script-src]` element in the document | |
2. base64url-encode the result. | ||
3. Prefix that with `sha384-`. | ||
|
||
Here's you might build the hash in node.js: | ||
Here's how you calculate the hash in Node.js: | ||
|
||
```js | ||
const crypto = require('crypto'); | ||
const hash = crypto.createHash('sha384'); | ||
|
||
function generateCSPHash(script) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea to suggest that people do this by importing the toolbox. Especially as then they'll be up-to-date if somehow we ever change the way this is calculated. I did also change the docs to mention the toolbox earlier. That said, I think people should also know how to do this themselves - and providing the sample code is more explicit than the instructions I gave. Why don't we include both methods? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Developers should use the toolbox library instead of implementing it on their own. This gives us an easier upgrade path if we'd decide to change the implementation in the future. If they want to see the implementation they can look at the source code of the NPM module. |
||
const hash = crypto.createHash('sha384'); | ||
const data = hash.update(script, 'utf-8'); | ||
return ( | ||
'sha384-' + | ||
|
@@ -205,6 +206,8 @@ function generateCSPHash(script) { | |
} | ||
``` | ||
|
||
There also a node module available which does it for you: [@ampproject/toolbox-script-csp](https://www.npmjs.com/package/@ampproject/toolbox-script-csp). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you change "There also" to "There is also"? |
||
|
||
This example shows how to use the script hash in HTML: | ||
|
||
```html | ||
|
@@ -291,14 +294,14 @@ This element includes [common attributes](https://amp.dev/documentation/guides-a | |
|
||
There are several types of runtime errors that may be encountered when using `amp-script`. | ||
|
||
#### "Maximum total script size exceeded (...)" | ||
### "Maximum total script size exceeded (...)" | ||
|
||
`amp-script` limits the size of the JS source that may be used. See [Size of JavaScript code](#size-of-javascript-code) above. | ||
|
||
#### "Script hash not found." | ||
### "Script hash not found." | ||
|
||
For local scripts and cross-origin scripts, you need to add a [script hash](#script-hash) for security. | ||
|
||
#### "amp-script... was terminated due to illegal mutation" | ||
### "amp-script... was terminated due to illegal mutation" | ||
|
||
To avoid unexpected content jumping, `amp-script` generally requires user gestures for DOM changes. See [User gestures](#user-gestures) above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing these! This was also on my to-do list. Now I don't have to :)