@teipublisher/pb-components 1.33.1 → 1.34.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.
@@ -1328,6 +1328,12 @@
1328
1328
  "type": "string",
1329
1329
  "default": "\"title\""
1330
1330
  },
1331
+ {
1332
+ "name": "static",
1333
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
1334
+ "type": "boolean",
1335
+ "default": "false"
1336
+ },
1331
1337
  {
1332
1338
  "name": "url",
1333
1339
  "description": "The URL for the AJAX request. If a relative URL is passed, it will be resolved\nagainst the current API endpoint.",
@@ -1497,6 +1503,13 @@
1497
1503
  "type": "string",
1498
1504
  "default": "\"title\""
1499
1505
  },
1506
+ {
1507
+ "name": "static",
1508
+ "attribute": "static",
1509
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
1510
+ "type": "boolean",
1511
+ "default": "false"
1512
+ },
1500
1513
  {
1501
1514
  "name": "url",
1502
1515
  "attribute": "url",
@@ -10209,6 +10222,12 @@
10209
10222
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10210
10223
  "type": "string"
10211
10224
  },
10225
+ {
10226
+ "name": "static",
10227
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10228
+ "type": "boolean",
10229
+ "default": "false"
10230
+ },
10212
10231
  {
10213
10232
  "name": "subscribe",
10214
10233
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -10404,6 +10423,13 @@
10404
10423
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10405
10424
  "type": "string"
10406
10425
  },
10426
+ {
10427
+ "name": "static",
10428
+ "attribute": "static",
10429
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10430
+ "type": "boolean",
10431
+ "default": "false"
10432
+ },
10407
10433
  {
10408
10434
  "name": "subscribe",
10409
10435
  "attribute": "subscribe",
@@ -10660,6 +10686,12 @@
10660
10686
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10661
10687
  "type": "string"
10662
10688
  },
10689
+ {
10690
+ "name": "static",
10691
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10692
+ "type": "boolean",
10693
+ "default": "false"
10694
+ },
10663
10695
  {
10664
10696
  "name": "subscribe",
10665
10697
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -10838,6 +10870,13 @@
10838
10870
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10839
10871
  "type": "string"
10840
10872
  },
10873
+ {
10874
+ "name": "static",
10875
+ "attribute": "static",
10876
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10877
+ "type": "boolean",
10878
+ "default": "false"
10879
+ },
10841
10880
  {
10842
10881
  "name": "subscribe",
10843
10882
  "attribute": "subscribe",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teipublisher/pb-components",
3
- "version": "1.33.1",
3
+ "version": "1.34.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",
package/pb-elements.json CHANGED
@@ -1328,6 +1328,12 @@
1328
1328
  "type": "string",
1329
1329
  "default": "\"title\""
1330
1330
  },
1331
+ {
1332
+ "name": "static",
1333
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
1334
+ "type": "boolean",
1335
+ "default": "false"
1336
+ },
1331
1337
  {
1332
1338
  "name": "url",
1333
1339
  "description": "The URL for the AJAX request. If a relative URL is passed, it will be resolved\nagainst the current API endpoint.",
@@ -1497,6 +1503,13 @@
1497
1503
  "type": "string",
1498
1504
  "default": "\"title\""
1499
1505
  },
1506
+ {
1507
+ "name": "static",
1508
+ "attribute": "static",
1509
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
1510
+ "type": "boolean",
1511
+ "default": "false"
1512
+ },
1500
1513
  {
1501
1514
  "name": "url",
1502
1515
  "attribute": "url",
@@ -10209,6 +10222,12 @@
10209
10222
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10210
10223
  "type": "string"
10211
10224
  },
10225
+ {
10226
+ "name": "static",
10227
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10228
+ "type": "boolean",
10229
+ "default": "false"
10230
+ },
10212
10231
  {
10213
10232
  "name": "subscribe",
10214
10233
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -10404,6 +10423,13 @@
10404
10423
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10405
10424
  "type": "string"
10406
10425
  },
10426
+ {
10427
+ "name": "static",
10428
+ "attribute": "static",
10429
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10430
+ "type": "boolean",
10431
+ "default": "false"
10432
+ },
10407
10433
  {
10408
10434
  "name": "subscribe",
10409
10435
  "attribute": "subscribe",
@@ -10660,6 +10686,12 @@
10660
10686
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10661
10687
  "type": "string"
10662
10688
  },
10689
+ {
10690
+ "name": "static",
10691
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10692
+ "type": "boolean",
10693
+ "default": "false"
10694
+ },
10663
10695
  {
10664
10696
  "name": "subscribe",
10665
10697
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -10838,6 +10870,13 @@
10838
10870
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10839
10871
  "type": "string"
10840
10872
  },
