You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+18Lines changed: 18 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,24 @@
4
4
5
5
- Put your changes here...
6
6
7
+
## 1.2.0
8
+
9
+
- Added view transition support in the default render method.
10
+
- Added support for multiple DOM update targets in the default render method.
11
+
- Added `req.backButtonPressed` and `req.forwardButtonPressed` to `app`.
12
+
- Added classes `backButtonPressed` and `forwardButtonPressed` which will populate on the `<html>` element if either button was pressed.
13
+
- Added `[data-page-title]` to the top of the list of accepted query selectors for sourcing content to announce to screen readers when a new page is rendered.
14
+
- Added new params to the `res.beforeRender(params)`, `beforeEveryRender(params)`, `res.afterRender(params)`, and `afterEveryRender(params)` methods:
15
+
- It now supplies an object with:
16
+
-`model`: The data model supplied to the template to be rendered.
17
+
-`doc`: The document object created from the template after it is rendered.
18
+
-`markup`: The HTML string that will be written to the page.
19
+
-`targets`: The list of DOM nodes that will be updated.
20
+
- Fixed a bug that caused `postRenderCallbacks` not to function properly.
21
+
- Fixed a bug related to script tags from the rendered page being executed unnecessarily.
22
+
- Fixed a bug causing unnecessary outlines to appear on page transitions in Safari.
23
+
- Updated dependencies.
24
+
7
25
## 1.1.1
8
26
9
27
- Fixed crash related to unfinished HTML validation feature.
A client-side implementation of the [Express](http://expressjs.com) route API. It works by hijacking links and form submits, then providing a direct imitation of the Express route API to handle "requests" (click or submit events) and issue "responses" in the form of DOM updates. It will update the browser history to match the route accordingly, update the scroll position appropriately, and there are hooks available for setting animations as well.
6
+
A client-side implementation of the [Express](http://expressjs.com) route API. It works by hijacking links and form submits, then providing a direct imitation of the Express route API to handle "requests" (click or submit events) and issue "responses" in the form of DOM updates.
7
+
8
+
When a `single-page-express` route is triggered, it will update the browser history state to match the route accordingly, update the scroll position appropriately, set focus appropriately, will start a [view transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API) to animate the DOM updates, and there are hooks available to customize the animations as well. If view transitions are not supported in the browser, the page will transition, but it will not animate unless you set a custom animation using another animation technique.
7
9
8
10
This allows you to write isomorphic (aka universal, [amphibious](https://twitter.com/kethinov/status/566896168324825088), etc) router code that can be shared verbatim on the client and the server in your Express application.
9
11
@@ -46,8 +48,8 @@ The package is distributed with the following builds available:
46
48
Then, in your frontend code:
47
49
48
50
```javascript
49
-
consttemplatingEngine=// define which templating engine to use here
50
-
consttemplates=// load some templates here
51
+
consttemplatingEngine=require('') // define which templating engine to use here
52
+
consttemplates={} // load some templates here
51
53
```
52
54
53
55
For `templatingEngine`, use something like [teddy](https://github.com/rooseveltframework/teddy), [mustache](https://github.com/janl/mustache.js/), or any other templating system that supports Express and works in the browser.
@@ -191,7 +193,7 @@ There are 3 sample apps you can run to see demos of how `single-page-express` ca
191
193
The default render method will handle both full page renders as well as rendering partials:
192
194
193
195
- If you set `res.title`, the page's title will be updated with its contents. Alternatively, if the template render output contains a `<title>` tag, the page's title will be updated with its contents.
194
-
- When the new page is rendered, it will be announced to screen readers. The content to read to screen readers will be sourced from one of the following querySelectors: `h1[aria-label]`, `h1`, or `title` in that order.
196
+
- When the new page is rendered, it will be announced to screen readers. The content to read to screen readers will be sourced from one of the following querySelectors: `[data-page-title]`, `h1[aria-label]`, `h1`, or `title` in that order.
195
197
- If the template render contains an `<html>` or `<head>` tag and there are new attributes on the `<html>` or `<head>` tags that aren't present in the current document, those attributes will be set on the current document. This behavior is additive or replacement-level only. Attributes cannot be removed simply by omitting them in the template render. If you want to remove an attribute, do it with JavaScript, or set it to a different value in your template render.
196
198
- If there are any new children for the `<head>` in the template render, they will be inserted into the current document's `<head>` tag if they are not present already.
197
199
- If any of the new tags are `<link>` or `<script>` tags, the DOM update will be delayed until those external files load to prevent a [flash of unstyled content](https://en.wikipedia.org/wiki/Flash_of_unstyled_content).
@@ -204,8 +206,10 @@ The default render method will handle both full page renders as well as renderin
204
206
- If you set `res.removeHeadTags`, all tags except `<title>` will be removed from the `<head>` before adding any new ones.
205
207
- If you set `res.target`, the DOM will be updated at that spot. `res.target` is a query selector, so an example value you could give it would be `#my-container`. That would replace the contents of the element with the id "my-container" with the output of your rendered template.
206
208
- If the output of your rendered template also has an element matching the same query selector, then the contents of that portion of the output will be all that is used to replace the target.
207
-
- If you do not set `res.target`, the contents of the `<body>` tag will be replaced with the output of your rendered template.
208
-
- If you set `res.focus`, the browser's focus will be set to that element after the page is rendered. If you do not set `res.focus`, then the browser's focus will be set to the first non-inert element in the DOM with the `autofocus` attribute, or, if none are present, it will be set to whatever the target element was set to for the DOM update.
209
+
- If you do not set `res.target` and neither `app.defaultTarget` nor `app.defaultTargets` is set, then the contents of the `<body>` tag will be replaced with the output of your rendered template.
210
+
- You can also supply an array of query selectors to `res.target`. Elements found matching the query selectors in the array will be replaced with the corresponding query selectors from the rendered template.
211
+
- If you set `res.appendTargets = true`, any new target(s) you add will be in addition to whatever is set by `app.defaultTarget` or `app.defaultTargets`.
212
+
- If you set `res.focus`, the browser's focus will be set to that element after the page is rendered. If you do not set `res.focus`, then the browser's focus will be set to the first non-inert element in the DOM with the `autofocus` attribute, or, if none are present, it will be set to whatever the target element was set to for the DOM update. If there are multiple targets, the first target on the list will be what is selected.
209
213
- There are also hooks for setting animations as well. See "Hooks for setting animations" below.
210
214
211
215
If this DOM manipulation behavior is undesirable to you, you can supply your own render method instead and do whatever you like. To supply your own render method, see the constructor parameter documentation below.
@@ -229,18 +233,27 @@ These constructor params are only relevant if you're not supplying a custom rend
229
233
230
234
##### Pre-render
231
235
232
-
-`beforeEveryRender(model)`: Optionally supply a function to execute just before your template is rendered and written to the DOM. Useful for beginning a CSS transition.
233
-
- You can also set `res.beforeRender(model)` on a per request basis.
236
+
-`beforeEveryRender(params)`: Optionally supply a function to execute just before your template is rendered and written to the DOM. Useful for beginning a CSS transition.
237
+
- You can also set `res.beforeRender(params)` on a per request basis.
238
+
- The `params` argument contains:
239
+
-`model`: The data model supplied to the template to be rendered.
240
+
-`doc`: The document object created from the template after it is rendered.
241
+
-`markup`: The HTML string that will be written to the page.
242
+
-`targets`: The list of DOM nodes that will be updated.
234
243
-`defaultTarget`: Query string representing the default element to target if one is not supplied by `res.target`. Defaults to the `<body>` tag if neither `res.target` or `app.defaultTarget` is supplied.
244
+
-`defaultTargets`: Array of query strings representing elements to target for replacement if such an array is not supplied by `res.target`. Elements found matching the query strings in the array will be replaced with the corresponding query string from the rendered template.
235
245
-`updateDelay`: How long to wait in milliseconds between rendering the template and writing its contents to the DOM. This is useful to give your animations time to animate if you're using animations. Default: `0`
236
246
- You can also set `res.updateDelay` on a per request basis.
237
247
238
248
##### Post-render
239
249
240
-
-`afterEveryRender(model)`: Optionally supply a function to execute just after your template is rendered and written to the DOM. Useful for finishing a CSS transition.
241
-
242
-
- You can also set `res.afterRender(model)` on a per request basis.
243
-
250
+
-`afterEveryRender(params)`: Optionally supply a function to execute just after your template is rendered and written to the DOM. Useful for finishing a CSS transition.
251
+
- You can also set `res.afterRender(params)` on a per request basis.
252
+
- The `params` argument contains:
253
+
-`model`: The data model supplied to the template rendered.
254
+
-`doc`: The document object created from the template after it was rendered.
255
+
-`markup`: The HTML string that was written to the page.
256
+
-`targets`: The list of DOM nodes that were updated.
244
257
-`postRenderCallbacks`: Optionally supply an object with keys that are template names and values that are functions to execute after that template renders. You can also supply `*` as a key to execute a post-render callback after every template render.
245
258
246
259
### Application object
@@ -254,6 +267,7 @@ When you call the constructor, it will return an `app` object.
254
267
-`appVars`: List of variables stored via `app.set()` and retrieved with `app.get()`.
255
268
-`beforeEveryRender`: Function to execute before every template render sourced from the constructor params.
256
269
-`defaultTarget`: Query string representing the default element to target if one is not supplied by `res.target`.
270
+
-`defaultTargets`: Optional array of query strings representing elements to target for replacement if such an array is not supplied by `res.target`.
257
271
-`expressVersion`: Which version of the Express API to use for route string parsing sourced from the constructor params.
258
272
-`postRenderCallbacks`: List of callback functions to execute after a render event occurs sourced from the constructor params.
259
273
-`routes`: List of routes registered with `single-page-express`.
@@ -366,6 +380,8 @@ Likewise all other `req` methods [from the Node.js API](https://nodejs.org/api/h
366
380
367
381
#### New properties defined by single-page-express
368
382
383
+
-`req.backButtonPressed`: This will be `true` when the browser back button was pressed. A class `backButtonPressed` will also be added to the `<html>` element.
384
+
-`req.forwardButtonPressed`: This will be `true` when the browser forward button was pressed. A class `forwardButtonPressed` will also be added to the `<html>` element.
369
385
-`req.singlePageExpress`: This property will always be set to `true`. You can use it to detect whether your route is executing in the `single-page-express` context or not.
370
386
371
387
### Response object
@@ -380,8 +396,9 @@ Likewise all other `req` methods [from the Node.js API](https://nodejs.org/api/h
380
396
381
397
##### New properties defined by single-page-express
382
398
383
-
-`res.afterRender(model)`: If using the default render method, you can set this to a function that will execute after every render.
384
-
-`res.beforeRender(model)` If using the default render method, you can set this to a function that will execute before every render.
399
+
-`res.addTargets`: If using the default render method, use this variable to set an array of query selectors representing elements to target for replacement in addition to whatever is set by `app.defaultTargets`. Elements found matching the query strings in the array will be replaced with the corresponding query string from the rendered template.
400
+
-`res.afterRender(params)`: If using the default render method, you can set this to a function that will execute after every render.
401
+
-`res.beforeRender(params)` If using the default render method, you can set this to a function that will execute before every render.
385
402
-`res.focus`: If using the default render method, if you set `res.focus`, the browser's focus will be set to that element after the page is rendered. If you do not set `res.focus`, then the browser's focus will be set to the first non-inert element in the DOM with the `autofocus` attribute, or, if none are present, it will be set to whatever the target element was set to for the DOM update.
386
403
-`res.removeBaseTags`: If using the default render method, this will remove any `<base>` tags from the page before doing the DOM update.
387
404
-`res.removeHeadTags`: If using the default render method, this will remove all children of the `<head>` tag except the title element from the page before doing the DOM update.
@@ -390,7 +407,7 @@ Likewise all other `req` methods [from the Node.js API](https://nodejs.org/api/h
390
407
-`res.removeScriptTags`: If using the default render method, this will remove any `<script>` tags from the page before doing the DOM update.
391
408
-`res.removeStyleTags`: If using the default render method, this will remove any `<style>` tags from the page before doing the DOM update.
392
409
-`res.removeTemplateTags`: If using the default render method, this will remove any `<template>` tags from the page before doing the DOM update.
393
-
-`res.target`: If using the default render method, use this variable to set a query selector to determine which element's contents will be replaced by your template render's contents. If none is supplied, the `<body>` tag's contents will be replaced.
410
+
-`res.target`: If using the default render method, use this variable to set a query selector or array of query selectors to determine which DOM node contents will be replaced by your template render's contents. If none is supplied, and neither `app.defaultTarget` nor `app.defaultTargets` is set, then the contents of the `<body>` tagwill be replaced with the output of your rendered template.
394
411
-`res.title`: If using the default render method, use this variable to set a page title for the new render.
395
412
-`res.updateDelay`: If using the default render method, use this variable to set a delay in milliseconds before the render occurs. If not using the default render method, this property will still allow you to specify a delay before resetting the scroll position.
396
413
-`res.resetScroll`: Purges the memory of the scroll position for this route so that scroll position is reset to the top for this page and all its child containers.
0 commit comments