@teipublisher/pb-components 2.7.0 → 2.9.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.
@@ -111,7 +111,10 @@
111
111
  "reset": "Obnovit",
112
112
  "placeholder": "Zadejte dotaz",
113
113
  "sections": "Hledat v oddílech",
114
- "headings": "Hledat v nadpisech"
114
+ "headings": "Hledat v nadpisech",
115
+ "title": "Titul",
116
+ "content": "Text",
117
+ "scope": "Omezit hledání na"
115
118
  },
116
119
  "dts": {
117
120
  "endpoint": "Vybrat koncový bod",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teipublisher/pb-components",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "Collection of webcomponents underlying TEI Publisher",
5
5
  "repository": "https://github.com/eeditiones/tei-publisher-components.git",
6
6
  "main": "index.html",
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@babel/runtime": "7.11.2",
40
40
  "@cwmr/paper-autocomplete": "^4.0.0",
41
- "@jinntec/jinn-codemirror": "^1.11.6",
41
+ "@jinntec/jinn-codemirror": "^1.13.4",
42
42
  "@lrnwebcomponents/es-global-bridge": "^2.7.10",
43
43
  "@polymer/app-layout": "^3.1.0",
44
44
  "@polymer/iron-ajax": "^3.0.1",
@@ -85,6 +85,7 @@
85
85
  "pagedjs": "^0.4.0",
86
86
  "path-to-regexp": "^6.2.1",
87
87
  "prismjs": "^1.21.0",
88
+ "tify": "^0.28.1",
88
89
  "tippy.js": "^6.2.7",
89
90
  "tom-select": "^2.0.2",
90
91
  "uniqolor": "^1.0.1",
package/pb-elements.json CHANGED
@@ -3944,7 +3944,7 @@
3944
3944
  "name": "wait-for",
3945
3945
  "description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
3946
3946
  "type": "string",
3947
- "default": "\"pb-facsimile,pb-image-strip\""
3947
+ "default": "\"pb-facsimile,pb-image-strip,pb-tify\""
3948
3948
  },
3949
3949
  {
3950
3950
  "name": "disabled",
@@ -4025,7 +4025,7 @@
4025
4025
  "attribute": "wait-for",
4026
4026
  "description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
4027
4027
  "type": "string",
4028
- "default": "\"pb-facsimile,pb-image-strip\""
4028
+ "default": "\"pb-facsimile,pb-image-strip,pb-tify\""
4029
4029
  },
