@teipublisher/pb-components 3.6.3 → 3.6.5
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/.github/workflows/node.js.yml +14 -0
- package/CHANGELOG.md +15 -0
- package/Dockerfile +30 -41
- package/ci/setup-tei-publisher-app.sh +70 -0
- package/ci/tp_config.json +31 -0
- package/dist/pb-components-bundle.js +22 -22
- package/package.json +2 -2
- package/src/pb-page.js +4 -12
- package/src/pb-view-annotate.js +51 -8
- package/src/pb-view.js +55 -14
- package/tei-publisher-app/tei-publisher.xar +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teipublisher/pb-components",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.5",
|
|
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",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"start": "npm run build && npm run docs && es-dev-server",
|
|
19
19
|
"test": "karma start",
|
|
20
20
|
"test:watch": "karma start --auto-watch=true --single-run=false",
|
|
21
|
-
"docker": "npm run build:production && docker build --no-cache --pull --rm -f 'Dockerfile' -t pbcomponents:master '.'",
|
|
21
|
+
"docker": "npm run build:production && ci/setup-tei-publisher-app.sh && docker build --no-cache --pull --rm -f 'Dockerfile' -t pbcomponents:master '.'",
|
|
22
22
|
"docker:run": "docker run --rm -it -p 8080:8080/tcp -p 8443:8443/tcp pbcomponents:master",
|
|
23
23
|
"docs": "wca src -f json --outFile pb-elements.json",
|
|
24
24
|
"lint:eslint": "eslint --ext .js,.html . --ignore-path .gitignore",
|
package/src/pb-page.js
CHANGED
|
@@ -281,19 +281,11 @@ export class PbPage extends pbMixin(LitElement) {
|
|
|
281
281
|
console.log('<pb-page> Loading component theme stylesheets from %s', stylesheetURLs.join(', '));
|
|
282
282
|
this._themeSheet = await loadStylesheets(stylesheetURLs);
|
|
283
283
|
|
|
284
|
-
//
|
|
284
|
+
// Determine the server API version. Jinks-generated apps expose a /login
|
|
285
|
+
// page (HTTP 200), so probing that URL is no longer a reliable indicator
|
|
286
|
+
// of a pre-7 server — use /api/version directly.
|
|
285
287
|
if (!this.apiVersion) {
|
|
286
|
-
|
|
287
|
-
// this is necessary to prevent a CORS failure
|
|
288
|
-
const json = await fetch(`${this.endpoint}/login`)
|
|
289
|
-
.then(res => {
|
|
290
|
-
if (res.ok) {
|
|
291
|
-
return null;
|
|
292
|
-
}
|
|
293
|
-
// if not, access the actual /api/version endpoint to retrieve the API version
|
|
294
|
-
return fetch(`${this.endpoint}/api/version`).then(res2 => res2.json());
|
|
295
|
-
})
|
|
296
|
-
.catch(() => fetch(`${this.endpoint}/api/version`).then(res2 => res2.json()));
|
|
288
|
+
const json = await fetch(`${this.endpoint}/api/version`).then(res2 => res2.json());
|
|
297
289
|
|
|
298
290
|
if (json) {
|
|
299
291
|
this.apiVersion = json.api;
|
package/src/pb-view-annotate.js
CHANGED
|
@@ -405,7 +405,7 @@ class PbViewAnnotate extends PbView {
|
|
|
405
405
|
console.warn('<pb-view-annotate> history is empty');
|
|
406
406
|
return;
|
|
407
407
|
}
|
|
408
|
-
this.
|
|
408
|
+
this._captureScrollPosition();
|
|
409
409
|
const lastEntry = this._history.pop();
|
|
410
410
|
this._clearMarkers();
|
|
411
411
|
this._ranges = JSON.parse(lastEntry);
|
|
@@ -460,11 +460,57 @@ class PbViewAnnotate extends PbView {
|
|
|
460
460
|
});
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Return the nearest ancestor (or this element) that actually scrolls.
|
|
465
|
+
* In fixed-layout annotate pages the scroll container is usually `main`,
|
|
466
|
+
* not the pb-view-annotate host.
|
|
467
|
+
*/
|
|
468
|
+
_scrollContainer() {
|
|
469
|
+
let el = this;
|
|
470
|
+
while (el) {
|
|
471
|
+
const { overflow, overflowY } = getComputedStyle(el);
|
|
472
|
+
const scrollable =
|
|
473
|
+
/(auto|scroll|overlay)/.test(overflowY) || /(auto|scroll|overlay)/.test(overflow);
|
|
474
|
+
if (scrollable && el.scrollHeight > el.clientHeight) {
|
|
475
|
+
return el;
|
|
476
|
+
}
|
|
477
|
+
el = el.parentElement;
|
|
478
|
+
}
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
_captureScrollPosition() {
|
|
483
|
+
const el = this._scrollContainer();
|
|
484
|
+
this._scrollEl = el;
|
|
485
|
+
this._scrollTop = el.scrollTop;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
_restoreScrollPosition() {
|
|
489
|
+
if (this._scrollTop === undefined || !this._scrollEl) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const { _scrollEl: el, _scrollTop: top } = this;
|
|
493
|
+
const restore = () => {
|
|
494
|
+
el.scrollTop = top;
|
|
495
|
+
};
|
|
496
|
+
restore();
|
|
497
|
+
requestAnimationFrame(() => {
|
|
498
|
+
restore();
|
|
499
|
+
setTimeout(restore, 100);
|
|
500
|
+
// Run after pb-view._scroll() (400ms) so URL-hash scrolling does not win.
|
|
501
|
+
setTimeout(() => {
|
|
502
|
+
restore();
|
|
503
|
+
this._scrollTop = undefined;
|
|
504
|
+
this._scrollEl = undefined;
|
|
505
|
+
}, 450);
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
463
509
|
_refresh(ev) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
this._scrollTop = this.scrollTop;
|
|
510
|
+
if (ev?.detail?.preserveScroll) {
|
|
511
|
+
this._captureScrollPosition();
|
|
467
512
|
}
|
|
513
|
+
super._refresh(ev);
|
|
468
514
|
}
|
|
469
515
|
|
|
470
516
|
_doLoad(params) {
|
|
@@ -480,10 +526,7 @@ class PbViewAnnotate extends PbView {
|
|
|
480
526
|
this._annotationStyles();
|
|
481
527
|
this.updateAnnotations(true, false);
|
|
482
528
|
this._markIncompleteAnnotations();
|
|
483
|
-
|
|
484
|
-
this.scrollTop = this._scrollTop;
|
|
485
|
-
this._scrollTop = undefined;
|
|
486
|
-
}
|
|
529
|
+
this._restoreScrollPosition();
|
|
487
530
|
this.emitTo('pb-annotations-loaded');
|
|
488
531
|
// Marker positions depend on the ODD stylesheet and final text layout.
|
|
489
532
|
this._scheduleMarkerRefresh();
|
package/src/pb-view.js
CHANGED
|
@@ -384,28 +384,26 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
if (!this.disableHistory) {
|
|
387
|
-
|
|
388
|
-
this.xmlId = registry.state.id;
|
|
389
|
-
}
|
|
387
|
+
this._syncPositionFromRegistry();
|
|
390
388
|
|
|
391
389
|
if (registry.state.action && registry.state.action === 'search') {
|
|
392
390
|
this.highlight = true;
|
|
393
391
|
}
|
|
394
392
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
} else if (registry.state.root && !this.nodeId) {
|
|
398
|
-
this.nodeId = registry.state.root;
|
|
399
|
-
}
|
|
400
|
-
|
|
393
|
+
const doc = this.getDocument();
|
|
394
|
+
const prevState = { ...registry.state, ...registry.getState(this) };
|
|
401
395
|
const newState = {
|
|
402
|
-
id: this.xmlId,
|
|
403
396
|
view: this.getView(),
|
|
404
397
|
odd: this.getOdd(),
|
|
405
|
-
path:
|
|
398
|
+
path: doc.path,
|
|
406
399
|
};
|
|
407
|
-
if (this.
|
|
400
|
+
if (this.xmlId) {
|
|
401
|
+
newState.id = this.xmlId;
|
|
402
|
+
}
|
|
403
|
+
if (this.view !== 'single' && this.nodeId) {
|
|
408
404
|
newState.root = this.nodeId;
|
|
405
|
+
} else if (prevState.path && prevState.path !== doc.path) {
|
|
406
|
+
newState.root = null;
|
|
409
407
|
}
|
|
410
408
|
if (this.fill) {
|
|
411
409
|
newState.fill = this.fill;
|
|
@@ -567,6 +565,43 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
567
565
|
}
|
|
568
566
|
}
|
|
569
567
|
|
|
568
|
+
_refreshHasPosition(detail) {
|
|
569
|
+
if (!detail) {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
return (
|
|
573
|
+
Object.prototype.hasOwnProperty.call(detail, 'id') ||
|
|
574
|
+
Object.prototype.hasOwnProperty.call(detail, 'root') ||
|
|
575
|
+
Object.prototype.hasOwnProperty.call(detail, 'position') ||
|
|
576
|
+
Object.prototype.hasOwnProperty.call(detail, 'path') ||
|
|
577
|
+
Object.prototype.hasOwnProperty.call(detail, 'xpath')
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
_syncPositionFromRegistry() {
|
|
582
|
+
if (this.disableHistory || this.getAttribute('xml-id')) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
const doc = this.getDocument();
|
|
586
|
+
if (!doc?.path) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const state = { ...registry.state, ...registry.getState(this) };
|
|
590
|
+
if (state.path && state.path !== doc.path) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (!this.xmlId && state.id) {
|
|
594
|
+
this.xmlId = state.id;
|
|
595
|
+
}
|
|
596
|
+
if (!this.nodeId) {
|
|
597
|
+
if (this.getView() === 'single') {
|
|
598
|
+
this.nodeId = null;
|
|
599
|
+
} else if (state.root) {
|
|
600
|
+
this.nodeId = state.root;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
570
605
|
_refresh(ev) {
|
|
571
606
|
if (ev && ev.detail) {
|
|
572
607
|
if (
|
|
@@ -588,6 +623,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
588
623
|
}
|
|
589
624
|
if (ev.detail.id) {
|
|
590
625
|
this.xmlId = ev.detail.id;
|
|
626
|
+
this.nodeId = null;
|
|
591
627
|
} else if (ev.detail.id == null) {
|
|
592
628
|
this.xmlId = null;
|
|
593
629
|
}
|
|
@@ -619,6 +655,9 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
619
655
|
this._scrollTarget = ev.detail.hash;
|
|
620
656
|
}
|
|
621
657
|
}
|
|
658
|
+
if (!this._refreshHasPosition(ev?.detail)) {
|
|
659
|
+
this._syncPositionFromRegistry();
|
|
660
|
+
}
|
|
622
661
|
this._updateStyles();
|
|
623
662
|
if (this.infiniteScroll) {
|
|
624
663
|
this._clear();
|
|
@@ -1264,7 +1303,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
1264
1303
|
if (this.view === 'single') {
|
|
1265
1304
|
// when switching to single view, clear current node id
|
|
1266
1305
|
this.nodeId = null;
|
|
1267
|
-
} else {
|
|
1306
|
+
} else if (this.switchView) {
|
|
1268
1307
|
// otherwise use value for alternate view returned from server
|
|
1269
1308
|
this.nodeId = this.switchView;
|
|
1270
1309
|
}
|
|
@@ -1279,7 +1318,9 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
|
1279
1318
|
this.columnSeparator = properties.columnSeparator;
|
|
1280
1319
|
}
|
|
1281
1320
|
this.xmlId = (!this.getAttribute('xml-id') && properties.id) || this.xmlId;
|
|
1282
|
-
|
|
1321
|
+
if (Object.prototype.hasOwnProperty.call(properties, 'root')) {
|
|
1322
|
+
this.nodeId = (!this.getAttribute('xml-id') && properties.root) || null;
|
|
1323
|
+
}
|
|
1283
1324
|
|
|
1284
1325
|
if (properties.path) {
|
|
1285
1326
|
this.getDocument().path = properties.path;
|
|
Binary file
|