@teipublisher/pb-components 3.6.2 → 3.6.4
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 +14 -0
- package/dist/pb-components-bundle.js +32 -32
- package/package.json +1 -1
- package/src/pb-authority-lookup.js +92 -9
- package/src/pb-view-annotate.js +51 -8
package/package.json
CHANGED
|
@@ -87,6 +87,20 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
87
87
|
this._authorities = {};
|
|
88
88
|
this.noOccurrences = false;
|
|
89
89
|
this.group = 'tei';
|
|
90
|
+
this._queryGeneration = 0;
|
|
91
|
+
this._queryDebounceMs = 300;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
disconnectedCallback() {
|
|
95
|
+
super.disconnectedCallback();
|
|
96
|
+
if (this._queryTimer) {
|
|
97
|
+
clearTimeout(this._queryTimer);
|
|
98
|
+
this._queryTimer = null;
|
|
99
|
+
}
|
|
100
|
+
if (this._occurrencesController) {
|
|
101
|
+
this._occurrencesController.abort();
|
|
102
|
+
this._occurrencesController = null;
|
|
103
|
+
}
|
|
90
104
|
}
|
|
91
105
|
|
|
92
106
|
connectedCallback() {
|
|
@@ -101,7 +115,7 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
101
115
|
this.query = ev.detail.query;
|
|
102
116
|
this.type = ev.detail.type;
|
|
103
117
|
this._results = [];
|
|
104
|
-
this.
|
|
118
|
+
this._scheduleQuery(true);
|
|
105
119
|
});
|
|
106
120
|
|
|
107
121
|
waitOnce('pb-page-ready', () => {
|
|
@@ -110,7 +124,7 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
110
124
|
this._authorities[connector.register] = connector;
|
|
111
125
|
});
|
|
112
126
|
if (this.autoLookup) {
|
|
113
|
-
this.
|
|
127
|
+
this._scheduleQuery(true);
|
|
114
128
|
}
|
|
115
129
|
});
|
|
116
130
|
|
|
@@ -347,28 +361,76 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
347
361
|
}
|
|
348
362
|
this._results = [];
|
|
349
363
|
this.query = e.target.value;
|
|
350
|
-
this.
|
|
364
|
+
this._scheduleQuery();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
_scheduleQuery(immediate = false) {
|
|
368
|
+
if (this._queryTimer) {
|
|
369
|
+
clearTimeout(this._queryTimer);
|
|
370
|
+
this._queryTimer = null;
|
|
371
|
+
}
|
|
372
|
+
if (immediate) {
|
|
373
|
+
this._query();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
this._queryTimer = setTimeout(() => {
|
|
377
|
+
this._queryTimer = null;
|
|
378
|
+
this._query();
|
|
379
|
+
}, this._queryDebounceMs);
|
|
351
380
|
}
|
|
352
381
|
|
|
353
382
|
_query() {
|
|
383
|
+
const generation = ++this._queryGeneration;
|
|
384
|
+
|
|
385
|
+
if (this._occurrencesController) {
|
|
386
|
+
this._occurrencesController.abort();
|
|
387
|
+
this._occurrencesController = null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const authority = this._authorities[this.type];
|
|
391
|
+
if (!authority) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
354
395
|
this.emitTo('pb-start-update');
|
|
355
|
-
|
|
356
|
-
|
|
396
|
+
authority
|
|
397
|
+
.query(this.query)
|
|
398
|
+
.then(results => {
|
|
399
|
+
if (generation !== this._queryGeneration) {
|
|
400
|
+
return undefined;
|
|
401
|
+
}
|
|
402
|
+
return this._occurrences(results.items, generation);
|
|
403
|
+
})
|
|
404
|
+
.then(merged => {
|
|
405
|
+
if (merged === undefined || generation !== this._queryGeneration) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
357
408
|
this._results = merged;
|
|
409
|
+
this.emitTo('pb-end-update');
|
|
410
|
+
})
|
|
411
|
+
.catch(err => {
|
|
412
|
+
if (generation !== this._queryGeneration) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
console.error('<pb-authority-lookup> query failed: %s', err.message);
|
|
416
|
+
this.emitTo('pb-end-update');
|
|
358
417
|
});
|
|
359
|
-
this.emitTo('pb-end-update');
|
|
360
|
-
// this.shadowRoot.getElementById('query').focus();
|
|
361
|
-
});
|
|
362
418
|
}
|
|
363
419
|
|
|
364
420
|
_addEntity() {
|
|
365
421
|
this.emitTo('pb-authority-new-entity', { query: this.query, type: this.type });
|
|
366
422
|
}
|
|
367
423
|
|
|
368
|
-
_occurrences(items) {
|
|
424
|
+
_occurrences(items, generation) {
|
|
369
425
|
if (this.noOccurrences) {
|
|
370
426
|
return Promise.resolve(items);
|
|
371
427
|
}
|
|
428
|
+
if (this._occurrencesController) {
|
|
429
|
+
this._occurrencesController.abort();
|
|
430
|
+
}
|
|
431
|
+
const controller = new AbortController();
|
|
432
|
+
this._occurrencesController = controller;
|
|
433
|
+
|
|
372
434
|
const params = new FormData();
|
|
373
435
|
params.append('register', this.type);
|
|
374
436
|
items.forEach(item => {
|
|
@@ -378,13 +440,27 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
378
440
|
fetch(`${this.getEndpoint()}/api/annotations/occurrences`, {
|
|
379
441
|
method: 'POST',
|
|
380
442
|
body: params,
|
|
443
|
+
signal: controller.signal,
|
|
381
444
|
})
|
|
382
445
|
.then(response => {
|
|
446
|
+
if (generation !== this._queryGeneration) {
|
|
447
|
+
resolve(undefined);
|
|
448
|
+
return undefined;
|
|
449
|
+
}
|
|
383
450
|
if (response.ok) {
|
|
384
451
|
return response.json();
|
|
385
452
|
}
|
|
453
|
+
resolve(items);
|
|
454
|
+
return undefined;
|
|
386
455
|
})
|
|
387
456
|
.then(json => {
|
|
457
|
+
if (json === undefined) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (generation !== this._queryGeneration) {
|
|
461
|
+
resolve(undefined);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
388
464
|
items.forEach(item => {
|
|
389
465
|
if (json[item.id]) {
|
|
390
466
|
item.occurrences = json[item.id];
|
|
@@ -406,6 +482,13 @@ export class PbAuthorityLookup extends themableMixin(pbMixin(LitElement)) {
|
|
|
406
482
|
return d;
|
|
407
483
|
});
|
|
408
484
|
resolve(items);
|
|
485
|
+
})
|
|
486
|
+
.catch(err => {
|
|
487
|
+
if (err.name === 'AbortError' || generation !== this._queryGeneration) {
|
|
488
|
+
resolve(undefined);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
resolve(items);
|
|
409
492
|
});
|
|
410
493
|
});
|
|
411
494
|
}
|
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();
|