@soleil-se/app-util 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +165 -23
- package/app-data/index.js +14 -5
- package/attribute-util/index.js +1 -2
- package/package.json +3 -3
- package/render-vue/index.js +5 -3
- package/src/index.js +32 -12
- package/svelte-client/.eslintrc +4 -0
- package/svelte-client/index.js +31 -0
- package/svelte-server/index.js +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [3.0.0] - 2020-09-28
|
|
8
|
+
### Added
|
|
9
|
+
- Svelte support.
|
|
10
|
+
- New exports:
|
|
11
|
+
- `uniqueId` - A unique id for the app instance.
|
|
12
|
+
|
|
13
|
+
## [2.4.1] - 2020-09-01
|
|
14
|
+
### Fixed
|
|
15
|
+
- App data with single quotes crashes app in edit mode, use double quotes instead.
|
|
16
|
+
|
|
7
17
|
## [2.4.0] - 2020-05-26
|
|
8
18
|
### Fixed
|
|
9
19
|
- `getViewUri` returns correct URI when in offline mode and in the Addons view.
|
package/README.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Webapp Util
|
|
2
2
|
Utility functions for Webapps.
|
|
3
|
+
|
|
4
|
+
<!-- TOC -->
|
|
5
|
+
|
|
6
|
+
- [Install](#install)
|
|
7
|
+
- [Changelog](#changelog)
|
|
8
|
+
- [Migration 1.x.x to 2.x.x](#migration-1xx-to-2xx)
|
|
9
|
+
- [Usage](#usage)
|
|
10
|
+
- [`renderApp([config], [settings])` ⇒ `String`](#renderappconfig-settings-⇒-string)
|
|
11
|
+
- [Example](#example)
|
|
12
|
+
- [**Vue**](#vue)
|
|
13
|
+
- [`getRouteUri(route)` ⇒ `String`](#getrouteuriroute-⇒-string)
|
|
14
|
+
- [Example](#example-1)
|
|
15
|
+
- [`getViewUri(route)` ⇒ `String`](#getviewuriroute-⇒-string)
|
|
16
|
+
- [Example](#example-2)
|
|
17
|
+
- [`getResourceUri(resource)` ⇒ `String`](#getresourceuriresource-⇒-string)
|
|
18
|
+
- [Example](#example-3)
|
|
19
|
+
- [`renderTemplate(template, [values])` ⇒ `String`](#rendertemplatetemplate-values-⇒-string)
|
|
20
|
+
- [Example](#example-4)
|
|
21
|
+
- [`isOffline`](#isoffline)
|
|
22
|
+
- [`isOnline`](#isonline)
|
|
23
|
+
- [`uniqueId`](#uniqueid)
|
|
24
|
+
- [AppData](#appdata)
|
|
25
|
+
- [Svelte](#svelte)
|
|
26
|
+
- [Server](#server)
|
|
27
|
+
- [`render(App, [data], [settings])` ⇒ `String`](#renderapp-data-settings-⇒-string)
|
|
28
|
+
- [`renderServer(App, [data])` ⇒ `String`](#renderserverapp-data-⇒-string)
|
|
29
|
+
- [`renderClient(App, [data], [settings])` ⇒ `String`](#renderclientapp-data-settings-⇒-string)
|
|
30
|
+
- [Client](#client)
|
|
31
|
+
- [`render(App)`](#renderapp)
|
|
32
|
+
|
|
33
|
+
<!-- /TOC -->
|
|
34
|
+
|
|
3
35
|
## Install
|
|
4
36
|
`yarn add @soleil-se/webapp-util`
|
|
5
37
|
|
|
@@ -20,8 +52,8 @@ See [example](#example).
|
|
|
20
52
|
import { renderApp, getRouteUri, getViewUri, getResourceUri, renderTemplate, isOffline, isOnline } from '@soleil-se/webapp-util';
|
|
21
53
|
```
|
|
22
54
|
### `renderApp([config], [settings])` ⇒ `String`
|
|
23
|
-
Get HTML string for rendering
|
|
24
|
-
Can be used together with `@soleil-se/webapp-util/render-vue` or a custom render function in the client code.
|
|
55
|
+
Get HTML string for rendering a client side application.
|
|
56
|
+
Can be used together with `@soleil-se/webapp-util/render-vue`, `@soleil-se/webapp-util/svelte-client` or a custom render function in the client code.
|
|
25
57
|
|
|
26
58
|
**Returns**: <code>String</code> - HTML for rendering an application.
|
|
27
59
|
|
|
@@ -54,7 +86,7 @@ router.get('/', (req, res) => {
|
|
|
54
86
|
});
|
|
55
87
|
```
|
|
56
88
|
##### **Vue**
|
|
57
|
-
In `app_src/client/index.js`.
|
|
89
|
+
In `app_src/client/index.js` or `app_src/main.js`.
|
|
58
90
|
```javascript
|
|
59
91
|
import render from '@soleil-se/webapp-util/render-vue';
|
|
60
92
|
import App from './App.vue';
|
|
@@ -62,24 +94,6 @@ import App from './App.vue';
|
|
|
62
94
|
render(App);
|
|
63
95
|
```
|
|
64
96
|
|
|
65
|
-
##### **App data**
|
|
66
|
-
If you need to use the data that is available for the App you can use `@soleil-se/webapp-util/app-data`.
|
|
67
|
-
|
|
68
|
-
For example when you need a route URI from the server:
|
|
69
|
-
```javascript
|
|
70
|
-
import AppData from '@soleil-se/webapp-util/app-data';
|
|
71
|
-
import superagent from 'superagent';
|
|
72
|
-
|
|
73
|
-
const searchThings = async (query) => {
|
|
74
|
-
const { body } = await superagent
|
|
75
|
-
.get(AppData.searchRoute)
|
|
76
|
-
.query({ query });
|
|
77
|
-
return body;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export default searchThings;
|
|
81
|
-
```
|
|
82
|
-
|
|
83
97
|
### `getRouteUri(route)` ⇒ `String`
|
|
84
98
|
Get URI for a route, same as `getStandaloneUrl` in SiteVision template.
|
|
85
99
|
https://developer.sitevision.se/docs/webapps/template#h-Methods
|
|
@@ -169,7 +183,8 @@ const string = renderTemplate(mainTemplate, { items, itemTemplate });
|
|
|
169
183
|
> **NOTE**
|
|
170
184
|
> Remember that the second argument must be an object and that objects properties are accessed directly in any child templates!
|
|
171
185
|
### `isOffline`
|
|
172
|
-
If the webapp is running in offline mode or not.
|
|
186
|
+
If the webapp is running in offline mode or not.
|
|
187
|
+
This value is also passed to AppData.
|
|
173
188
|
|
|
174
189
|
```javascript
|
|
175
190
|
if(isOffline) {
|
|
@@ -178,10 +193,137 @@ if(isOffline) {
|
|
|
178
193
|
```
|
|
179
194
|
|
|
180
195
|
### `isOnline`
|
|
181
|
-
If the webapp is running in online mode or not.
|
|
196
|
+
If the webapp is running in online mode or not.
|
|
197
|
+
This value is also passed to AppData.
|
|
182
198
|
|
|
183
199
|
```javascript
|
|
184
200
|
if(isOnline) {
|
|
185
201
|
// Do something
|
|
186
202
|
}
|
|
187
203
|
```
|
|
204
|
+
|
|
205
|
+
### `uniqueId`
|
|
206
|
+
A unique ID for the WebApp.
|
|
207
|
+
This value is also passed to AppData.
|
|
208
|
+
|
|
209
|
+
## AppData
|
|
210
|
+
`@soleil-se/webapp-util/app-data`
|
|
211
|
+
Data that is available for the WebApp.
|
|
212
|
+
```javascript
|
|
213
|
+
import AppData from '@soleil-se/webapp-util/app-data';
|
|
214
|
+
|
|
215
|
+
// These are avaliable per default:
|
|
216
|
+
const { isOffline, isOnline, uniqueId } = AppData;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
All data passed to the app is available in AppData:
|
|
220
|
+
index.js
|
|
221
|
+
```javascript
|
|
222
|
+
res.send(renderApp({ foo: 'bar' }))
|
|
223
|
+
```
|
|
224
|
+
In app:
|
|
225
|
+
```javascript
|
|
226
|
+
import AppData from '@soleil-se/webapp-util/app-data';
|
|
227
|
+
|
|
228
|
+
console.log(AppData.foo);
|
|
229
|
+
|
|
230
|
+
// Or descructured
|
|
231
|
+
const { foo } = AppData;
|
|
232
|
+
console.log(foo);
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Svelte
|
|
236
|
+
Functions for rendering a Svelte application.
|
|
237
|
+
|
|
238
|
+
### Server
|
|
239
|
+
`@soleil-se/webapp-util/svelte-server`
|
|
240
|
+
#### `render(App, [data], [settings])` ⇒ `String`
|
|
241
|
+
Get HTML string for rendering a universal Svelte application.
|
|
242
|
+
To be used together with `@soleil-se/webapp-util/svelte-client`.
|
|
243
|
+
|
|
244
|
+
**Returns**: <code>String</code> - HTML for rendering an application.
|
|
245
|
+
|
|
246
|
+
| Param | Type | Default | Description |
|
|
247
|
+
| --- | --- | --- | --- |
|
|
248
|
+
| [App] | <code>Svelte</code> | | Svelte application. |
|
|
249
|
+
| [data] | <code>Object</code> | <code>{}</code> | Server data or config that will be available from `@soleil-se/webapp-util/app-data` |
|
|
250
|
+
| [settings] | <code>Object</code> | <code>{}</code> | Settings object. |
|
|
251
|
+
| [settings.async] | <code>Boolean</code> | <code>false</code> | If the app script should be loaded asynchronously. [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/) |
|
|
252
|
+
| [settings.defer] | <code>Boolean</code> | <code>true</code> | If the app script should be loaded after DOM is ready. [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/) |
|
|
253
|
+
| [settings.req] | <code>Object</code> | | The req object from SiteVision, pass this to optimize browser specific script loading if you have multiple instances of the app. |
|
|
254
|
+
|
|
255
|
+
In `app_src/server/index.js` or `app_src/index.js`.
|
|
256
|
+
```javascript
|
|
257
|
+
import router from 'router';
|
|
258
|
+
import { render } from '@soleil-se/webapp-util/svelte-server';
|
|
259
|
+
|
|
260
|
+
import App from './App.svelte';
|
|
261
|
+
|
|
262
|
+
router.get('/', (req, res) => {
|
|
263
|
+
const data = { foo: 'bar' };
|
|
264
|
+
res.send(renderSvelte(App, data));
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### `renderServer(App, [data])` ⇒ `String`
|
|
269
|
+
Get HTML string for a server only rendered Svelte application.
|
|
270
|
+
|
|
271
|
+
**Returns**: <code>String</code> - HTML for rendering an application.
|
|
272
|
+
|
|
273
|
+
| Param | Type | Default | Description |
|
|
274
|
+
| --- | --- | --- | --- |
|
|
275
|
+
| [App] | <code>Svelte</code> | | Svelte application. |
|
|
276
|
+
| [data] | <code>Object</code> | <code>{}</code> | Server data or config that will be available from `@soleil-se/webapp-util/app-data` |
|
|
277
|
+
|
|
278
|
+
In `app_src/server/index.js` or `app_src/index.js`.
|
|
279
|
+
```javascript
|
|
280
|
+
import router from 'router';
|
|
281
|
+
import { renderServer } from '@soleil-se/webapp-util/svelte-server';
|
|
282
|
+
|
|
283
|
+
import App from './App.svelte';
|
|
284
|
+
|
|
285
|
+
router.get('/', (req, res) => {
|
|
286
|
+
const data = { foo: 'bar' };
|
|
287
|
+
res.send(renderServer(App, data));
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### `renderClient(App, [data], [settings])` ⇒ `String`
|
|
292
|
+
Get HTML string for a client only rendered Svelte application.
|
|
293
|
+
Can be used together with `@soleil-se/webapp-util/svelte-client`.
|
|
294
|
+
|
|
295
|
+
**Returns**: <code>String</code> - HTML for rendering an application.
|
|
296
|
+
|
|
297
|
+
| Param | Type | Default | Description |
|
|
298
|
+
| --- | --- | --- | --- |
|
|
299
|
+
| [App] | <code>Svelte</code> | | Svelte application. |
|
|
300
|
+
| [data] | <code>Object</code> | <code>{}</code> | Server data or config that will be available from `@soleil-se/webapp-util/app-data` |
|
|
301
|
+
| [settings] | <code>Object</code> | <code>{}</code> | Settings object. |
|
|
302
|
+
| [settings.async] | <code>Boolean</code> | <code>false</code> | If the app script should be loaded asynchronously. [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/) |
|
|
303
|
+
| [settings.defer] | <code>Boolean</code> | <code>true</code> | If the app script should be loaded after DOM is ready. [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/) |
|
|
304
|
+
| [settings.req] | <code>Object</code> | | The req object from SiteVision, pass this to optimize browser specific script loading if you have multiple instances of the app. |
|
|
305
|
+
|
|
306
|
+
In `app_src/server/index.js` or `app_src/index.js`.
|
|
307
|
+
```javascript
|
|
308
|
+
import router from 'router';
|
|
309
|
+
import { renderClient } from '@soleil-se/webapp-util/svelte-server';
|
|
310
|
+
|
|
311
|
+
import App from './App.svelte';
|
|
312
|
+
|
|
313
|
+
router.get('/', (req, res) => {
|
|
314
|
+
const data = { foo: 'bar' };
|
|
315
|
+
res.send(renderSvelte(App, data));
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Client
|
|
320
|
+
`@soleil-se/webapp-util/svelte-client`
|
|
321
|
+
#### `render(App)`
|
|
322
|
+
In `app_src/client/index.js` or `app_src/main.js`.
|
|
323
|
+
```javascript
|
|
324
|
+
import { render } from '@soleil-se/webapp-util/svelte-client';
|
|
325
|
+
import App from './App.svelte';
|
|
326
|
+
|
|
327
|
+
render(App);
|
|
328
|
+
```
|
|
329
|
+
|
package/app-data/index.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { parseAttribute } from '../attribute-util';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
let appData = {};
|
|
4
|
+
|
|
5
|
+
export function setAppData(data) {
|
|
6
|
+
appData = data;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getAppData(key) {
|
|
10
|
+
if (!Object.keys(appData).length && process && process.browser) {
|
|
11
|
+
setAppData(parseAttribute('data-app'));
|
|
12
|
+
}
|
|
13
|
+
return key ? appData[key] : appData;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default process && process.browser ? parseAttribute('data-app') : appData;
|
package/attribute-util/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const { currentScript } = document;
|
|
2
1
|
/**
|
|
3
2
|
* JSON decode an attribute on the currentScript element.
|
|
4
3
|
* Use if attribute contains a JSON-object.
|
|
@@ -6,7 +5,7 @@ const { currentScript } = document;
|
|
|
6
5
|
* @returns {Object} Decoded JSON object.
|
|
7
6
|
*/
|
|
8
7
|
export const decodeAttribute = (attribute) => {
|
|
9
|
-
const encoded = currentScript.getAttribute(attribute);
|
|
8
|
+
const encoded = document.currentScript.getAttribute(attribute);
|
|
10
9
|
if (encoded) {
|
|
11
10
|
return decodeURIComponent(encoded);
|
|
12
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soleil-se/app-util",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Utility functions for Webapps.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"author": "Soleil AB",
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
],
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"private": false,
|
|
13
|
-
"homepage": "https://github.com/soleilit/server-monorepo/tree/
|
|
13
|
+
"homepage": "https://github.com/soleilit/server-monorepo/tree/app-util/next/packages/webapp-util#readme",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"current-script-polyfill": "^1.0.0"
|
|
16
16
|
},
|
|
17
|
-
"
|
|
17
|
+
"peerDependencies": {
|
|
18
18
|
"vue": "^2.6.11"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {}
|
package/render-vue/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import 'current-script-polyfill';
|
|
2
2
|
import Vue from 'vue';
|
|
3
3
|
|
|
4
|
-
import { decodeAttribute } from '../attribute-util';
|
|
5
|
-
import
|
|
4
|
+
import { decodeAttribute, parseAttribute } from '../attribute-util';
|
|
5
|
+
import { setAppData } from '../app-data';
|
|
6
|
+
|
|
7
|
+
const options = parseAttribute('data-app');
|
|
8
|
+
setAppData(options);
|
|
6
9
|
|
|
7
10
|
const offlineModeMixin = {
|
|
8
11
|
mounted() {
|
|
@@ -23,7 +26,6 @@ const offlineModeMixin = {
|
|
|
23
26
|
*/
|
|
24
27
|
export default function render(App) {
|
|
25
28
|
const selector = decodeAttribute('data-selector');
|
|
26
|
-
const options = appData;
|
|
27
29
|
|
|
28
30
|
Object.assign(App, options, {
|
|
29
31
|
mixins: [offlineModeMixin],
|
package/src/index.js
CHANGED
|
@@ -13,7 +13,19 @@ export const isOffline = VersionUtil.getCurrentVersion() === VersionUtil.OFFLINE
|
|
|
13
13
|
export const isOnline = !isOffline;
|
|
14
14
|
|
|
15
15
|
const currentPortlet = PortletContextUtil.getCurrentPortlet();
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
const getUniqueId = () => {
|
|
18
|
+
const id = (currentPortlet ? currentPortlet.getIdentifier() : appInfo['jcr:uuid']).replace('.', '_');
|
|
19
|
+
const decoratedNode = PortletContextUtil.getCurrentDecoratedNode();
|
|
20
|
+
|
|
21
|
+
if (decoratedNode) {
|
|
22
|
+
return `${decoratedNode.getIdentifier().replace('.', '_')}_${id}`;
|
|
23
|
+
}
|
|
24
|
+
return id;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export const uniqueId = getUniqueId();
|
|
17
29
|
|
|
18
30
|
/**
|
|
19
31
|
* Get URI for a resource.
|
|
@@ -39,7 +51,8 @@ export function renderTemplate(template, values = {}) {
|
|
|
39
51
|
|
|
40
52
|
/**
|
|
41
53
|
* Get a HTML string for rendering an application.
|
|
42
|
-
* @param {
|
|
54
|
+
* @param {Svelte} [App] Svelte application.
|
|
55
|
+
* @param {Object} [data={}] Server config or data that will be available in the attribute.
|
|
43
56
|
* `data-app` on currentScript. In Vue it will also be available in the `$options` object.
|
|
44
57
|
* @param {Object} [settings={}] Settings object.
|
|
45
58
|
* @param {String} [settings.noScript=''] HTML that will be rendered when JavaScript
|
|
@@ -56,7 +69,8 @@ export function renderTemplate(template, values = {}) {
|
|
|
56
69
|
*/
|
|
57
70
|
export function renderApp(data, {
|
|
58
71
|
noScript = '',
|
|
59
|
-
|
|
72
|
+
html = '',
|
|
73
|
+
selector = `[data-portlet-id="${uniqueId}"]`,
|
|
60
74
|
async = false,
|
|
61
75
|
defer = true,
|
|
62
76
|
req,
|
|
@@ -71,25 +85,31 @@ export function renderApp(data, {
|
|
|
71
85
|
return /Trident\/|MSIE/.test(userAgent);
|
|
72
86
|
};
|
|
73
87
|
|
|
88
|
+
const getHtml = () => (html || (noScript ? `<noscript>${noScript}</noscript>` : ''));
|
|
89
|
+
|
|
90
|
+
const appData = {
|
|
91
|
+
...data, isOffline, isOnline, uniqueId,
|
|
92
|
+
};
|
|
93
|
+
|
|
74
94
|
if (isOffline) {
|
|
75
95
|
return `
|
|
76
|
-
<div data-portlet-id="${
|
|
96
|
+
<div data-portlet-id="${uniqueId}">${getHtml()}</div>
|
|
77
97
|
<script>
|
|
78
98
|
window.svDocReady(function() {
|
|
79
|
-
var targetElement = document.querySelector('[data-portlet-id="${
|
|
80
|
-
var script = document.createElement(
|
|
81
|
-
script.src =
|
|
82
|
-
script.setAttribute(
|
|
83
|
-
script.setAttribute(
|
|
99
|
+
var targetElement = document.querySelector('[data-portlet-id="${uniqueId}"]');
|
|
100
|
+
var script = document.createElement("script");
|
|
101
|
+
script.src = "${getResourceUri('client/index.js')}?${appInfo.appImportDate}${uniqueId.replace('_', '')}";
|
|
102
|
+
script.setAttribute("data-app", "${encodeURIComponent(JSON.stringify(appData))}");
|
|
103
|
+
script.setAttribute("data-selector", "${encodeURIComponent(selector)}");
|
|
84
104
|
targetElement.parentNode.insertBefore(script, targetElement.nextSibling);
|
|
85
105
|
});
|
|
86
106
|
</script>`;
|
|
87
107
|
}
|
|
88
108
|
return `
|
|
89
|
-
<div data-portlet-id="${
|
|
109
|
+
<div data-portlet-id="${uniqueId}">${getHtml()}</div>
|
|
90
110
|
<script
|
|
91
|
-
src="${getResourceUri('client/index.js')}?${appInfo.appImportDate}${isIE() ?
|
|
92
|
-
data-app="${encodeURIComponent(JSON.stringify(
|
|
111
|
+
src="${getResourceUri('client/index.js')}?${appInfo.appImportDate}${isIE() ? uniqueId.replace('_', '') : ''}"
|
|
112
|
+
data-app="${encodeURIComponent(JSON.stringify(appData))}"
|
|
93
113
|
data-selector="${encodeURIComponent(selector)}"
|
|
94
114
|
${async && !defer ? 'async' : ''}
|
|
95
115
|
${defer ? 'defer' : ''}>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* eslint-disable import/prefer-default-export */
|
|
2
|
+
import 'current-script-polyfill';
|
|
3
|
+
|
|
4
|
+
import { decodeAttribute, parseAttribute } from '../attribute-util';
|
|
5
|
+
import { setAppData } from '../app-data';
|
|
6
|
+
|
|
7
|
+
const props = parseAttribute('data-app');
|
|
8
|
+
setAppData(props);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Render a Svelte application
|
|
12
|
+
* @param {Svelte} App Svelte application to be started.
|
|
13
|
+
*/
|
|
14
|
+
export function render(App) {
|
|
15
|
+
const selector = decodeAttribute('data-selector');
|
|
16
|
+
|
|
17
|
+
const mountElement = document.querySelector(selector);
|
|
18
|
+
const hydrate = mountElement.childElementCount > 0;
|
|
19
|
+
if (mountElement) {
|
|
20
|
+
return new App({
|
|
21
|
+
hydrate,
|
|
22
|
+
target: document.querySelector(selector),
|
|
23
|
+
props,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return document.addEventListener('DOMContentLoaded', () => new App({
|
|
27
|
+
hydrate,
|
|
28
|
+
target: document.querySelector(selector),
|
|
29
|
+
props,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import appResource from 'appResource';
|
|
2
|
+
import { setAppData } from '../app-data';
|
|
3
|
+
import {
|
|
4
|
+
renderApp, isOffline, isOnline, uniqueId,
|
|
5
|
+
} from '../src';
|
|
6
|
+
|
|
7
|
+
export function renderClient(data, settings) {
|
|
8
|
+
return renderApp(data, settings);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function renderServer(App, data) {
|
|
12
|
+
const appData = {
|
|
13
|
+
...data, isOffline, isOnline, uniqueId,
|
|
14
|
+
};
|
|
15
|
+
setAppData(appData);
|
|
16
|
+
const { html } = App.render(appData);
|
|
17
|
+
return html;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function render(App, data, settings) {
|
|
21
|
+
const html = renderServer(App, data);
|
|
22
|
+
if (appResource.getNode('client/index.js')) {
|
|
23
|
+
return renderClient(data, { html, ...settings });
|
|
24
|
+
}
|
|
25
|
+
return html;
|
|
26
|
+
}
|