@teipublisher/pb-components 2.6.1 → 2.8.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 +31 -0
- package/dist/pb-components-bundle.js +197 -197
- package/dist/pb-elements.json +63 -21
- package/package.json +2 -1
- package/pb-elements.json +63 -21
- package/src/pb-browse-docs.js +2 -0
- package/src/pb-custom-form.js +17 -1
- package/src/pb-link.js +13 -3
- package/src/pb-load.js +5 -0
- package/src/pb-page.js +28 -1
- package/src/pb-popover.js +398 -390
- package/src/pb-split-list.js +4 -1
- package/src/pb-view.js +37 -14
- package/src/urls.js +93 -15
package/src/pb-split-list.js
CHANGED
|
@@ -131,7 +131,10 @@ export class PbSplitList extends themableMixin(pbMixin(LitElement)) {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
load() {
|
|
134
|
-
const formParams = this._paramsFromSubforms({
|
|
134
|
+
const formParams = this._paramsFromSubforms({});
|
|
135
|
+
if (this.selected) {
|
|
136
|
+
formParams.category = this.selected;
|
|
137
|
+
}
|
|
135
138
|
if (!this._initialized) {
|
|
136
139
|
registry.replace(this, formParams);
|
|
137
140
|
} else {
|
package/src/pb-view.js
CHANGED
|
@@ -321,6 +321,9 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
321
321
|
type: Node,
|
|
322
322
|
attribute: false
|
|
323
323
|
},
|
|
324
|
+
_additionalParams: {
|
|
325
|
+
type: Object
|
|
326
|
+
},
|
|
324
327
|
...super.properties
|
|
325
328
|
};
|
|
326
329
|
}
|
|
@@ -341,6 +344,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
341
344
|
this.beforeUpdate = null;
|
|
342
345
|
this.noScroll = false;
|
|
343
346
|
this._features = {};
|
|
347
|
+
this._additionalParams = {};
|
|
344
348
|
this._selector = {};
|
|
345
349
|
this._chunks = [];
|
|
346
350
|
this._scrollTarget = null;
|
|
@@ -436,8 +440,8 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
436
440
|
this.signalReady();
|
|
437
441
|
|
|
438
442
|
if (this.onUpdate) {
|
|
439
|
-
this.subscribeTo('pb-update', () => {
|
|
440
|
-
this._refresh();
|
|
443
|
+
this.subscribeTo('pb-update', (ev) => {
|
|
444
|
+
this._refresh(ev);
|
|
441
445
|
});
|
|
442
446
|
}
|
|
443
447
|
}
|
|
@@ -587,6 +591,13 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
587
591
|
} else {
|
|
588
592
|
this.nodeId = ev.detail.root || this.nodeId;
|
|
589
593
|
}
|
|
594
|
+
|
|
595
|
+
// check if the URL template needs any other parameters
|
|
596
|
+
// and set them on this._additionalParams
|
|
597
|
+
registry.pathParams.forEach((key) => {
|
|
598
|
+
this._additionalParams[key] = ev.detail[key];
|
|
599
|
+
});
|
|
600
|
+
|
|
590
601
|
if (!this.noScroll) {
|
|
591
602
|
this._scrollTarget = ev.detail.hash;
|
|
592
603
|
}
|
|
@@ -994,6 +1005,12 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
994
1005
|
for (const [key, value] of Object.entries(this._features)) {
|
|
995
1006
|
params['user.' + key] = value;
|
|
996
1007
|
}
|
|
1008
|
+
// add parameters for user-defined parameters supplied via pb-link
|
|
1009
|
+
if (this._additionalParams) {
|
|
1010
|
+
for (const [key, value] of Object.entries(this._additionalParams)) {
|
|
1011
|
+
params[key] = value;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
997
1014
|
return params;
|
|
998
1015
|
}
|
|
999
1016
|
|
|
@@ -1162,18 +1179,24 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
1162
1179
|
|
|
1163
1180
|
_setState(properties) {
|
|
1164
1181
|
for (const [key, value] of Object.entries(properties)) {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1182
|
+
// check if URL template needs the parameter and if
|
|
1183
|
+
// yes, add it to the additional parameter list
|
|
1184
|
+
if (registry.pathParams.has(key)) {
|
|
1185
|
+
this._additionalParams[key] = value;
|
|
1186
|
+
} else {
|
|
1187
|
+
switch (key) {
|
|
1188
|
+
case 'odd':
|
|
1189
|
+
case 'view':
|
|
1190
|
+
case 'columnSeparator':
|
|
1191
|
+
case 'xpath':
|
|
1192
|
+
case 'nodeId':
|
|
1193
|
+
case 'path':
|
|
1194
|
+
case 'root':
|
|
1195
|
+
break;
|
|
1196
|
+
default:
|
|
1197
|
+
this._features[key] = value;
|
|
1198
|
+
break;
|
|
1199
|
+
}
|
|
1177
1200
|
}
|
|
1178
1201
|
}
|
|
1179
1202
|
if (properties.odd && !this.getAttribute('odd')) {
|
package/src/urls.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { match, compile, pathToRegexp } from "path-to-regexp";
|
|
1
2
|
import { PbEvents } from "./pb-events.js";
|
|
2
3
|
import { getSubscribedChannels } from "./pb-mixin.js";
|
|
3
4
|
|
|
@@ -60,12 +61,34 @@ class Registry {
|
|
|
60
61
|
*/
|
|
61
62
|
this.idHash = true;
|
|
62
63
|
this._listeners = [];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* URL pattern to use for mapping parameters into the URL path
|
|
67
|
+
*/
|
|
68
|
+
this.urlPattern = null;
|
|
69
|
+
|
|
70
|
+
this.urlIgnore = new Set();
|
|
71
|
+
this.pathParams = new Set();
|
|
63
72
|
}
|
|
64
73
|
|
|
65
|
-
configure(usePath = true, idHash = false, rootPath = '') {
|
|
74
|
+
configure(usePath = true, idHash = false, rootPath = '', urlPattern, ignoredParams) {
|
|
66
75
|
this.rootPath = rootPath;
|
|
67
76
|
this.usePath = usePath;
|
|
68
77
|
this.idHash = idHash;
|
|
78
|
+
this.urlPattern = urlPattern;
|
|
79
|
+
if (ignoredParams) {
|
|
80
|
+
ignoredParams.split(/\s*,\s*/).forEach(param => this.urlIgnore.add(param));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (this.urlPattern) {
|
|
84
|
+
// save a list of parameter names which go into the path
|
|
85
|
+
const pathParams = [];
|
|
86
|
+
pathToRegexp(this.urlPattern, pathParams);
|
|
87
|
+
pathParams.forEach((param) => this.pathParams.add(param.name));
|
|
88
|
+
// compile URL pattern into a decode and encode function
|
|
89
|
+
this._decodePath = match(this.urlPattern);
|
|
90
|
+
this._encodePath = compile(this.urlPattern);
|
|
91
|
+
}
|
|
69
92
|
|
|
70
93
|
// determine initial state of the registry by parsing current URL
|
|
71
94
|
const initialState = this._stateFromURL();
|
|
@@ -115,16 +138,35 @@ class Registry {
|
|
|
115
138
|
if (this.idHash && this.hash.length > 0 && (!/^#\d+\./.test(this.hash))) {
|
|
116
139
|
params.id = this.hash.substring(1);
|
|
117
140
|
}
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
const relpath = window.location.pathname.replace(new RegExp(`^${this.rootPath}/?`), '');
|
|
142
|
+
if (this.urlPattern) {
|
|
143
|
+
const result = this._decodePath(relpath);
|
|
144
|
+
Object.assign(params, result.params);
|
|
145
|
+
log('decoded path %s using template %s: %o', relpath, this.urlPattern, params);
|
|
146
|
+
} else if (this.usePath) {
|
|
147
|
+
params.path = relpath;
|
|
120
148
|
}
|
|
149
|
+
|
|
121
150
|
const urlParams = new URLSearchParams(window.location.search);
|
|
122
151
|
urlParams.forEach((value, key) => {
|
|
123
|
-
if (
|
|
152
|
+
if (
|
|
153
|
+
(this.urlPattern && this.pathParams.has(key)) ||
|
|
154
|
+
(this.usePath && key === 'path')
|
|
155
|
+
) {
|
|
124
156
|
console.warn("Found path parameter in query, but usePath is set to true. The path parameter will be ignored.");
|
|
125
157
|
return;
|
|
126
158
|
}
|
|
127
|
-
|
|
159
|
+
// parameter already set
|
|
160
|
+
if ((key in params)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// check for multiple entries
|
|
164
|
+
const allValues = urlParams.getAll(key);
|
|
165
|
+
if (allValues.length === 1) {
|
|
166
|
+
params[key] = value; // single entry
|
|
167
|
+
} else {
|
|
168
|
+
params[key] = allValues; // array
|
|
169
|
+
}
|
|
128
170
|
});
|
|
129
171
|
return params;
|
|
130
172
|
}
|
|
@@ -196,7 +238,7 @@ class Registry {
|
|
|
196
238
|
}
|
|
197
239
|
|
|
198
240
|
_commit(elem, newState, overwrite, replace) {
|
|
199
|
-
this.state = overwrite ? newState :
|
|
241
|
+
this.state = overwrite ? newState : ({ ...this.state, ...newState});
|
|
200
242
|
const resolved = this.urlFromState();
|
|
201
243
|
|
|
202
244
|
const chs = getSubscribedChannels(elem);
|
|
@@ -220,22 +262,58 @@ class Registry {
|
|
|
220
262
|
|
|
221
263
|
urlFromState() {
|
|
222
264
|
const newUrl = new URL(window.location.href);
|
|
265
|
+
|
|
266
|
+
function setParam(value, param) {
|
|
267
|
+
if (value === null) {
|
|
268
|
+
newUrl.searchParams.delete(param);
|
|
269
|
+
} else if (Array.isArray(value)) {
|
|
270
|
+
// copy array before mutating it
|
|
271
|
+
const _v = Array.from(value);
|
|
272
|
+
// overwrite any previous value by setting the first member
|
|
273
|
+
newUrl.searchParams.set(param, _v.pop());
|
|
274
|
+
// add additional values
|
|
275
|
+
_v.forEach(v => newUrl.searchParams.append(param, v));
|
|
276
|
+
} else {
|
|
277
|
+
newUrl.searchParams.set(param, value);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
223
281
|
for (const [param, value] of Object.entries(this.state)) {
|
|
224
|
-
if (
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
282
|
+
if (this.urlPattern) {
|
|
283
|
+
// check if param should be ignored or is required by the URL template
|
|
284
|
+
// fill up missing parameters by stripping potential "user." prefix
|
|
285
|
+
const normParam = param.replace(/^(?:user\.)?(.*)$/, '$1');
|
|
286
|
+
if (!(this.pathParams.has(normParam) || this.urlIgnore.has(normParam))) {
|
|
287
|
+
setParam(value, normParam);
|
|
230
288
|
}
|
|
289
|
+
} else if (
|
|
290
|
+
(param !== 'path' || !this.usePath) &&
|
|
291
|
+
(param !== 'id' || !this.idHash) &&
|
|
292
|
+
(!this.urlIgnore.has(param))
|
|
293
|
+
) {
|
|
294
|
+
setParam(value, param);
|
|
231
295
|
}
|
|
232
296
|
}
|
|
233
297
|
|
|
234
|
-
if (this.
|
|
235
|
-
|
|
298
|
+
if (this.state.path && this.state.path.length > 0) {
|
|
299
|
+
if (this.urlPattern) {
|
|
300
|
+
// path parameters should not be the empty string
|
|
301
|
+
const normState = {};
|
|
302
|
+
for (const [key, value] of Object.entries(this.state)) {
|
|
303
|
+
if (this.pathParams.has(key) && value === '') {
|
|
304
|
+
normState[key] = null;
|
|
305
|
+
} else {
|
|
306
|
+
normState[key] = value;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const encoded = this._encodePath(normState);
|
|
310
|
+
newUrl.pathname = `${this.rootPath}/${encoded}`;
|
|
311
|
+
} else if (this.usePath) {
|
|
312
|
+
newUrl.pathname = `${this.rootPath}/${this.state.path}`;
|
|
313
|
+
}
|
|
236
314
|
}
|
|
237
315
|
|
|
238
|
-
if (this.state.id) {
|
|
316
|
+
if (this.state.id && !this.urlPattern) {
|
|
239
317
|
newUrl.hash = `#${this.state.id}`;
|
|
240
318
|
}
|
|
241
319
|
|