10873
+ {
10874
+ "name": "static",
10875
+ "attribute": "static",
10876
+ "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
10877
+ "type": "boolean",
10878
+ "default": "false"
10879
+ },
10841
10880
  {
10842
10881
  "name": "subscribe",
10843
10882
  "attribute": "subscribe",
@@ -87,6 +87,13 @@ export class PbBrowseDocs extends PbLoad {
87
87
  subforms: {
88
88
  type: String
89
89
  },
90
+ /**
91
+ * If set, rewrite URLs to load pages as static HTML files,
92
+ * so no TEI Publisher instance is required
93
+ */
94
+ static: {
95
+ type: Boolean
96
+ },
90
97
  _file: {
91
98
  type: String
92
99
  },
@@ -120,6 +127,8 @@ export class PbBrowseDocs extends PbLoad {
120
127
  this.filterBy = 'title';
121
128
  this._allowModification = false;
122
129
  this._suggestions = [];
130
+
131
+ this.static = false;
123
132
  }
124
133
 
125
134
  connectedCallback() {
@@ -177,14 +186,16 @@ export class PbBrowseDocs extends PbLoad {
177
186
  });
178
187
  this.shadowRoot.getElementById('autocomplete').addEventListener('autocomplete-change', this._autocomplete.bind(this));
179
188
 
180
- const login = document.getElementById(this.login);
181
- if (!login) {
182
- console.error('<pb-browse-docs> connected pb-login element not found!');
183
- } else {
184
- this.subscribeTo('pb-login', (ev) => {
185
- this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
186
- }, []);
187
- this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
189
+ if (this.login) {
190
+ const login = document.getElementById(this.login);
191
+ if (!login) {
192
+ console.error('<pb-browse-docs> connected pb-login element not found!');
193
+ } else {
194
+ this.subscribeTo('pb-login', (ev) => {
195
+ this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
196
+ }, []);
197
+ this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
198
+ }
188
199
  }
189
200
 
190
201
  this.shadowRoot.getElementById('sort-list').addEventListener('selected-item-changed', this._sort.bind(this));
@@ -313,6 +324,10 @@ export class PbBrowseDocs extends PbLoad {
313
324
  }
314
325
 
315
326
  getURL(params) {
327
+ if (this.static) {
328
+ // use a static URL
329
+ return `collections/${this.collection}/${params.start || '1'}.html`;
330
+ }
316
331
  const url = super.getURL(params);
317
332
  return this.collection ? `${url}/${this.collection}` : url;
318
333
  }
package/src/pb-load.js CHANGED
@@ -288,13 +288,12 @@ export class PbLoad extends pbMixin(LitElement) {
288
288
  }
289
289
 
290
290
  _handleContent(ev) {
291
- this._parseHeaders(ev.detail.xhr);
292
-
293
291
  const resp = this.shadowRoot.getElementById('loadContent').lastResponse;
294
292
  if (this.container) {
295
293
  this.style.display = 'none';
296
294
  document.querySelectorAll(this.container).forEach((elem) => {
297
- elem.innerHTML = resp
295
+ elem.innerHTML = resp;
296
+ this._parseHeaders(ev.detail.xhr, elem);
298
297
  this._fixLinks(elem);
299
298
  this._onLoad(elem);
300
299
  });
@@ -304,6 +303,7 @@ export class PbLoad extends pbMixin(LitElement) {
304
303
 
305
304
  const div = document.createElement('div');
306
305
  div.innerHTML = resp;
306
+ this._parseHeaders(ev.detail.xhr, div);
307
307
  div.slot = '';
308
308
  this.appendChild(div);
309
309
  this._fixLinks(div);
@@ -338,9 +338,20 @@ export class PbLoad extends pbMixin(LitElement) {
338
338
  dialog.open();
339
339
  }
340
340
 
341
- _parseHeaders(xhr) {
342
- const total = xhr.getResponseHeader('pb-total');
343
- const start = xhr.getResponseHeader('pb-start');
341
+ _parseHeaders(xhr, content) {
342
+ // Try to determine number of pages and current position
343
+ // Search for data-pagination-* attributes first and if they
344
+ // can't be found, check HTTP headers
345
+ function getPaginationParam(type) {
346
+ const elem = content.querySelector(`[data-pagination-${type}]`);
347
+ if (elem) {
348
+ return elem.getAttribute(`data-pagination-${type}`);
349
+ }
350
+ return xhr.getResponseHeader(`pb-${type}`);
351
+ }
352
+
353
+ const total = getPaginationParam('total');
354
+ const start = getPaginationParam('start');
344
355
 
345
356
  if (this.start !== start) {
346
357
  this.start = parseInt(start);
package/src/pb-view.js CHANGED
@@ -161,6 +161,14 @@ export class PbView extends pbMixin(LitElement) {
161
161
  url: {
162
162
  type: String
163
163
  },
164
+ /**
165
+ * If set, rewrite URLs to load pages as static HTML files,
166
+ * so no TEI Publisher instance is required. Use this in combination with
167
+ * [tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).
168
+ */
169
+ static: {
170
+ type: Boolean
171
+ },
164
172
  /**
165
173
  * The server returns footnotes separately. Set this property
166
174
  * if you wish to append them to the main text.
@@ -328,6 +336,7 @@ export class PbView extends pbMixin(LitElement) {
328
336
  this._selector = new Map();
329
337
  this._chunks = [];
330
338
  this._scrollTarget = null;
339
+ this.static = false;
331
340
  }
332
341
 
333
342
  attributeChangedCallback(name, oldVal, newVal) {
@@ -584,20 +593,56 @@ export class PbView extends pbMixin(LitElement) {
584
593
 
585
594
  const loadContent = this.shadowRoot.getElementById('loadContent');
586
595
 
587
- if (!this.url) {
596
+ if (this.static) {
597
+ this._staticUrl(params).then((url) => {
598
+ loadContent.url = url;
599
+ loadContent.generateRequest();
600
+ });
601
+ } else {
602
+ if (!this.url) {
603
+ if (this.minApiVersion('1.0.0')) {
604
+ this.url = "api/parts";
605
+ } else {
606
+ this.url = "modules/lib/components.xql";
607
+ }
608
+ }
588
609
  if (this.minApiVersion('1.0.0')) {
589
- this.url = "api/parts";
610
+ loadContent.url = `${this.getEndpoint()}/${this.url}/${encodeURIComponent(this.getDocument().path)}/json`;
590
611
  } else {
591
- this.url = "modules/lib/components.xql";
612
+ loadContent.url = `${this.getEndpoint()}/${this.url}`;
592
613
  }
614
+ loadContent.params = params;
615
+ loadContent.generateRequest();
593
616
  }
594
- if (this.minApiVersion('1.0.0')) {
595
- loadContent.url = `${this.getEndpoint()}/${this.url}/${encodeURIComponent(this.getDocument().path)}/json`;
596
- } else {
597
- loadContent.url = `${this.getEndpoint()}/${this.url}`;
617
+ }
618
+
619
+ /**
620
+ * Use a static URL to load pre-generated content.
621
+ */
622
+ async _staticUrl(params) {
623
+ function createKey(paramNames) {
624
+ const urlComponents = [];
625
+ paramNames.sort().forEach(key => {
626
+ if (params[key]) {
627
+ urlComponents.push(`${key}=${params[key]}`);
628
+ }
629
+ });
630
+ return urlComponents.join('&');
598
631
  }
599
- loadContent.params = params;
600
- loadContent.generateRequest();
632
+
633
+ const index = await fetch(`index.json`)
634
+ .then((response) => response.json());
635
+ const paramNames = ['odd', 'view', 'xpath'];
636
+ this.querySelectorAll('pb-param').forEach((param) => paramNames.push(`user.${param.getAttribute('name')}`));
637
+ let url = createKey([...paramNames, 'root']);
638
+ let file = index[url];
639
+ if (!file) {
640
+ url = createKey(paramNames);
641
+ file = index[url];
642
+ }
643
+
644
+ console.log('<pb-view> Static lookup %s: %s', url, file);
645
+ return `${file}`;
601
646
  }
602
647
 
603
648
  _clear() {
@@ -838,7 +883,11 @@ export class PbView extends pbMixin(LitElement) {
838
883
  let link = document.createElement('link');
839
884
  link.setAttribute('rel', 'stylesheet');
840
885
  link.setAttribute('type', 'text/css');
841
- link.setAttribute('href', `${this.getEndpoint()}/transform/${this.getOdd()}.css`);
886
+ if (this.static) {
887
+ link.setAttribute('href', `/css/${this.getOdd()}.css`);
888
+ } else {
889
+ link.setAttribute('href', `${this.getEndpoint()}/transform/${this.getOdd()}.css`);
890
+ }
842
891
  links.push(link);
843
892
 
844
893
  if (this.loadCss) {