@soleil-se/app-util 1.2.4 → 2.1.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 +39 -0
- package/README.md +157 -108
- package/app-data/.eslintrc +4 -0
- package/app-data/index.js +7 -0
- package/attribute-util/.eslintrc +4 -0
- package/attribute-util/index.js +22 -0
- package/package.json +7 -7
- package/render-vue/.eslintrc +4 -0
- package/render-vue/index.js +41 -43
- package/src/index.js +117 -100
- package/dist/index.js +0 -87
- package/render-vue/src/.eslintrc +0 -3
- package/render-vue/src/index.js +0 -42
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [2.1.0] - 2020-02-14
|
|
8
|
+
### Added
|
|
9
|
+
- App data import in client, `@soleil-api/webapp-util/app-data`.
|
|
10
|
+
- `getViewUri` to get the URI that also renders the page.
|
|
11
|
+
- `isOnline` to see if the app is online.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `vue` is now an optional depedency.
|
|
15
|
+
|
|
16
|
+
## [2.0.0] - 2020-02-12
|
|
17
|
+
### Changed
|
|
18
|
+
- Now using `currentScript` to reference the script element the app is running in to pass data when using `renderApp`.
|
|
19
|
+
- `renderApp` is no longer using appName.
|
|
20
|
+
- `render` is now called directly in `./app_src/client/index.js`.
|
|
21
|
+
- `render` and `App` no longer needs to be exported from `./app_src/client/index.js`.
|
|
22
|
+
|
|
23
|
+
## [1.2.4] - 2020-12-12
|
|
24
|
+
### Fixed
|
|
25
|
+
- `TypeError: Cannot call method getIdentifier of null` when app is viewed in Addons.
|
|
26
|
+
|
|
27
|
+
## [1.2.2] - 2019-05-20
|
|
28
|
+
### Fixed
|
|
29
|
+
- Removed `_sitePage` from `currentPageId` in `getRouteUri`.
|
|
30
|
+
|
|
31
|
+
## [1.2.1] - 2019-05-09
|
|
32
|
+
### Added
|
|
33
|
+
- Added timestamp to WebApp script tag to prevent cache when uploading a new version.
|
|
34
|
+
|
|
35
|
+
## [1.2.0] - 2019-05-07
|
|
36
|
+
### Changed
|
|
37
|
+
- `getRouteUri` now returns the standalone route.
|
|
38
|
+
- HTML comment to not include this.name in `renderApp`.
|
|
39
|
+
|
package/README.md
CHANGED
|
@@ -1,108 +1,157 @@
|
|
|
1
|
-
# Webapp Util
|
|
2
|
-
Utility functions for Webapps.
|
|
3
|
-
## Install
|
|
4
|
-
`yarn add @soleil-se/webapp-util`
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
1
|
+
# Webapp Util
|
|
2
|
+
Utility functions for Webapps.
|
|
3
|
+
## Install
|
|
4
|
+
`yarn add @soleil-se/webapp-util`
|
|
5
|
+
|
|
6
|
+
## Changelog
|
|
7
|
+
[See changelog](CHANGELOG.md).
|
|
8
|
+
|
|
9
|
+
## Migration 1.x.x to 2.x.x
|
|
10
|
+
|
|
11
|
+
Now using `currentScript` to reference the script element the app is running in to pass data.
|
|
12
|
+
|
|
13
|
+
Remove appName from the `renderApp` call in `./app_src/server/index.js`.
|
|
14
|
+
Remove export of `App` and `render` and replace with a call to `render(App)` in `./app_src/client/index.js`.
|
|
15
|
+
|
|
16
|
+
See [example](#example).
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
```javascript
|
|
20
|
+
import { renderApp, getRouteUri, getResourceUri, renderTemplate, isOffline } from '@soleil-se/webapp-util';
|
|
21
|
+
```
|
|
22
|
+
### `renderApp([config], [settings])` ⇒ `String`
|
|
23
|
+
Get HTML string for rendering an application.
|
|
24
|
+
Can be used together with `@soleil-se/webapp-util/render-vue` or a custom render function in the client code.
|
|
25
|
+
|
|
26
|
+
**Returns**: <code>String</code> - HTML for rendering an application.
|
|
27
|
+
|
|
28
|
+
| Param | Type | Default | Description |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| [config] | <code>Object</code> | <code>{}</code> | Server config or data that will be available in the attribute `data-app` on currentScript. In Vue it will also be available in the `$options` object. |
|
|
31
|
+
| [settings] | <code>Object</code> | <code>{}</code> | Settings object. |
|
|
32
|
+
| [settings.noScript] | <code>String</code> | <code>''</code> | HTML that will be rendered when JavaScript is not available. |
|
|
33
|
+
| [settings.selector] | <code>String</code> | <code>`[data-portlet-id="${portletId}"]`</code> | Query selector for where the app should be mounted. |
|
|
34
|
+
| [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/) |
|
|
35
|
+
| [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/) |
|
|
36
|
+
|
|
37
|
+
#### Example
|
|
38
|
+
In `app_src/server/index.js`.
|
|
39
|
+
```javascript
|
|
40
|
+
router.get('/', (req, res) => {
|
|
41
|
+
const data = { foo: 'bar' };
|
|
42
|
+
// Most common usage.
|
|
43
|
+
res.send(renderApp(data));
|
|
44
|
+
|
|
45
|
+
// With all settings.
|
|
46
|
+
res.send(renderApp(data, {
|
|
47
|
+
noScript: 'You need JS for this!',
|
|
48
|
+
selector: '#mount_me_here',
|
|
49
|
+
async: false,
|
|
50
|
+
defer: true,
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
##### **Vue**
|
|
55
|
+
In `app_src/client/index.js`.
|
|
56
|
+
```javascript
|
|
57
|
+
import render from '@soleil-se/webapp-util/render-vue';
|
|
58
|
+
import App from './App.vue';
|
|
59
|
+
|
|
60
|
+
render(App);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
##### **App data**
|
|
64
|
+
If you need to use the data that is available for the App you can use `@soleil-se/webapp-util/app-data`.
|
|
65
|
+
|
|
66
|
+
For example when you need a route URI from the server:
|
|
67
|
+
```javascript
|
|
68
|
+
import AppData from '@soleil-se/webapp-util/app-data';
|
|
69
|
+
import superagent from 'superagent';
|
|
70
|
+
|
|
71
|
+
const searchThings = async (query) => {
|
|
72
|
+
const { body } = await superagent
|
|
73
|
+
.get(AppData.searchRoute)
|
|
74
|
+
.query({ query });
|
|
75
|
+
return body;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default searchThings;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## `getRouteUri(route)` ⇒ `String`
|
|
82
|
+
Get URI for a route, same as `getStandaloneUrl` in SiteVision template.
|
|
83
|
+
https://developer.sitevision.se/docs/webapps/template#h-Methods
|
|
84
|
+
|
|
85
|
+
**Returns**: <code>String</code> - URI for route.
|
|
86
|
+
|
|
87
|
+
| Param | Type | Description |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| route | <code>String</code> | A route. |
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
#### Example
|
|
93
|
+
```javascript
|
|
94
|
+
const routeUri = getRouteUri('/my-route');
|
|
95
|
+
```
|
|
96
|
+
## `getViewUri(route)` ⇒ `String`
|
|
97
|
+
Get URI for a view, same as `getUrl` in SiteVision template.
|
|
98
|
+
https://developer.sitevision.se/docs/webapps/template#h-Methods
|
|
99
|
+
|
|
100
|
+
**Returns**: <code>String</code> - URI for view.
|
|
101
|
+
|
|
102
|
+
| Param | Type | Description |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| route | <code>String</code> | A route. |
|
|
105
|
+
|
|
106
|
+
#### Example
|
|
107
|
+
```javascript
|
|
108
|
+
const viewUri = getViewUri('/my-route');
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `getResourceUri(resource)` ⇒ `String`
|
|
112
|
+
Get URI for a resource.
|
|
113
|
+
|
|
114
|
+
**Returns**: `String` - URI for a resource.
|
|
115
|
+
|
|
116
|
+
| Param | Type | Description |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| resource | `String` | A resource. |
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
#### Example
|
|
122
|
+
```javascript
|
|
123
|
+
const resourceUri = getResourceUri('file/in/resource.png');
|
|
124
|
+
```
|
|
125
|
+
### `renderTemplate(template, [values])` ⇒ `String`
|
|
126
|
+
Renders a Underscore template and returns a string.
|
|
127
|
+
|
|
128
|
+
**Returns**: `String` - Rendered template
|
|
129
|
+
|
|
130
|
+
| Param | Type | Default | Description |
|
|
131
|
+
| --- | --- | --- | --- |
|
|
132
|
+
| template | `String` | | Underscore template. |
|
|
133
|
+
| [values] | `Object` | `{}` | Values. |
|
|
134
|
+
|
|
135
|
+
#### Example
|
|
136
|
+
```javascript
|
|
137
|
+
const string = renderTemplate('<div><%= foo %></div>', {
|
|
138
|
+
foo: 'bar',
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
### `isOffline`
|
|
142
|
+
If the webapp is running in offline mode or not.
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
if(isOffline) {
|
|
146
|
+
// Do something
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `isOnline`
|
|
151
|
+
If the webapp is running in online mode or not.
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
if(isOnline) {
|
|
155
|
+
// Do something
|
|
156
|
+
}
|
|
157
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { currentScript } = document;
|
|
2
|
+
/**
|
|
3
|
+
* JSON decode an attribute on the currentScript element.
|
|
4
|
+
* Use if attribute contains a JSON-object.
|
|
5
|
+
* @param {String} attribute Attribute to decode.
|
|
6
|
+
* @returns {Object} Decoded JSON object.
|
|
7
|
+
*/
|
|
8
|
+
export const decodeAttribute = (attribute) => {
|
|
9
|
+
const encoded = currentScript.getAttribute(attribute);
|
|
10
|
+
if (encoded) {
|
|
11
|
+
return decodeURIComponent(encoded);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Parse an attribute on the currentScript element.
|
|
18
|
+
* Us if the attribute is a String.
|
|
19
|
+
* @param {String} attribute
|
|
20
|
+
* @returns {String} Parsed attribute value.
|
|
21
|
+
*/
|
|
22
|
+
export const parseAttribute = (attribute) => JSON.parse(decodeAttribute(attribute));
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soleil-se/app-util",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Utility functions for Webapps.",
|
|
5
|
-
"main": "./
|
|
5
|
+
"main": "./src/index.js",
|
|
6
6
|
"author": "Soleil AB",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Kimmy Monassar",
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"license": "UNLICENSED",
|
|
12
12
|
"private": false,
|
|
13
13
|
"homepage": "https://github.com/soleilit/server-monorepo/tree/master/packages/app-util",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"current-script-polyfill": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"optionalDependencies": {
|
|
18
|
+
"vue": "^2.6.11"
|
|
18
19
|
},
|
|
19
|
-
"dependencies": {},
|
|
20
20
|
"devDependencies": {}
|
|
21
21
|
}
|
package/render-vue/index.js
CHANGED
|
@@ -1,43 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
import Vue from 'vue';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
mounted
|
|
9
|
-
if (this.$options.isOffline) {
|
|
10
|
-
|
|
11
|
-
$anchors.forEach(
|
|
12
|
-
$anchor.addEventListener('click',
|
|
13
|
-
e.preventDefault();
|
|
14
|
-
window.$svjq($anchor).trigger('click');
|
|
15
|
-
}, false);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Render a Vue application
|
|
22
|
-
* @param {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
}
|
|
1
|
+
import 'current-script-polyfill';
|
|
2
|
+
import Vue from 'vue';
|
|
3
|
+
|
|
4
|
+
import { decodeAttribute } from '../attribute-util';
|
|
5
|
+
import appData from '../app-data';
|
|
6
|
+
|
|
7
|
+
const offlineModeMixin = {
|
|
8
|
+
mounted() {
|
|
9
|
+
if (this.$options.isOffline) {
|
|
10
|
+
const $anchors = this.$el.querySelectorAll('a');
|
|
11
|
+
$anchors.forEach(($anchor) => {
|
|
12
|
+
$anchor.addEventListener('click', (e) => {
|
|
13
|
+
e.preventDefault();
|
|
14
|
+
window.$svjq($anchor).trigger('click');
|
|
15
|
+
}, false);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Render a Vue application
|
|
22
|
+
* @param {Vue} App Vue application to be started.
|
|
23
|
+
*/
|
|
24
|
+
export default function render(App) {
|
|
25
|
+
const selector = decodeAttribute('data-selector');
|
|
26
|
+
const options = appData;
|
|
27
|
+
|
|
28
|
+
Object.assign(App, options, {
|
|
29
|
+
mixins: [offlineModeMixin],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const mountElementExists = !!document.querySelector(selector);
|
|
33
|
+
|
|
34
|
+
if (mountElementExists) {
|
|
35
|
+
new Vue(App).$mount(selector);
|
|
36
|
+
} else {
|
|
37
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
38
|
+
new Vue(App).$mount(selector);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,100 +1,117 @@
|
|
|
1
|
-
import PortletContextUtil from 'PortletContextUtil';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
* @param {Object} [
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* @param {String} [settings.
|
|
45
|
-
*
|
|
46
|
-
* @param {
|
|
47
|
-
*
|
|
48
|
-
* @param {Boolean} [settings.
|
|
49
|
-
* [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
|
|
50
|
-
* @
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<
|
|
66
|
-
<script>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
</
|
|
79
|
-
<script
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
1
|
+
import PortletContextUtil from 'PortletContextUtil';
|
|
2
|
+
import PropertyUtil from 'PropertyUtil';
|
|
3
|
+
import VersionUtil from 'VersionUtil';
|
|
4
|
+
import appInfo from 'appInfo';
|
|
5
|
+
/* Underscore is provided by SiteVision */
|
|
6
|
+
/* eslint-disable-next-line import/no-extraneous-dependencies */
|
|
7
|
+
import _ from 'underscore';
|
|
8
|
+
|
|
9
|
+
/** If the webapp is running in offline mode or not. */
|
|
10
|
+
export const isOffline = VersionUtil.getCurrentVersion() === VersionUtil.OFFLINE_VERSION;
|
|
11
|
+
/** If the webapp is running in online mode or not. */
|
|
12
|
+
export const isOnline = !isOffline;
|
|
13
|
+
|
|
14
|
+
const currentPortlet = PortletContextUtil.getCurrentPortlet();
|
|
15
|
+
const portletId = currentPortlet ? currentPortlet.getIdentifier().replace('.', '_') : '';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get URI for a resource.
|
|
19
|
+
* @param {String} resource A resource.
|
|
20
|
+
* @returns {String} URI for a resource.
|
|
21
|
+
*/
|
|
22
|
+
export function getResourceUri(resource) {
|
|
23
|
+
return `/webapp-files/${appInfo.appIdentifier}/${appInfo.appVersion}/${resource}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Renders a Underscore template and returns a string.
|
|
28
|
+
* @param {String} template Underscore template.
|
|
29
|
+
* @param {Object} [values={}] Values.
|
|
30
|
+
* @returns {String} Rendered template
|
|
31
|
+
*/
|
|
32
|
+
export function renderTemplate(template, values = {}) {
|
|
33
|
+
if (typeof template === 'function') {
|
|
34
|
+
return template(values);
|
|
35
|
+
}
|
|
36
|
+
return _.template(template)(values);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get a HTML string for rendering an application.
|
|
41
|
+
* @param {Object} [data={}] Server config or data that will be available in the attribute
|
|
42
|
+
* `data-app` on currentScript. In Vue it will also be available in the `$options` object.
|
|
43
|
+
* @param {Object} [settings={}] Settings object.
|
|
44
|
+
* @param {String} [settings.noScript=''] HTML that will be rendered when JavaScript
|
|
45
|
+
* is not available.
|
|
46
|
+
* @param {String} [settings.selector=`[data-portlet-id="${portletId}"]`] Query selector for
|
|
47
|
+
* where the app should be mounted.
|
|
48
|
+
* @param {Boolean} [settings.async=false] If the app script should be loaded asynchronously.
|
|
49
|
+
* [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
|
|
50
|
+
* @param {Boolean} [settings.defer=true] If the app script should be loaded after DOM is ready.
|
|
51
|
+
* [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
|
|
52
|
+
* @returns {String} HTML for rendering an application.
|
|
53
|
+
*/
|
|
54
|
+
export function renderApp(data, {
|
|
55
|
+
noScript = '',
|
|
56
|
+
selector = `[data-portlet-id="${portletId}"]`,
|
|
57
|
+
async = false,
|
|
58
|
+
defer = true,
|
|
59
|
+
} = {}) {
|
|
60
|
+
if (typeof data === 'string') {
|
|
61
|
+
throw new Error('As of version 2 renderApp no longer needs the application name.');
|
|
62
|
+
}
|
|
63
|
+
if (isOffline) {
|
|
64
|
+
return `
|
|
65
|
+
<div data-portlet-id="${portletId}">${noScript}</div>
|
|
66
|
+
<script>
|
|
67
|
+
(function(){
|
|
68
|
+
var targetElement = document.querySelector('[data-portlet-id="${portletId}"]');
|
|
69
|
+
var script = document.createElement('script');
|
|
70
|
+
script.src = '${getResourceUri('client/index.js')}?${portletId.replace('_', '')}';
|
|
71
|
+
script.setAttribute('data-app', '${encodeURIComponent(JSON.stringify({ ...data, isOffline }))}');
|
|
72
|
+
script.setAttribute('data-selector', '${encodeURIComponent(selector)}');
|
|
73
|
+
targetElement.parentNode.insertBefore(script, targetElement.nextSibling);
|
|
74
|
+
})();
|
|
75
|
+
</script>`;
|
|
76
|
+
}
|
|
77
|
+
return `
|
|
78
|
+
<div data-portlet-id="${portletId}">${noScript}</div>
|
|
79
|
+
<script
|
|
80
|
+
src="${getResourceUri('client/index.js')}?${appInfo.appImportDate}${portletId.replace('_', '')}"
|
|
81
|
+
data-app="${encodeURIComponent(JSON.stringify({ ...data, isOffline }))}"
|
|
82
|
+
data-selector="${encodeURIComponent(selector)}"
|
|
83
|
+
${async && !defer ? 'async' : ''}
|
|
84
|
+
${defer ? 'defer' : ''}>
|
|
85
|
+
</script>`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get URI for a route, same as `getStandaloneUrl` in SiteVision template.
|
|
90
|
+
* @param {String} route A route.
|
|
91
|
+
* @returns {String} URI for route.
|
|
92
|
+
*/
|
|
93
|
+
export function getRouteUri(route) {
|
|
94
|
+
const currentPageId = PortletContextUtil.getCurrentPage().getIdentifier().replace('_sitePage', '');
|
|
95
|
+
const currentPortletId = PortletContextUtil.getCurrentPortlet().getIdentifier();
|
|
96
|
+
return `/appresource/${currentPageId}/${currentPortletId}/${route}`.replace(/\/\//g, '/');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get URI for a view, same as `getUrl` in SiteVision template.
|
|
101
|
+
* @param {String} route A route.
|
|
102
|
+
* @returns {String} URI for view.
|
|
103
|
+
*/
|
|
104
|
+
export function getViewUri(route) {
|
|
105
|
+
const currentPageUri = PropertyUtil.getString(PortletContextUtil.getCurrentPage(), 'URI');
|
|
106
|
+
return `${currentPageUri}?sv.${portletId}.route=${encodeURI(route)}&sv.target=${portletId}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export default {
|
|
110
|
+
getRouteUri,
|
|
111
|
+
getViewUri,
|
|
112
|
+
getResourceUri,
|
|
113
|
+
renderApp,
|
|
114
|
+
renderTemplate,
|
|
115
|
+
isOffline,
|
|
116
|
+
isOnline,
|
|
117
|
+
};
|
package/dist/index.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import PortletContextUtil from 'PortletContextUtil';
|
|
2
|
-
import VersionUtil from 'VersionUtil';
|
|
3
|
-
import appInfo from 'appInfo';
|
|
4
|
-
/* Underscore is provided by SiteVision */
|
|
5
|
-
/* eslint-disable-next-line import/no-extraneous-dependencies */
|
|
6
|
-
import _ from 'underscore';
|
|
7
|
-
|
|
8
|
-
/** If the webapp is running in offline mode or not. */
|
|
9
|
-
export var isOffline = VersionUtil.getCurrentVersion() === VersionUtil.OFFLINE_VERSION;
|
|
10
|
-
|
|
11
|
-
var currentPortlet = PortletContextUtil.getCurrentPortlet();
|
|
12
|
-
var portletId = currentPortlet ? currentPortlet.getIdentifier().replace('.', '_') : '';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Get URI for a resource.
|
|
16
|
-
* @param {String} resource A resource.
|
|
17
|
-
* @returns {String} URI for a resource.
|
|
18
|
-
*/
|
|
19
|
-
export function getResourceUri(resource) {
|
|
20
|
-
return ("/webapp-files/" + (appInfo.appIdentifier) + "/" + (appInfo.appVersion) + "/" + resource);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Renders a Underscore template and returns a string.
|
|
25
|
-
* @param {String} template Underscore template.
|
|
26
|
-
* @param {Object} [values={}] Values.
|
|
27
|
-
* @returns {String} Rendered template
|
|
28
|
-
*/
|
|
29
|
-
export function renderTemplate(template, values) {
|
|
30
|
-
if ( values === void 0 ) values = {};
|
|
31
|
-
|
|
32
|
-
if (typeof template === 'function') {
|
|
33
|
-
return template(values);
|
|
34
|
-
}
|
|
35
|
-
return _.template(template)(values);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get HTML string for rendering an application.
|
|
40
|
-
* @param {String} name Name of the app, has to match the name of the application.
|
|
41
|
-
* @param {Object} [data={}] Server data that will be available in the app.
|
|
42
|
-
* In Vue it will be available in the `$options` object.
|
|
43
|
-
* @param {Object} [settings={}] Settings object.
|
|
44
|
-
* @param {String} [settings.noScript=''] HTML that will be rendered when JavaScript
|
|
45
|
-
* is not available.
|
|
46
|
-
* @param {String} [settings.selector=`[data-portlet-id="${portletId}"]`] Query selector for
|
|
47
|
-
* where the app should be mounted.
|
|
48
|
-
* @param {Boolean} [settings.async=true] If the app script should be loaded asynchronously.
|
|
49
|
-
* [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
|
|
50
|
-
* @param {Boolean} [settings.defer=false] If the app script should be loaded after DOM is ready.
|
|
51
|
-
* [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
|
|
52
|
-
* @returns {String} HTML for rendering an application.
|
|
53
|
-
*/
|
|
54
|
-
export function renderApp(name, data, ref) {
|
|
55
|
-
if ( ref === void 0 ) ref = {};
|
|
56
|
-
var noScript = ref.noScript; if ( noScript === void 0 ) noScript = '';
|
|
57
|
-
var selector = ref.selector; if ( selector === void 0 ) selector = "[data-portlet-id=\"" + portletId + "\"]";
|
|
58
|
-
var async = ref.async; if ( async === void 0 ) async = true;
|
|
59
|
-
var defer = ref.defer; if ( defer === void 0 ) defer = false;
|
|
60
|
-
|
|
61
|
-
var options = Object.assign({}, data, {isOffline: isOffline});
|
|
62
|
-
var clientUri = getResourceUri('client/index.js');
|
|
63
|
-
|
|
64
|
-
if (isOffline) {
|
|
65
|
-
return ("\n<!-- Generated by WebappUtil.renderApp() -->\n<div data-portlet-id=\"" + portletId + "\">" + noScript + "</div>\n<script src=\"" + clientUri + "?" + (appInfo.appImportDate) + "\"></script>\n<script> \n Soleil.webapps['" + name + "'].render('" + name + "', '" + selector + "', " + (JSON.stringify(options)) + ");\n</script>\n");
|
|
66
|
-
}
|
|
67
|
-
return ("\n<!-- Generated by WebappUtil.renderApp() -->\n<div data-portlet-id=\"" + portletId + "\">" + noScript + "</div>\n<script>\n function renderApp" + portletId + "() {\n Soleil.webapps['" + name + "'].render('" + name + "', '" + selector + "', " + (JSON.stringify(options)) + ");\n } \n</script>\n<script src=\"" + clientUri + "?" + (appInfo.appImportDate) + "\" " + (async && !defer ? 'async' : '') + " " + (defer ? 'defer' : '') + " onload=\"renderApp" + portletId + "();\"></script>\n");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Get URI for a route.
|
|
72
|
-
* @param {String} route A route.
|
|
73
|
-
* @returns {String} URI for route.
|
|
74
|
-
*/
|
|
75
|
-
export function getRouteUri(route) {
|
|
76
|
-
var currentPageId = PortletContextUtil.getCurrentPage().getIdentifier().replace('_sitePage', '');
|
|
77
|
-
var currentPortletId = PortletContextUtil.getCurrentPortlet().getIdentifier();
|
|
78
|
-
return ("/appresource/" + currentPageId + "/" + currentPortletId + "/" + route).replace(/\/\//g, '/');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default {
|
|
82
|
-
getRouteUri: getRouteUri,
|
|
83
|
-
getResourceUri: getResourceUri,
|
|
84
|
-
renderApp: renderApp,
|
|
85
|
-
renderTemplate: renderTemplate,
|
|
86
|
-
isOffline: isOffline,
|
|
87
|
-
};
|
package/render-vue/src/.eslintrc
DELETED
package/render-vue/src/index.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* eslint-disable-next-line import/no-unresolved */
|
|
2
|
-
import Vue from 'vue';
|
|
3
|
-
|
|
4
|
-
window.Soleil = window.Soleil || {};
|
|
5
|
-
window.Soleil.webapps = window.Soleil.webapps || {};
|
|
6
|
-
|
|
7
|
-
const offlineModeMixin = {
|
|
8
|
-
mounted() {
|
|
9
|
-
if (this.$options.isOffline) {
|
|
10
|
-
const $anchors = this.$el.querySelectorAll('a');
|
|
11
|
-
$anchors.forEach(($anchor) => {
|
|
12
|
-
$anchor.addEventListener('click', (e) => {
|
|
13
|
-
e.preventDefault();
|
|
14
|
-
window.$svjq($anchor).trigger('click');
|
|
15
|
-
}, false);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Render a Vue application
|
|
22
|
-
* @param {String} name Name of the application, has to match both on server and client.
|
|
23
|
-
* @param {String} selector Selector for element where the app should be mounted.
|
|
24
|
-
* @param {Object} [options={}] Options for `$options`.
|
|
25
|
-
*/
|
|
26
|
-
export default function render(name, selector, options = {}) {
|
|
27
|
-
const {
|
|
28
|
-
App,
|
|
29
|
-
} = window.Soleil.webapps[name];
|
|
30
|
-
Object.assign(App, options, {
|
|
31
|
-
mixins: [offlineModeMixin],
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const mountElementExists = !!document.querySelector(selector);
|
|
35
|
-
if (mountElementExists) {
|
|
36
|
-
new Vue(App).$mount(selector);
|
|
37
|
-
} else {
|
|
38
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
39
|
-
new Vue(App).$mount(selector);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|