@teipublisher/pb-components 2.25.5 → 2.25.7

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.
Files changed (130) hide show
  1. package/.github/workflows/main.yml +3 -3
  2. package/.github/workflows/node.js.yml +3 -3
  3. package/.github/workflows/release.js.yml +3 -3
  4. package/CHANGELOG.md +15 -0
  5. package/Dockerfile +78 -70
  6. package/css/components.css +5 -5
  7. package/dist/demo/pb-drawer2.html +1 -1
  8. package/dist/demo/pb-facsimile.html +2 -2
  9. package/dist/demo/pb-leaflet-map.html +1 -1
  10. package/dist/demo/pb-repeat.html +1 -3
  11. package/dist/demo/pb-view3.html +1 -1
  12. package/dist/{paper-icon-button-0fb125c4.js → paper-icon-button-72125e67.js} +1 -1
  13. package/dist/pb-code-editor.js +25 -20
  14. package/dist/pb-component-docs.js +58 -54
  15. package/dist/pb-components-bundle.js +1827 -1520
  16. package/dist/pb-edit-app.js +167 -107
  17. package/dist/pb-elements.json +54 -54
  18. package/dist/{pb-i18n-0611135a.js → pb-i18n-4cc00bfe.js} +1 -1
  19. package/dist/pb-leaflet-map.js +23 -23
  20. package/dist/pb-mei.js +56 -41
  21. package/dist/{pb-mixin-b1caa22e.js → pb-mixin-886ece32.js} +1 -1
  22. package/dist/pb-odd-editor.js +925 -758
  23. package/dist/pb-tify.js +2 -2
  24. package/dist/{vaadin-element-mixin-859a0132.js → vaadin-element-mixin-ad07ba25.js} +88 -61
  25. package/gh-pages.js +5 -3
  26. package/lib/openseadragon.min.js +6 -6
  27. package/package.json +3 -2
  28. package/pb-elements.json +54 -54
  29. package/src/assets/components.css +5 -5
  30. package/src/authority/airtable.js +20 -21
  31. package/src/authority/anton.js +129 -129
  32. package/src/authority/custom.js +23 -21
  33. package/src/authority/geonames.js +38 -32
  34. package/src/authority/gnd.js +47 -42
  35. package/src/authority/kbga.js +137 -134
  36. package/src/authority/metagrid.js +44 -46
  37. package/src/authority/reconciliation.js +66 -67
  38. package/src/authority/registry.js +4 -4
  39. package/src/docs/pb-component-docs.js +2 -2
  40. package/src/docs/pb-component-view.js +5 -5
  41. package/src/docs/pb-components-list.js +2 -2
  42. package/src/docs/pb-demo-snippet.js +2 -2
  43. package/src/dts-client.js +299 -297
  44. package/src/dts-select-endpoint.js +90 -82
  45. package/src/parse-date-service.js +184 -135
  46. package/src/pb-ajax.js +171 -167
  47. package/src/pb-authority-lookup.js +96 -81
  48. package/src/pb-autocomplete.js +292 -280
  49. package/src/pb-blacklab-highlight.js +264 -259
  50. package/src/pb-blacklab-results.js +236 -221
  51. package/src/pb-browse-docs.js +540 -475
  52. package/src/pb-browse.js +68 -65
  53. package/src/pb-clipboard.js +79 -76
  54. package/src/pb-code-editor.js +110 -102
  55. package/src/pb-code-highlight.js +209 -204
  56. package/src/pb-codepen.js +79 -72
  57. package/src/pb-collapse.js +149 -146
  58. package/src/pb-combo-box.js +190 -190
  59. package/src/pb-components-bundle.js +1 -1
  60. package/src/pb-custom-form.js +150 -149
  61. package/src/pb-document.js +89 -90
  62. package/src/pb-download.js +208 -195
  63. package/src/pb-drawer.js +145 -148
  64. package/src/pb-edit-app.js +301 -229
  65. package/src/pb-edit-xml.js +99 -96
  66. package/src/pb-events.js +114 -107
  67. package/src/pb-facs-link.js +104 -102
  68. package/src/pb-facsimile.js +444 -410
  69. package/src/pb-formula.js +151 -153
  70. package/src/pb-geolocation.js +129 -131
  71. package/src/pb-grid-action.js +53 -56
  72. package/src/pb-grid.js +231 -228
  73. package/src/pb-highlight.js +140 -140
  74. package/src/pb-hotkeys.js +40 -42
  75. package/src/pb-i18n.js +101 -104
  76. package/src/pb-image-strip.js +84 -78
  77. package/src/pb-lang.js +83 -70
  78. package/src/pb-leaflet-map.js +488 -485
  79. package/src/pb-link.js +126 -124
  80. package/src/pb-load.js +431 -426
  81. package/src/pb-login.js +275 -254
  82. package/src/pb-manage-odds.js +364 -318
  83. package/src/pb-map-icon.js +89 -89
  84. package/src/pb-map-layer.js +85 -85
  85. package/src/pb-markdown.js +90 -99
  86. package/src/pb-media-query.js +74 -72
  87. package/src/pb-mei.js +306 -295
  88. package/src/pb-message.js +143 -130
  89. package/src/pb-mixin.js +269 -264
  90. package/src/pb-navigation.js +80 -82
  91. package/src/pb-observable.js +38 -38
  92. package/src/pb-odd-editor.js +1056 -958
  93. package/src/pb-odd-elementspec-editor.js +348 -297
  94. package/src/pb-odd-model-editor.js +1058 -898
  95. package/src/pb-odd-parameter-editor.js +200 -178
  96. package/src/pb-odd-rendition-editor.js +136 -124
  97. package/src/pb-page.js +432 -422
  98. package/src/pb-paginate.js +202 -190
  99. package/src/pb-panel.js +191 -179
  100. package/src/pb-popover-themes.js +7 -5
  101. package/src/pb-popover.js +296 -287
  102. package/src/pb-print-preview.js +127 -127
  103. package/src/pb-progress.js +49 -49
  104. package/src/pb-repeat.js +105 -104
  105. package/src/pb-restricted.js +84 -77
  106. package/src/pb-search.js +238 -221
  107. package/src/pb-select-feature.js +127 -120
  108. package/src/pb-select-odd.js +132 -124
  109. package/src/pb-select-template.js +89 -78
  110. package/src/pb-select.js +251 -227
  111. package/src/pb-split-list.js +179 -174
  112. package/src/pb-svg.js +80 -79
  113. package/src/pb-table-column.js +54 -54
  114. package/src/pb-table-grid.js +221 -203
  115. package/src/pb-tabs.js +61 -63
  116. package/src/pb-tify.js +154 -154
  117. package/src/pb-timeline.js +271 -229
  118. package/src/pb-toggle-feature.js +198 -185
  119. package/src/pb-upload.js +184 -174
  120. package/src/pb-version.js +30 -30
  121. package/src/pb-view-annotate.js +132 -98
  122. package/src/pb-view.js +1282 -1263
  123. package/src/pb-zoom.js +40 -40
  124. package/src/polymer-hack.js +1 -1
  125. package/src/search-result-service.js +256 -223
  126. package/src/seed-element.js +13 -20
  127. package/src/settings.js +4 -4
  128. package/src/theming.js +91 -91
  129. package/src/urls.js +289 -289
  130. package/src/utils.js +53 -51
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import "@lrnwebcomponents/es-global-bridge";
2
+ import '@lrnwebcomponents/es-global-bridge';
3
3
  import { pbMixin } from './pb-mixin.js';
