saasufy-components 1.1.1 → 1.2.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/app-router.js +1 -1
- package/collection-browser.js +4 -1
- package/model-input.js +3 -3
- package/model-text.js +3 -3
- package/package.json +2 -1
- package/socket.js +2 -7
- package/utils.js +30 -17
package/app-router.js
CHANGED
package/collection-browser.js
CHANGED
|
@@ -155,7 +155,10 @@ class CollectionBrowser extends SocketConsumer {
|
|
|
155
155
|
let items = [];
|
|
156
156
|
|
|
157
157
|
for (let modelItem of this.collection.value) {
|
|
158
|
-
let itemString = renderTemplate(
|
|
158
|
+
let itemString = renderTemplate(
|
|
159
|
+
itemTemplate.innerHTML,
|
|
160
|
+
{ [this.collection.type]: modelItem }
|
|
161
|
+
);
|
|
159
162
|
items.push(itemString);
|
|
160
163
|
}
|
|
161
164
|
let noItemTemplate = this.shadowRoot.querySelector('slot[name="no-item"]').assignedNodes()[0];
|
package/model-input.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SocketConsumer } from './socket.js';
|
|
2
|
-
import {
|
|
2
|
+
import { debouncer } from './utils.js';
|
|
3
3
|
import AGModel from '/node_modules/ag-model/ag-model.js';
|
|
4
4
|
|
|
5
5
|
class ModelInput extends SocketConsumer {
|
|
@@ -166,7 +166,7 @@ class ModelInput extends SocketConsumer {
|
|
|
166
166
|
|
|
167
167
|
syncInputElementWithModel(inputElement, model, fieldName, messageContainerElement) {
|
|
168
168
|
if (model.isLoaded) {
|
|
169
|
-
let fieldValue =
|
|
169
|
+
let fieldValue = model.value[fieldName];
|
|
170
170
|
if (inputElement.type === 'checkbox') {
|
|
171
171
|
inputElement.checked = !!fieldValue;
|
|
172
172
|
} else {
|
|
@@ -178,7 +178,7 @@ class ModelInput extends SocketConsumer {
|
|
|
178
178
|
(async () => {
|
|
179
179
|
for await (let event of changeConsumer) {
|
|
180
180
|
if (event.resourceField !== fieldName || !event.isRemote) continue;
|
|
181
|
-
let fieldValue =
|
|
181
|
+
let fieldValue = model.value[fieldName];
|
|
182
182
|
if (inputElement.type === 'checkbox') {
|
|
183
183
|
inputElement.checked = fieldValue;
|
|
184
184
|
} else {
|
package/model-text.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SocketConsumer } from './socket.js';
|
|
2
|
-
import {
|
|
2
|
+
import { toSafeHTML } from './utils.js';
|
|
3
3
|
import AGModel from '/node_modules/ag-model/ag-model.js';
|
|
4
4
|
|
|
5
5
|
class ModelText extends SocketConsumer {
|
|
@@ -79,12 +79,12 @@ class ModelText extends SocketConsumer {
|
|
|
79
79
|
(async () => {
|
|
80
80
|
for await (let event of changeConsumer) {
|
|
81
81
|
if (event.resourceField !== modelField || !event.isRemote) continue;
|
|
82
|
-
let fieldValue =
|
|
82
|
+
let fieldValue = toSafeHTML(model.value[modelField]);
|
|
83
83
|
this.innerHTML = fieldValue;
|
|
84
84
|
}
|
|
85
85
|
})();
|
|
86
86
|
if (model.isLoaded) {
|
|
87
|
-
this.innerHTML =
|
|
87
|
+
this.innerHTML = toSafeHTML(model.value[modelField]);
|
|
88
88
|
}
|
|
89
89
|
this.destroy = () => {
|
|
90
90
|
changeConsumer.kill();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "saasufy-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Components for Saasufy.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"ag-collection": "^3.2.1",
|
|
21
21
|
"ag-model": "^1.3.6",
|
|
22
|
+
"expr-eval": "^2.0.2",
|
|
22
23
|
"socketcluster-client": "^19.0.2"
|
|
23
24
|
},
|
|
24
25
|
"bugs": {
|
package/socket.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { create } from '/node_modules/socketcluster-client/socketcluster-client.min.js';
|
|
2
2
|
|
|
3
|
-
const DEFAULT_AUTH_TOKEN_NAME = 'saasufy.authToken';
|
|
4
|
-
|
|
5
3
|
let globalSocket;
|
|
6
4
|
|
|
7
5
|
let urlPartsRegExp = /(^[^:]+):\/\/([^:\/]*)(:[0-9]*)?(\/.*)/;
|
|
8
6
|
|
|
9
7
|
export function createGlobalSocket(options) {
|
|
10
|
-
globalSocket = create({
|
|
11
|
-
authTokenName: DEFAULT_AUTH_TOKEN_NAME,
|
|
12
|
-
...options
|
|
13
|
-
});
|
|
8
|
+
globalSocket = create({ ...options });
|
|
14
9
|
return globalSocket;
|
|
15
10
|
}
|
|
16
11
|
|
|
@@ -64,7 +59,7 @@ export class SocketProvider extends HTMLElement {
|
|
|
64
59
|
}
|
|
65
60
|
|
|
66
61
|
createSocket() {
|
|
67
|
-
let authTokenName = this.getAttribute('auth-token-name') ||
|
|
62
|
+
let authTokenName = this.getAttribute('auth-token-name') || null;
|
|
68
63
|
let url = this.getAttribute('url') || '';
|
|
69
64
|
let urlOptions;
|
|
70
65
|
let matchedList = url.match(urlPartsRegExp);
|
package/utils.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import AGCollection from '/node_modules/ag-collection/ag-collection.js';
|
|
2
2
|
import AGModel from '/node_modules/ag-model/ag-model.js';
|
|
3
|
+
import { Parser } from '/node_modules/expr-eval/dist/index.mjs';
|
|
3
4
|
|
|
4
5
|
const DEFAULT_DEBOUNCE_DELAY = 300;
|
|
5
6
|
const DEFAULT_RELOAD_DELAY = 0;
|
|
6
7
|
|
|
7
|
-
export function
|
|
8
|
+
export function toSafeHTML(text) {
|
|
8
9
|
if (typeof text === 'string') {
|
|
9
10
|
return text.replace(/&/g, '&')
|
|
10
11
|
.replace(/</g, '<')
|
|
@@ -29,10 +30,10 @@ export function debouncer() {
|
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
export function
|
|
33
|
+
export function toSafeModelValue(value) {
|
|
33
34
|
return Object.fromEntries(
|
|
34
35
|
Object.entries(value || {}).map(
|
|
35
|
-
([key, value]) => [ key,
|
|
36
|
+
([key, value]) => [ key, toSafeHTML(value) ]
|
|
36
37
|
)
|
|
37
38
|
);
|
|
38
39
|
}
|
|
@@ -60,7 +61,7 @@ export function createReactiveCollection(collectionOptions, callback) {
|
|
|
60
61
|
|
|
61
62
|
if (!collection.isLoaded) continue;
|
|
62
63
|
|
|
63
|
-
collection.safeValue = collection.value.map(
|
|
64
|
+
collection.safeValue = collection.value.map(toSafeModelValue);
|
|
64
65
|
|
|
65
66
|
callback({
|
|
66
67
|
changes
|
|
@@ -102,7 +103,7 @@ export function createReactiveModel(modelOptions, callback) {
|
|
|
102
103
|
changes[event.resourceField] = event.isRemote;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
model.safeValue =
|
|
106
|
+
model.safeValue = toSafeModelValue(model.value);
|
|
106
107
|
callback({
|
|
107
108
|
changes
|
|
108
109
|
});
|
|
@@ -128,7 +129,7 @@ export function createCollection(collectionOptions) {
|
|
|
128
129
|
(async () => {
|
|
129
130
|
for await (let event of collection.listener('change')) {
|
|
130
131
|
if (!collection.isLoaded) continue;
|
|
131
|
-
collection.safeValue = collection.value.map(
|
|
132
|
+
collection.safeValue = collection.value.map(toSafeModelValue);
|
|
132
133
|
}
|
|
133
134
|
})();
|
|
134
135
|
|
|
@@ -148,7 +149,7 @@ export function createModel(modelOptions) {
|
|
|
148
149
|
|
|
149
150
|
(async () => {
|
|
150
151
|
for await (let event of model.listener('change')) {
|
|
151
|
-
model.safeValue =
|
|
152
|
+
model.safeValue = toSafeModelValue(model.value);
|
|
152
153
|
}
|
|
153
154
|
})();
|
|
154
155
|
|
|
@@ -162,20 +163,32 @@ let templateFormatters = {
|
|
|
162
163
|
capitalize: (value) => {
|
|
163
164
|
let valueString = String(value);
|
|
164
165
|
return `${valueString.slice(0, 1).toUpperCase()}${valueString.slice(1)}`;
|
|
166
|
+
},
|
|
167
|
+
fallback: (...args) => {
|
|
168
|
+
return args.filter(arg => arg)[0];
|
|
165
169
|
}
|
|
166
170
|
};
|
|
167
171
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
let templateTagsRegExp = /{{[^}]+}}/g;
|
|
173
|
+
|
|
174
|
+
export function renderTemplate(templateString, data) {
|
|
175
|
+
return templateString.replace(templateTagsRegExp, (match) => {
|
|
176
|
+
let expString = match.slice(2, -2);
|
|
177
|
+
let options = {
|
|
178
|
+
...templateFormatters,
|
|
179
|
+
...data
|
|
180
|
+
};
|
|
181
|
+
try {
|
|
182
|
+
return toSafeHTML(
|
|
183
|
+
Parser.evaluate(
|
|
184
|
+
expString,
|
|
185
|
+
options
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
return match;
|
|
174
190
|
}
|
|
175
|
-
|
|
176
|
-
templateString = templateString.replace(regExp, safeValue);
|
|
177
|
-
}
|
|
178
|
-
return templateString;
|
|
191
|
+
});
|
|
179
192
|
}
|
|
180
193
|
|
|
181
194
|
export function wait(duration) {
|