@soleil-se/app-util 2.1.4 → 2.3.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 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
+ ## [2.3.0] - 2020-05-22
8
+ ### Added
9
+ - `renderApp` now accepts `req` as a setting to opimize script loading when multiple instances of the app exists. If `req` is present the script will only be loaded once in all browsers except IE11 that needs a unique script src for the currentScript polyfill to work.
10
+
11
+ ### Fixed
12
+ - ´noScript` in `renderApp` was not wrapped in a `<noscript>` tag.
13
+
14
+ ## [2.2.0] - 2020-05-20
15
+ ### Added
16
+ - `renderTemplate` function is now available inside templates rendered by the function.
7
17
  ## [2.1.4] - 2020-04-07
8
18
  ### Fixed
9
19
  - `getViewUri` had incorrect portlet ID.
package/README.md CHANGED
@@ -33,6 +33,7 @@ Can be used together with `@soleil-se/webapp-util/render-vue` or a custom render
33
33
  | [settings.selector] | <code>String</code> | <code>&#x60;[data-portlet-id&#x3D;&quot;${portletId}&quot;]&#x60;</code> | Query selector for where the app should be mounted. |
34
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
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
+ | [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. |
36
37
 
37
38
  #### Example
38
39
  In `app_src/server/index.js`.
@@ -48,6 +49,7 @@ router.get('/', (req, res) => {
48
49
  selector: '#mount_me_here',
49
50
  async: false,
50
51
  defer: true,
52
+ req,
51
53
  }));
52
54
  });
53
55
  ```
@@ -123,7 +125,8 @@ Get URI for a resource.
123
125
  const resourceUri = getResourceUri('file/in/resource.png');
124
126
  ```
125
127
  ### `renderTemplate(template, [values])` ⇒ `String`
126
- Renders a Underscore template and returns a string.
128
+ Renders a Underscore template and returns a string.
129
+ This function is also available inside the template.
127
130
 
128
131
  **Returns**: `String` - Rendered template
129
132
 
@@ -133,11 +136,38 @@ Renders a Underscore template and returns a string.
133
136
  | [values] | `Object` | `{}` | Values. |
134
137
 
135
138
  #### Example
139
+ **Simple example**
136
140
  ```javascript
137
141
  const string = renderTemplate('<div><%= foo %></div>', {
138
142
  foo: 'bar',
139
143
  });
140
144
  ```
145
+ **Multiple templates**
146
+ ```html
147
+ /* views/item.html */
148
+ <li>
149
+ <%- name %>
150
+ </li>
151
+ ```
152
+ ```html
153
+ /* views/main.html */
154
+ <ul>
155
+ <% items.forEach(function(item) { %>
156
+ <%= renderTemplate(itemTemplate, item) %>
157
+ <% }); %>
158
+ </ul>
159
+ ```
160
+
161
+ ```javascript
162
+ import { renderTemplate } from '@soleil-se/webapp-util';
163
+ import mainTemplate from './views/main.html';
164
+ import itemTemplate from './views/item.html';
165
+
166
+ const items = [{ name: 'Foo' }, { name: 'Bar' }, { name: 'Baz' }];
167
+ const string = renderTemplate(mainTemplate, { items, itemTemplate });
168
+ ```
169
+ > **NOTE**
170
+ > Remember that the second argument must be an object and that objects properties are accessed directly in any child templates!
141
171
  ### `isOffline`
142
172
  If the webapp is running in offline mode or not.
143
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleil-se/app-util",
3
- "version": "2.1.4",
3
+ "version": "2.3.0",
4
4
  "description": "Utility functions for Webapps.",
5
5
  "main": "./src/index.js",
6
6
  "author": "Soleil AB",
package/src/index.js CHANGED
@@ -2,6 +2,7 @@ import PortletContextUtil from 'PortletContextUtil';
2
2
  import PropertyUtil from 'PropertyUtil';
3
3
  import VersionUtil from 'VersionUtil';
4
4
  import appInfo from 'appInfo';
5
+
5
6
  /* Underscore is provided by SiteVision */
6
7
  /* eslint-disable-next-line import/no-extraneous-dependencies */
7
8
  import _ from 'underscore';
@@ -31,9 +32,9 @@ export function getResourceUri(resource) {
31
32
  */
32
33
  export function renderTemplate(template, values = {}) {
33
34
  if (typeof template === 'function') {
34
- return template(values);
35
+ return template({ ...values, renderTemplate });
35
36
  }
36
- return _.template(template)(values);
37
+ return _.template(template)(({ ...values, renderTemplate }));
37
38
  }
38
39
 
39
40
  /**
@@ -49,6 +50,8 @@ export function renderTemplate(template, values = {}) {
49
50
  * [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
50
51
  * @param {Boolean} [settings.defer=true] If the app script should be loaded after DOM is ready.
51
52
  * [Read more about async and defer.](https://flaviocopes.com/javascript-async-defer/)
53
+ * @param {Object} [settings.req] The req object from SiteVision, pass this to optimize browser
54
+ * specific script loading if you have multiple instances of the app.
52
55
  * @returns {String} HTML for rendering an application.
53
56
  */
54
57
  export function renderApp(data, {
@@ -56,10 +59,18 @@ export function renderApp(data, {
56
59
  selector = `[data-portlet-id="${portletId}"]`,
57
60
  async = false,
58
61
  defer = true,
62
+ req,
59
63
  } = {}) {
60
64
  if (typeof data === 'string') {
61
65
  throw new Error('As of version 2 renderApp no longer needs the application name.');
62
66
  }
67
+
68
+ const isIE = () => {
69
+ if (!req) return true;
70
+ const userAgent = req.header('user-agent');
71
+ return /Trident\/|MSIE/.test(userAgent);
72
+ };
73
+
63
74
  if (isOffline) {
64
75
  return `
65
76
  <div data-portlet-id="${portletId}">${noScript}</div>
@@ -75,9 +86,9 @@ export function renderApp(data, {
75
86
  </script>`;
76
87
  }
77
88
  return `
78
- <div data-portlet-id="${portletId}">${noScript}</div>
89
+ <div data-portlet-id="${portletId}"><noscript>${noScript}</noscript></div>
79
90
  <script
80
- src="${getResourceUri('client/index.js')}?${appInfo.appImportDate}${portletId.replace('_', '')}"
91
+ src="${getResourceUri('client/index.js')}?${appInfo.appImportDate}${isIE() ? portletId.replace('_', '') : ''}"
81
92
  data-app="${encodeURIComponent(JSON.stringify({ ...data, isOffline }))}"
82
93
  data-selector="${encodeURIComponent(selector)}"
83
94
  ${async && !defer ? 'async' : ''}