4030
4030
  {
4031
4031
  "name": "disabled",
@@ -5624,7 +5624,7 @@
5624
5624
  {
5625
5625
  "name": "pb-link",
5626
5626
  "path": "./src/pb-link.js",
5627
- "description": "Create an internal link: clicking it will cause connected views to\nupdate and load the corresponding document fragment defined by the\nproperties.",
5627
+ "description": "Create an internal link: clicking it will emit a `pb-refresh`event, \ncausing connected views to update and load the corresponding document fragment defined by the\nproperties.",
5628
5628
  "attributes": [
5629
5629
  {
5630
5630
  "name": "xml-id",
@@ -5657,10 +5657,15 @@
5657
5657
  },
5658
5658
  {
5659
5659
  "name": "history",
5660
- "description": "Modify browser history: if set, clicking this\nelement will generate a new history entry in the browser's history.\nOnly use this on one element on the page.",
5660
+ "description": "Modify browser history: if set, clicking this\nelement will generate a new history entry in the browser's history.",
5661
5661
  "type": "boolean",
5662
5662
  "default": "true"
5663
5663
  },
5664
+ {
5665
+ "name": "params",
5666
+ "description": "Additional parameters to be passed in the event details.\nShould be specified as a JSON object.",
5667
+ "type": "object"
5668
+ },
5664
5669
  {
5665
5670
  "name": "subscribe",
5666
5671
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -5732,10 +5737,16 @@
5732
5737
  {
5733
5738
  "name": "history",
5734
5739
  "attribute": "history",
5735
- "description": "Modify browser history: if set, clicking this\nelement will generate a new history entry in the browser's history.\nOnly use this on one element on the page.",
5740
+ "description": "Modify browser history: if set, clicking this\nelement will generate a new history entry in the browser's history.",
5736
5741
  "type": "boolean",
5737
5742
  "default": "true"
5738
5743
  },
5744
+ {
5745
+ "name": "params",
5746
+ "attribute": "params",
5747
+ "description": "Additional parameters to be passed in the event details.\nShould be specified as a JSON object.",
5748
+ "type": "object"
5749
+ },
5739
5750
  {
5740
5751
  "name": "subscribe",
5741
5752
  "attribute": "subscribe",
@@ -10760,6 +10771,105 @@
10760
10771
  }
10761
10772
  ]
10762
10773
  },
10774
+ {
10775
+ "name": "pb-tify",
10776
+ "path": "./src/pb-tify.js",
10777
+ "description": "Viewer for IIIF presentation manifests based on https://tify.rocks/.\nRequires a proper manifest listing the resources to show. `pb-facs-link`\ncan be used to navigate to a page.",
10778
+ "attributes": [
10779
+ {
10780
+ "name": "manifest",
10781
+ "description": "URL pointing to a IIIF presentation manifest. Relative paths\nare interpreted relative to the API endpoint.",
10782
+ "type": "string"
10783
+ },
10784
+ {
10785
+ "name": "subscribe",
10786
+ "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
10787
+ "type": "string"
10788
+ },
10789
+ {
10790
+ "name": "subscribe-config",
10791
+ "description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
10792
+ "type": "object"
10793
+ },
10794
+ {
10795
+ "name": "emit",
10796
+ "description": "The name of the channel to send events to.",
10797
+ "type": "string"
10798
+ },
10799
+ {
10800
+ "name": "emit-config",
10801
+ "description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
10802
+ "type": "object"
10803
+ },
10804
+ {
10805
+ "name": "wait-for",
10806
+ "description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
10807
+ "type": "string"
10808
+ },
10809
+ {
10810
+ "name": "disabled",
10811
+ "description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
10812
+ "type": "boolean",
10813
+ "default": "false"
10814
+ }
10815
+ ],
10816
+ "properties": [
10817
+ {
10818
+ "name": "manifest",
10819
+ "attribute": "manifest",
10820
+ "description": "URL pointing to a IIIF presentation manifest. Relative paths\nare interpreted relative to the API endpoint.",
10821
+ "type": "string"
10822
+ },
10823
+ {
10824
+ "name": "cssPath",
10825
+ "type": "string",
10826
+ "default": "\"../css/tify\""
10827
+ },
10828
+ {
10829
+ "name": "subscribe",
10830
+ "attribute": "subscribe",
10831
+ "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
10832
+ "type": "string"
10833
+ },
10834
+ {
10835
+ "name": "subscribeConfig",
10836
+ "attribute": "subscribe-config",
10837
+ "description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
10838
+ "type": "object"
10839
+ },
10840
+ {
10841
+ "name": "emit",
10842
+ "attribute": "emit",
10843
+ "description": "The name of the channel to send events to.",
10844
+ "type": "string"
10845
+ },
10846
+ {
10847
+ "name": "emitConfig",
10848
+ "attribute": "emit-config",
10849
+ "description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
10850
+ "type": "object"
10851
+ },
10852
+ {
10853
+ "name": "waitFor",
10854
+ "attribute": "wait-for",
10855
+ "description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
10856
+ "type": "string"
10857
+ },
10858
+ {
10859
+ "name": "disabled",
10860
+ "attribute": "disabled",
10861
+ "description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
10862
+ "type": "boolean",
10863
+ "default": "false"
10864
+ }
10865
+ ],
10866
+ "events": [
10867
+ {
10868
+ "name": "pb-load-facsimile",
10869
+ "description": "when received, opens the page denoted by the\n`order` property in the event (see `pb-facs-link`). Page counts start at 1."
10870
+ }
10871
+ ]
10872
+ },
10763
10873
  {
10764
10874
  "name": "pb-timeline",
10765
10875
  "path": "./src/pb-timeline.js",
@@ -138,6 +138,7 @@ export class Anton extends Registry {
138
138
  case 'organization':
139
139
  register = 'actors';
140
140
  break;
141
+ case 'origPlace':
141
142
  case 'place':
142
143
  register = 'places';
143
144
  break;
@@ -152,4 +153,4 @@ export class Anton extends Registry {
152
153
  }
153
154
  return register;
154
155
  }
155
- }
156
+ }
@@ -47,7 +47,7 @@ export class PbFacsLink extends pbMixin(LitElement) {
47
47
  this.trigger = 'mouseover';
48
48
  this.label = '';
49
49
  this.order = Number.POSITIVE_INFINITY;
50
- this.waitFor = 'pb-facsimile,pb-image-strip';
50
+ this.waitFor = 'pb-facsimile,pb-image-strip,pb-tify';
51
51
  this.default = '';
52
52
  }
53
53
 
@@ -109,6 +109,7 @@ export class PbFacsLink extends pbMixin(LitElement) {
109
109
  this.emitTo('pb-show-annotation', {
110
110
  element: this,
111
111
  file: this.facs,
112
+ order: this.getOrder(),
112
113
  coordinates: this.coordinates
113
114
  });
114
115
  }
package/src/pb-link.js CHANGED
@@ -4,8 +4,8 @@ import { pbMixin } from './pb-mixin.js';
4
4
  import { registry } from "./urls.js";
5
5
 
6
6
  /**
7
- * Create an internal link: clicking it will cause connected views to
8
- * update and load the corresponding document fragment defined by the
7
+ * Create an internal link: clicking it will emit a `pb-refresh`event,
8
+ * causing connected views to update and load the corresponding document fragment defined by the
9
9
  * properties.
10
10
  *
11
11
  * @fires pb-refresh - Fires when user clicks the link
@@ -41,10 +41,16 @@ export class PbLink extends pbMixin(LitElement) {
41
41
  view: {
42
42
  type: String
43
43
  },
44
+ /**
45
+ * Additional parameters to be passed in the event details.
46
+ * Should be specified as a JSON object.
47
+ */
48
+ params: {
49
+ type: Object
50
+ },
44
51
  /**
45
52
  * Modify browser history: if set, clicking this
46
53
  * element will generate a new history entry in the browser's history.
47
- * Only use this on one element on the page.
48
54
  */
49
55
  history: {
50
56
  type: Boolean
@@ -55,6 +61,7 @@ export class PbLink extends pbMixin(LitElement) {
55
61
  constructor() {
56
62
  super();
57
63
  this.history = true;
64
+ this.params = null;
58
65
  }
59
66
 
60
67
  connectedCallback() {
@@ -110,6 +117,9 @@ export class PbLink extends pbMixin(LitElement) {
110
117
  if (this.view) {
111
118
  params.view = this.view;
112
119
  }
120
+ if (this.params) {
121
+ Object.assign(params, this.params);
122
+ }
113
123
  if (this.history) {
114
124
  registry.commit(this, params);
115
125
  }
@@ -131,7 +131,10 @@ export class PbSplitList extends themableMixin(pbMixin(LitElement)) {
131
131
  }
132
132
 
133
133
  load() {
134
- const formParams = this._paramsFromSubforms({ category: this.selected });
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-tify.js ADDED
@@ -0,0 +1,82 @@
1
+ import { LitElement } from 'lit-element';
2
+ import "tify";
3
+ import { pbMixin, waitOnce } from './pb-mixin.js';
4
+ import { resolveURL } from './utils.js';
5
+
6
+ function _injectStylesheet(path) {
7
+ const style = document.querySelector(`link#pb-tify`);
8
+ if (!style) {
9
+ const elem = document.createElement('link');
10
+ elem.type = 'text/css';
11
+ elem.rel = 'stylesheet';
12
+ elem.id = `pb-tify`;
13
+ elem.href = `${resolveURL(path)}/tify.css`;
14
+ document.head.appendChild(elem);
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Viewer for IIIF presentation manifests based on https://tify.rocks/.
20
+ * Requires a proper manifest listing the resources to show. `pb-facs-link`
21
+ * can be used to navigate to a page.
22
+ *
23
+ * @fires pb-load-facsimile - when received, opens the page denoted by the
24
+ * `order` property in the event (see `pb-facs-link`). Page counts start at 1.
25
+ */
26
+ export class PbTify extends pbMixin(LitElement) {
27
+ static get properties() {
28
+ return {
29
+ /**
30
+ * URL pointing to a IIIF presentation manifest. Relative paths
31
+ * are interpreted relative to the API endpoint.
32
+ */
33
+ manifest: {
34
+ type: String
35
+ },
36
+ ...super.properties
37
+ };
38
+ }
39
+
40
+ constructor() {
41
+ super();
42
+ this.cssPath = '../css/tify';
43
+ }
44
+
45
+ async connectedCallback() {
46
+ super.connectedCallback();
47
+
48
+ _injectStylesheet(this.cssPath);
49
+
50
+ this.subscribeTo('pb-load-facsimile', (ev) => {
51
+ if (ev.detail && ev.detail.order && this._tify) {
52
+ console.log('<pb-tify> selecting page %d', ev.detail.order);
53
+ this._tify.setPage(parseInt(ev.detail.order));
54
+ }
55
+ });
56
+ }
57
+
58
+ firstUpdated() {
59
+ super.firstUpdated();
60
+
61
+ waitOnce('pb-page-ready', () => {
62
+ this._tify = new Tify({
63
+ manifestUrl: this.toAbsoluteURL(this.manifest, this.getEndpoint())
64
+ });
65
+ this._tify.ready.then(() => {
66
+ this.signalReady();
67
+ });
68
+
69
+ const container = document.createElement('div');
70
+ container.style.height = '100%';
71
+ container.style.width = '100%';
72
+ this.appendChild(container);
73
+
74
+ this._tify.mount(container);
75
+ });
76
+ }
77
+
78
+ createRenderRoot() {
79
+ return this;
80
+ }
81
+ }
82
+ customElements.define('pb-tify', PbTify);
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
- switch (key) {
1166
- case 'odd':
1167
- case 'view':
1168
- case 'columnSeparator':
1169
- case 'xpath':
1170
- case 'nodeId':
1171
- case 'path':
1172
- case 'root':
1173
- break;
1174
- default:
1175
- this._features[key] = value;
1176
- break;
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
@@ -68,7 +68,7 @@ class Registry {
68
68
  this.urlPattern = null;
69
69
 
70
70
  this.urlIgnore = new Set();
71
- this._pathParams = new Set();
71
+ this.pathParams = new Set();
72
72
  }
73
73
 
74
74
  configure(usePath = true, idHash = false, rootPath = '', urlPattern, ignoredParams) {
@@ -84,7 +84,7 @@ class Registry {
84
84
  // save a list of parameter names which go into the path
85
85
  const pathParams = [];
86
86
  pathToRegexp(this.urlPattern, pathParams);
87
- pathParams.forEach((param) => this._pathParams.add(param.name));
87
+ pathParams.forEach((param) => this.pathParams.add(param.name));
88
88
  // compile URL pattern into a decode and encode function
89
89
  this._decodePath = match(this.urlPattern);
90
90
  this._encodePath = compile(this.urlPattern);
@@ -150,7 +150,7 @@ class Registry {
150
150
  const urlParams = new URLSearchParams(window.location.search);
151
151
  urlParams.forEach((value, key) => {
152
152
  if (
153
- (this.urlPattern && this._pathParams.has(key)) ||
153
+ (this.urlPattern && this.pathParams.has(key)) ||
154
154
  (this.usePath && key === 'path')
155
155
  ) {
156
156
  console.warn("Found path parameter in query, but usePath is set to true. The path parameter will be ignored.");
@@ -280,8 +280,11 @@ class Registry {
280
280
 
281
281
  for (const [param, value] of Object.entries(this.state)) {
282
282
  if (this.urlPattern) {
283
- if (!(this._pathParams.has(param) || this.urlIgnore.has(param))) {
284
- setParam(value, param);
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);
285
288
  }
286
289
  } else if (
287
290
  (param !== 'path' || !this.usePath) &&
@@ -294,7 +297,16 @@ class Registry {
294
297
 
295
298
  if (this.state.path && this.state.path.length > 0) {
296
299
  if (this.urlPattern) {
297
- const encoded = this._encodePath(this.state);
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);
298
310
  newUrl.pathname = `${this.rootPath}/${encoded}`;
299
311
  } else if (this.usePath) {
300
312
  newUrl.pathname = `${this.rootPath}/${this.state.path}`;