4
4
  import { resolveURL } from './utils.js';
5
5
 
@@ -24,445 +24,479 @@ import { resolveURL } from './utils.js';
24
24
  * @slot after - use for content which should be shown below the facsimile viewer
25
25
  */
26
26
  export class PbFacsimile extends pbMixin(LitElement) {
27
- static get properties() {
28
- return {
29
- ...super.properties,
30
- /**
31
- * Set to false to prevent the appearance of the default navigation controls.
32
- * Note that if set to false, the customs buttons set by the options
33
- * zoomInButton, zoomOutButton etc, are rendered inactive.
34
- */
35
- showNavigationControl: {
36
- type: Boolean,
37
- attribute: 'show-navigation-control'
38
- },
39
- // Set to true to make the navigator minimap appear.
40
- showNavigator: {
41
- type: Boolean,
42
- attribute: 'show-navigator'
43
- },
44
-
45
- /** If true then the 'previous" and 'next' button is displayed switch between images. */
46
- showSequenceMode: {
47
- type: Boolean,
48
- attribute: 'show-sequence-control'
49
- },
50
-
51
- /** If true then the 'Go home' button is displayed to go back to the original zoom and pan. */
52
- showHomeControl: {
53
- type: Boolean,
54
- attribute: 'show-home-control'
55
- },
56
- /** If true then the 'Toggle full page' button is displayed to switch between full page and normal mode. */
57
- showFullPageControl: {
58
- type: Boolean,
59
- attribute: 'show-full-page-control'
60
- },
61
- /**
62
- * if true shows a 'download' button
63
- */
64
- showDownloadButton:{
65
- type: Boolean,
66
- attribute: 'show-download-control'
67
- },
68
- /**
69
- * Default zoom between: set to 0 to adjust to viewer size.
70
- */
71
- defaultZoomLevel: {
72
- type: Number,
73
- attribute: 'default-zoom-level'
74
- },
75
- /**
76
- * If true then the rotate left/right controls will be displayed
77
- * as part of the standard controls. This is also subject to the
78
- * browser support for rotate (e.g. viewer.drawer.canRotate()).
79
- */
80
- showRotationControl: {
81
- type: Boolean,
82
- attribute: 'show-rotation-control'
83
- },
84
- // Constrain during pan
85
- constrainDuringPan: {
86
- type: Boolean,
87
- attribute: 'contrain-during-pan'
88
- },
89
- /**
90
- * The percentage ( as a number from 0 to 1 ) of the source image
91
- * which must be kept within the viewport.
92
- * If the image is dragged beyond that limit, it will 'bounce'
93
- * back until the minimum visibility ratio is achieved.
94
- * Setting this to 0 and wrapHorizontal ( or wrapVertical )
95
- * to true will provide the effect of an infinitely scrolling viewport.
96
- */
97
- visibilityRatio: {
98
- type: Number,
99
- attribute: 'visibility-ratio'
100
- },
101
- /**
102
- * If set, thumbnails of all images are shown in a reference strip at the
103
- * bottom of the viewer.
104
- */
105
- referenceStrip: {
106
- type: Boolean,
107
- attribute: 'reference-strip'
108
- },
109
- /**
110
- * Size ratio for the reference strip thumbnails. 0.2 by default.
111
- */
112
- referenceStripSizeRatio: {
113
- type: Number,
114
- attribute: 'reference-strip-size-ratio'
115
- },
116
- /**
117
- * Type of the source of the image to display: either 'iiif' or 'image'
118
- * (for simple image links not served via IIIF).
119
- */
120
- type: {
121
- type: String
122
- },
123
- baseUri: {
124
- type: String,
125
- attribute: 'base-uri'
126
- },
127
- /**
128
- * Path pointing to the location of openseadragon user interface images.
129
- */
130
- prefixUrl: {
131
- type: String,
132
- attribute: 'prefix-url'
133
- },
134
- /**
135
- * Array of facsimiles
136
- *
137
- */
138
- facsimiles: {
139
- type: Array
140
- },
141
- /**
142
- * Will be true if images were loaded for display, false if there are no images
143
- * to show.
144
- */
145
- loaded: {
146
- type: Boolean,
147
- reflect: true
148
- },
149
- /**
150
- * CORS (Cross-Origin Resource Sharing) policy - wraps the OSD Viewer option -
151
- * only sensible values are 'anonymous' (default) or 'use-credentials'.
152
- */
153
- crossOriginPolicy:{
154
- type: String,
155
- attribute: 'cors'
156
- }
157
- };
27
+ static get properties() {
28
+ return {
29
+ ...super.properties,
30
+ /**
31
+ * Set to false to prevent the appearance of the default navigation controls.
32
+ * Note that if set to false, the customs buttons set by the options
33
+ * zoomInButton, zoomOutButton etc, are rendered inactive.
34
+ */
35
+ showNavigationControl: {
36
+ type: Boolean,
37
+ attribute: 'show-navigation-control',
38
+ },
39
+ // Set to true to make the navigator minimap appear.
40
+ showNavigator: {
41
+ type: Boolean,
42
+ attribute: 'show-navigator',
43
+ },
44
+
45
+ /** If true then the 'previous" and 'next' button is displayed switch between images. */
46
+ showSequenceMode: {
47
+ type: Boolean,
48
+ attribute: 'show-sequence-control',
49
+ },
50
+
51
+ /** If true then the 'Go home' button is displayed to go back to the original zoom and pan. */
52
+ showHomeControl: {
53
+ type: Boolean,
54
+ attribute: 'show-home-control',
55
+ },
56
+ /** If true then the 'Toggle full page' button is displayed to switch between full page and normal mode. */
57
+ showFullPageControl: {
58
+ type: Boolean,
59
+ attribute: 'show-full-page-control',
60
+ },
61
+ /**
62
+ * if true shows a 'download' button
63
+ */
64
+ showDownloadButton: {
65
+ type: Boolean,
66
+ attribute: 'show-download-control',
67
+ },
68
+ /**
69
+ * Default zoom between: set to 0 to adjust to viewer size.
70
+ */
71
+ defaultZoomLevel: {
72
+ type: Number,
73
+ attribute: 'default-zoom-level',
74
+ },
75
+ /**
76
+ * If true then the rotate left/right controls will be displayed
77
+ * as part of the standard controls. This is also subject to the
78
+ * browser support for rotate (e.g. viewer.drawer.canRotate()).
79
+ */
80
+ showRotationControl: {
81
+ type: Boolean,
82
+ attribute: 'show-rotation-control',
83
+ },
84
+ // Constrain during pan
85
+ constrainDuringPan: {
86
+ type: Boolean,
87
+ attribute: 'contrain-during-pan',
88
+ },
89
+ /**
90
+ * The percentage ( as a number from 0 to 1 ) of the source image
91
+ * which must be kept within the viewport.
92
+ * If the image is dragged beyond that limit, it will 'bounce'
93
+ * back until the minimum visibility ratio is achieved.
94
+ * Setting this to 0 and wrapHorizontal ( or wrapVertical )
95
+ * to true will provide the effect of an infinitely scrolling viewport.
96
+ */
97
+ visibilityRatio: {
98
+ type: Number,
99
+ attribute: 'visibility-ratio',
100
+ },
101
+ /**
102
+ * If set, thumbnails of all images are shown in a reference strip at the
103
+ * bottom of the viewer.
104
+ */
105
+ referenceStrip: {
106
+ type: Boolean,
107
+ attribute: 'reference-strip',
108
+ },
109
+ /**
110
+ * Size ratio for the reference strip thumbnails. 0.2 by default.
111
+ */
112
+ referenceStripSizeRatio: {
113
+ type: Number,
114
+ attribute: 'reference-strip-size-ratio',
115
+ },
116
+ /**
117
+ * Type of the source of the image to display: either 'iiif' or 'image'
118
+ * (for simple image links not served via IIIF).
119
+ */
120
+ type: {
121
+ type: String,
122
+ },
123
+ baseUri: {
124
+ type: String,
125
+ attribute: 'base-uri',
126
+ },
127
+ /**
128
+ * Path pointing to the location of openseadragon user interface images.
129
+ */
130
+ prefixUrl: {
131
+ type: String,
132
+ attribute: 'prefix-url',
133
+ },
134
+ /**
135
+ * Array of facsimiles
136
+ *
137
+ */
138
+ facsimiles: {
139
+ type: Array,
140
+ },
141
+ /**
142
+ * Will be true if images were loaded for display, false if there are no images
143
+ * to show.
144
+ */
145
+ loaded: {
146
+ type: Boolean,
147
+ reflect: true,
148
+ },
149
+ /**
150
+ * CORS (Cross-Origin Resource Sharing) policy - wraps the OSD Viewer option -
151
+ * only sensible values are 'anonymous' (default) or 'use-credentials'.
152
+ */
153
+ crossOriginPolicy: {
154
+ type: String,
155
+ attribute: 'cors',
156
+ },
157
+ };
158
+ }
159
+
160
+ constructor() {
161
+ super();
162
+ this._facsimiles = [];
163
+ this.baseUri = '';
164
+ this.crossOriginPolicy = 'anonymous';
165
+ this.type = 'iiif';
166
+ this.visibilityRatio = 1;
167
+ this.defaultZoomLevel = 0;
168
+ this.sequenceMode = false;
169
+ this.showHomeControl = false;
170
+ this.showNavigator = false;
171
+ this.showNavigationControl = false;
172
+ this.showFullPageControl = false;
173
+ this.showRotationControl = false;
174
+ this.showDownloadButton = false;
175
+ this.constrainDuringPan = false;
176
+ this.referenceStrip = false;
177
+ this.referenceStripSizeRatio = 0.2;
178
+ this.prefixUrl = '../images/openseadragon/';
179
+ this.loaded = false;
180
+ }
181
+
182
+ set facsimiles(facs) {
183
+ this._facsimiles = facs || [];
184
+ this.loaded = this._facsimiles.length > 0;
185
+ this.emitTo('pb-facsimile-status', { status: 'loading' });
186
+ }
187
+
188
+ connectedCallback() {
189
+ super.connectedCallback();
190
+ this.subscribeTo('pb-start-update', this._clearAll.bind(this));
191
+ this.subscribeTo('pb-load-facsimile', e => {
192
+ const { element, order } = e.detail;
193
+ const itemOrder = this._facsimiles.map(item =>
194
+ item.getOrder ? item.getOrder() : Number.POSITIVE_INFINITY,
195
+ );
196
+ const insertAt = itemOrder.reduce((result, next, index) => {
197
+ if (order < next) return result;
198
+ if (order === next) return index;
199
+ return index + 1;
200
+ }, 0);
201
+
202
+ this._facsimiles.splice(insertAt, 0, element);
203
+ this.loaded = this._facsimiles.length > 0;
204
+
205
+ this._facsimileObserver();
206
+ });
207
+ this.subscribeTo('pb-show-annotation', this._showAnnotationListener.bind(this));
208
+ }
209
+
210
+ firstUpdated() {
211
+ try {
212
+ window.ESGlobalBridge.requestAvailability();
213
+ const path = resolveURL('../lib/openseadragon.min.js');
214
+ window.ESGlobalBridge.instance.load('openseadragon', path);
215
+ window.addEventListener(
216
+ 'es-bridge-openseadragon-loaded',
217
+ this._initOpenSeadragon.bind(this),
218
+ { once: true },
219
+ );
220
+ } catch (error) {
221
+ console.error(error.message);
158
222
  }
159
-
160
- constructor() {
161
- super();
162
- this._facsimiles = [];
163
- this.baseUri = '';
164
- this.crossOriginPolicy = 'anonymous';
165
- this.type = 'iiif';
166
- this.visibilityRatio = 1;
167
- this.defaultZoomLevel = 0;
168
- this.sequenceMode = false;
169
- this.showHomeControl = false;
170
- this.showNavigator = false;
171
- this.showNavigationControl = false;
172
- this.showFullPageControl = false;
173
- this.showRotationControl = false;
174
- this.showDownloadButton = false;
175
- this.constrainDuringPan = false;
176
- this.referenceStrip = false;
177
- this.referenceStripSizeRatio = 0.2;
178
- this.prefixUrl = '../images/openseadragon/';
179
- this.loaded = false;
180
- }
181
-
182
- set facsimiles(facs) {
183
- this._facsimiles = facs || [];
184
- this.loaded = this._facsimiles.length > 0;
185
- this.emitTo('pb-facsimile-status', { status: 'loading' });
186
- }
187
-
188
- connectedCallback() {
189
- super.connectedCallback();
190
- this.subscribeTo('pb-start-update', this._clearAll.bind(this));
191
- this.subscribeTo('pb-load-facsimile', (e) => {
192
- const { element, order } = e.detail
193
- const itemOrder = this._facsimiles.map(item => item.getOrder ? item.getOrder() : Number.POSITIVE_INFINITY )
194
- const insertAt = itemOrder.reduce((result, next, index) => {
195
- if (order < next) return result;
196
- if (order === next) return index;
197
- return index + 1;
198
- }, 0)
199
-
200
- this._facsimiles.splice(insertAt, 0, element)
201
- this.loaded = this._facsimiles.length > 0;
202
-
203
- this._facsimileObserver()
204
- });
205
- this.subscribeTo('pb-show-annotation', this._showAnnotationListener.bind(this));
223
+ }
224
+
225
+ render() {
226
+ return html`
227
+ <slot name="before"></slot>
228
+ <!-- Openseadragon -->
229
+
230
+ <div id="viewer" part="image"></div>
231
+ <slot name="after"></slot>
232
+ ${this.showDownloadButton ? html`<a id="downloadBtn" title="Download">&#8676;</a>` : ''}
233
+ `;
234
+ }
235
+
236
+ static get styles() {
237
+ return css`
238
+ :host {
239
+ display: flex;
240
+ flex-direction: column;
241
+ position: relative;
242
+ background: transparent;
243
+ }
244
+
245
+ #runtime-overlay {
246
+ border: var(--pb-facsimile-border, 4px solid rgba(0, 0, 128, 0.5));
247
+ }
248
+
249
+ #viewer {
250
+ flex: 1;
251
+ position: relative;
252
+ max-height: var(--pb-facsimile-height, auto);
253
+ width: 100%;
254
+ }
255
+ #downloadBtn {
256
+ position: absolute;
257
+ z-index: 100;
258
+ bottom: 0.25rem;
259
+ width: 1.35rem;
260
+ height: 1.35rem;
261
+ transform: rotate(-90deg);
262
+ cursor: pointer;
263
+ border: thin solid #d7dde8;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ border-radius: 0.75rem;
268
+ background-image: linear-gradient(to left, #fafafa 0%, #d7dde8 51%, #bbbbbb 100%);
269
+ font-size: 1.2rem;
270
+ box-shadow: -2px 1px 5px 0px rgba(0, 0, 0, 0.75);
271
+ }
272
+ #downloadBtn:hover {
273
+ background-image: radial-gradient(white, #efefef);
274
+ }
275
+ `;
276
+ }
277
+
278
+ // Init openseadragon
279
+ _initOpenSeadragon() {
280
+ const prefixUrl = resolveURL(this.prefixUrl + (this.prefixUrl.endsWith('/') ? '' : '/'));
281
+ const options = {
282
+ element: this.shadowRoot.getElementById('viewer'),
283
+ prefixUrl,
284
+ preserveViewport: true,
285
+ showZoomControl: true,
286
+ sequenceMode: this.showSequenceMode,
287
+ showHomeControl: this.showHomeControl,
288
+ showFullPageControl: this.showFullPageControl,
289
+ showNavigator: this.showNavigator,
290
+ showNavigationControl: this.showNavigationControl,
291
+ showRotationControl: this.showRotationControl,
292
+ autoHideControls: false,
293
+ visibilityRatio: 1,
294
+ minZoomLevel: 1,
295
+ defaultZoomLevel: this.defaultZoomLevel,
296
+ constrainDuringPan: true,
297
+ crossOriginPolicy: this.crossOriginPolicy,
298
+ };
299
+
300
+ if (this.referenceStrip) {
301
+ options.showReferenceStrip = true;
302
+ options.referenceStripSizeRatio = this.referenceStripSizeRatio;
206
303
  }
304
+ this.viewer = OpenSeadragon(options);
207
305
 
208
- firstUpdated() {
209
- try{
210
- window.ESGlobalBridge.requestAvailability();
211
- const path = resolveURL('../lib/openseadragon.min.js');
212
- window.ESGlobalBridge.instance.load("openseadragon", path);
213
- window.addEventListener(
214
- "es-bridge-openseadragon-loaded",
215
- this._initOpenSeadragon.bind(this),
216
- { once: true }
217
- );
218
- } catch (error){
219
- console.error(error.message);
220
- }
221
- }
222
-
223
- render() {
224
- return html`
225
- <slot name="before"></slot>
226
- <!-- Openseadragon -->
227
-
228
- <div id="viewer" part="image"></div>
229
- <slot name="after"></slot>
230
- ${this.showDownloadButton ?
231
- html`<a id="downloadBtn" title="Download">&#8676;</a>`:''
232
- }
233
-
234
- `;
306
+ if (this.showFullPageControl) {
307
+ this._overrideFullscreenButton();
235
308
  }
236
309
 
237
- static get styles() {
238
- return css`
239
- :host {
240
- display: flex;
241
- flex-direction: column;
242
- position: relative;
243
- background: transparent;
244
- }
245
-
246
- #runtime-overlay {
247
- border: var(--pb-facsimile-border, 4px solid rgba(0, 0, 128, 0.5));
248
- }
249
-
250
- #viewer {
251
- flex: 1;
252
- position: relative;
253
- max-height: var(--pb-facsimile-height, auto);
254
- width: 100%;
255
- }
256
- #downloadBtn{
257
- position: absolute;
258
- z-index: 100;
259
- bottom:0.25rem;
260
- width:1.35rem;
261
- height:1.35rem;
262
- transform:rotate(-90deg);
263
- cursor: pointer;
264
- border: thin solid #D7DDE8;
265
- display: flex;
266
- align-items: center;
267
- justify-content: center;
268
- border-radius:0.75rem;
269
- background-image:linear-gradient(to left, #fafafa 0%, #D7DDE8 51%, #bbbbbb 100%);
270
- font-size:1.2rem;
271
- box-shadow: -2px 1px 5px 0px rgba(0,0,0,0.75);
272
- }
273
- #downloadBtn:hover{
274
- background-image:radial-gradient( white, #efefef);
275
- }
276
- `;
310
+ this.viewer.addHandler('open', () => {
311
+ this.resetZoom();
312
+ this.emitTo('pb-facsimile-status', { status: 'loaded', facsimiles: this._facsimiles });
313
+ });
314
+ this.viewer.addHandler('open-failed', ev => {
315
+ console.error('<pb-facsimile> open failed: %s', ev.message);
316
+ this.loaded = false;
317
+ this.emitTo('pb-facsimile-status', { status: 'fail' });
318
+ });
319
+
320
+ const download = this.shadowRoot.querySelector('#downloadBtn');
321
+ if (this.showDownloadButton) {
322
+ download.addEventListener('click', ev => {
323
+ ev.preventDefault();
324
+ const currentImage = this.viewer.drawer.canvas.toDataURL('image/png');
325
+ const downloadLink = document.createElement('a');
326
+ downloadLink.href = currentImage;
327
+ downloadLink.download = 'download';
328
+ downloadLink.click();
329
+ });
277
330
  }
278
331
 
279
- // Init openseadragon
280
- _initOpenSeadragon() {
281
- const prefixUrl = resolveURL(this.prefixUrl + (this.prefixUrl.endsWith("/") ? "" : "/"));
282
- const options = {
283
- element: this.shadowRoot.getElementById('viewer'),
284
- prefixUrl,
285
- preserveViewport: true,
286
- showZoomControl: true,
287
- sequenceMode: this.showSequenceMode,
288
- showHomeControl: this.showHomeControl,
289
- showFullPageControl: this.showFullPageControl,
290
- showNavigator: this.showNavigator,
291
- showNavigationControl: this.showNavigationControl,
292
- showRotationControl: this.showRotationControl,
293
- autoHideControls: false,
294
- visibilityRatio: 1,
295
- minZoomLevel: 1,
296
- defaultZoomLevel: this.defaultZoomLevel,
297
- constrainDuringPan: true,
298
- crossOriginPolicy: this.crossOriginPolicy
299
- };
300
-
301
- if (this.referenceStrip) {
302
- options.showReferenceStrip = true;
303
- options.referenceStripSizeRatio = this.referenceStripSizeRatio;
304
- }
305
- this.viewer = OpenSeadragon(options);
306
-
307
- this.viewer.addHandler('open', () => {
308
- this.resetZoom();
309
- this.emitTo('pb-facsimile-status', { status: 'loaded', facsimiles: this._facsimiles });
310
- });
311
- this.viewer.addHandler('open-failed', (ev) => {
312
- console.error('<pb-facsimile> open failed: %s', ev.message);
313
- this.loaded = false;
314
- this.emitTo('pb-facsimile-status', { status: 'fail' });
315
- });
316
-
317
- const download = this.shadowRoot.querySelector('#downloadBtn');
318
- if(this.showDownloadButton){
319
- download.addEventListener('click', (ev) => {
320
- ev.preventDefault();
321
- const currentImage = this.viewer.drawer.canvas.toDataURL("image/png");
322
- const downloadLink = document.createElement('a');
323
- downloadLink.href = currentImage;
324
- downloadLink.download = 'download';
325
- downloadLink.click();
326
- });
327
- }
328
-
329
- /*
332
+ /*
330
333
  handling of full-screen view requires to hide/unhide the content of body to allow full screen viewer
331
334
  to full-page functionality. Standard OSD completely deletes all body children disconnecting all event-handlers
332
335
  that have been there. This solution just uses style.display to hide/show. Former display value of pb-page
333
336
  will be preserved.
334
337
  */
335
- this.ownerPage = document.querySelector('pb-page');
336
- if(this.ownerPage){
337
- this.pbPageDisplay = window.getComputedStyle(this.ownerPage).getPropertyValue('display');
338
- this.viewer.addHandler('full-screen', (ev) => {
339
- if(ev.fullScreen){
340
- this.ownerPage.style.display = 'none';
341
- }else{
342
- this.viewer.clearOverlays();
343
- this.emitTo('pb-refresh');
344
- this.ownerPage.style.display = this.pbPageDisplay;
345
- }
346
- });
338
+ this.ownerPage = document.querySelector('pb-page');
339
+ if (this.ownerPage) {
340
+ this.pbPageDisplay = window.getComputedStyle(this.ownerPage).getPropertyValue('display');
341
+ this.viewer.addHandler('full-screen', ev => {
342
+ if (ev.fullScreen) {
343
+ this.ownerPage.style.display = 'none';
344
+ } else {
345
+ this.viewer.clearOverlays();
346
+ this.emitTo('pb-refresh');
347
+ this.ownerPage.style.display = this.pbPageDisplay;
347
348
  }
348
- this._facsimileObserver();
349
-
350
- this.signalReady();
349
+ });
351
350
  }
351
+ this._facsimileObserver();
352
352
 
353
- _facsimileObserver() {
354
- if (!this.viewer) {
355
- return;
356
- }
357
- if (this._facsimiles.length === 0) {
358
- return this.viewer.close()
359
- }
360
- const uris = this._facsimiles.map(facsLink => {
361
- const url = this.baseUri + (facsLink.getImage ? facsLink.getImage() : facsLink)
362
- if (this.type === 'iiif') {
363
- return `${url}/info.json`;
364
- }
365
- return {
366
- tileSource: {
367
- type: 'image',
368
- url,
369
- buildPyramid: false
370
- }
371
- }
372
- });
373
-
374
- this.viewer.open(uris)
375
- this.viewer.goToPage(0)
376
- }
353
+ this.signalReady();
354
+ }
377
355
 
378
- _clearAll() {
379
- if (!this.viewer) {
380
- return;
381
- }
382
- this.resetZoom();
383
- this.viewer.clearOverlays();
384
- this.facsimiles = [];
356
+ _facsimileObserver() {
357
+ if (!this.viewer) {
358
+ return;
385
359
  }
360
+ if (this._facsimiles.length === 0) {
361
+ return this.viewer.close();
362
+ }
363
+ const uris = this._facsimiles.map(facsLink => {
364
+ const url = this.baseUri + (facsLink.getImage ? facsLink.getImage() : facsLink);
365
+ if (this.type === 'iiif') {
366
+ return `${url}/info.json`;
367
+ }
368
+ return {
369
+ tileSource: {
370
+ type: 'image',
371
+ url,
372
+ buildPyramid: false,
373
+ },
374
+ };
375
+ });
376
+
377
+ this.viewer.open(uris);
378
+ this.viewer.goToPage(0);
379
+ }
380
+
381
+ _clearAll() {
382
+ if (!this.viewer) {
383
+ return;
384
+ }
385
+ this.resetZoom();
386
+ this.viewer.clearOverlays();
387
+ this.facsimiles = [];
388
+ }
389
+
390
+ _showAnnotationListener(event) {
391
+ if (!this.viewer) {
392
+ return;
393
+ }
394
+ const overlayId = 'runtime-overlay';
386
395
 
387
- _showAnnotationListener(event) {
388
- if (!this.viewer) {
389
- return;
390
- }
391
- const overlayId = 'runtime-overlay'
392
-
393
- // remove old overlay
394
- this.viewer.removeOverlay(this.overlay);
395
-
396
- // check event data for completeness
397
- if (!event.detail.file || event.detail.file === 0) {
398
- return console.error('file missing', event.detail)
399
- }
400
-
401
- if (
402
- event.detail.coordinates &&
403
- (!event.detail.coordinates[0] ||
404
- event.detail.coordinates.length !== 4)
405
- ) {
406
- return console.error('coords incomplete or missing', event.detail)
407
- }
396
+ // remove old overlay
397
+ this.viewer.removeOverlay(this.overlay);
408
398
 
409
- // find page to show
410
- const page = event.detail.element ? this._pageByElement(event.detail.element) : this._pageIndexByUrl(event.detail.file);
399
+ // check event data for completeness
400
+ if (!event.detail.file || event.detail.file === 0) {
401
+ return console.error('file missing', event.detail);
402
+ }
411
403
 
412
- if (page < 0) {
413
- return console.error('page not found', event.detail)
414
- }
404
+ if (
405
+ event.detail.coordinates &&
406
+ (!event.detail.coordinates[0] || event.detail.coordinates.length !== 4)
407
+ ) {
408
+ return console.error('coords incomplete or missing', event.detail);
409
+ }
415
410
 
416
- if (this.viewer.currentPage() !== page) {
417
- this.viewer.goToPage(page);
418
- }
411
+ // find page to show
412
+ const page = event.detail.element
413
+ ? this._pageByElement(event.detail.element)
414
+ : this._pageIndexByUrl(event.detail.file);
419
415
 
420
- if (event.detail.coordinates) {
421
- // deconstruct given coordinates into variables
422
- const [x1, y1, w, h] = event.detail.coordinates;
423
- const tiledImage = this.viewer.world.getItemAt(0);
424
- const currentRect = tiledImage.viewportToImageRectangle(
425
- tiledImage.getBounds(true));
426
-
427
- // scroll into view?
428
- if (!currentRect.containsPoint(new OpenSeadragon.Point(x1, y1))) {
429
- this.viewer.viewport.fitBoundsWithConstraints(
430
- tiledImage.imageToViewportRectangle(x1, y1, currentRect.width, currentRect.height));
431
- }
432
-
433
- // create new overlay
434
- const overlay = document.createElement('div');
435
- this.overlay = overlay
436
- overlay.id = overlayId;
437
-
438
- // place marker
439
- const marker = tiledImage.imageToViewportRectangle(x1, y1, w, h);
440
-
441
- this.viewer.addOverlay({
442
- element: overlay,
443
- location: marker
444
- });
445
- }
416
+ if (page < 0) {
417
+ return console.error('page not found', event.detail);
446
418
  }
447
419
 
448
- _pageByElement(element) {
449
- return this._facsimiles.indexOf(element);
420
+ if (this.viewer.currentPage() !== page) {
421
+ this.viewer.goToPage(page);
450
422
  }
451
423
 
452
- _pageIndexByUrl(file) {
453
- return this._facsimiles.findIndex(element => element.getImage() === file);
424
+ if (event.detail.coordinates) {
425
+ // deconstruct given coordinates into variables
426
+ const [x1, y1, w, h] = event.detail.coordinates;
427
+ const tiledImage = this.viewer.world.getItemAt(0);
428
+ const currentRect = tiledImage.viewportToImageRectangle(tiledImage.getBounds(true));
429
+
430
+ // scroll into view?
431
+ if (!currentRect.containsPoint(new OpenSeadragon.Point(x1, y1))) {
432
+ this.viewer.viewport.fitBoundsWithConstraints(
433
+ tiledImage.imageToViewportRectangle(x1, y1, currentRect.width, currentRect.height),
434
+ );
435
+ }
436
+
437
+ // create new overlay
438
+ const overlay = document.createElement('div');
439
+ this.overlay = overlay;
440
+ overlay.id = overlayId;
441
+
442
+ // place marker
443
+ const marker = tiledImage.imageToViewportRectangle(x1, y1, w, h);
444
+
445
+ this.viewer.addOverlay({
446
+ element: overlay,
447
+ location: marker,
448
+ });
454
449
  }
450
+ }
455
451
 
456
- // reset zoom
457
- resetZoom() {
458
- if (!this.viewer) {
459
- return;
460
- }
461
- this.viewer.viewport.goHome();
462
- }
452
+ _pageByElement(element) {
453
+ return this._facsimiles.indexOf(element);
454
+ }
463
455
 
456
+ _pageIndexByUrl(file) {
457
+ return this._facsimiles.findIndex(element => element.getImage() === file);
458
+ }
464
459
 
460
+ // reset zoom
461
+ resetZoom() {
462
+ if (!this.viewer) {
463
+ return;
464
+ }
465
+ this.viewer.viewport.goHome();
466
+ }
467
+
468
+ _overrideFullscreenButton() {
469
+ // The full page control in OSD makes all body elements disappear, causing all kinds of bugs in
470
+ // our webcomponents. Replace it with something that just calls `requestFullScreen` instead.
471
+ // This approach (but more elaborate) is also PR-ed to OSD
472
+ // (https://github.com/openseadragon/openseadragon/pull/2786). This code can be dropped the
473
+ // moment we upgrade to OSD.
474
+
475
+ const toggleFullscreenButton = this.viewer.buttonGroup.buttons.find(
476
+ button => button.tooltip === 'Toggle full page',
477
+ );
478
+ if (!toggleFullscreenButton) {
479
+ return;
480
+ }
481
+ const releaseHandler = async () => {
482
+ if (!document.fullscreenElement) {
483
+ await this.viewer.element.requestFullscreen();
484
+ return;
485
+ }
486
+ await document.exitFullscreen();
487
+ };
488
+
489
+ toggleFullscreenButton.onRelease = releaseHandler;
490
+ const oldRaiseEvent = toggleFullscreenButton.raiseEvent;
491
+ toggleFullscreenButton.raiseEvent = (eventName, args) => {
492
+ if (eventName === 'release') {
493
+ releaseHandler();
494
+ } else {
495
+ oldRaiseEvent.call(toggleFullscreenButton, eventName, args);
496
+ }
497
+ };
498
+ }
465
499
  }
466
500
  if (!customElements.get('pb-facsimile')) {
467
- customElements.define('pb-facsimile', PbFacsimile);
501
+ customElements.define('pb-facsimile', PbFacsimile);
468
502
  }