@teipublisher/pb-components 2.26.1-next.2 → 3.0.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.
- package/.github/workflows/main.yml +3 -3
- package/.github/workflows/node.js.yml +3 -3
- package/.github/workflows/release.js.yml +4 -4
- package/.releaserc.json +2 -2
- package/CHANGELOG.md +267 -9
- package/Dockerfile +78 -70
- package/css/components.css +5 -5
- package/css/leaflet/images/layers.png +0 -0
- package/dist/demo/components.css +46 -1
- package/dist/demo/pb-browse-docs2.html +1 -1
- package/dist/demo/pb-dialog.html +3 -5
- package/dist/demo/pb-drawer2.html +1 -1
- package/dist/demo/pb-facsimile.html +2 -2
- package/dist/demo/pb-grid.html +19 -6
- package/dist/demo/pb-leaflet-map.html +1 -1
- package/dist/demo/pb-login.html +0 -2
- package/dist/demo/pb-message.html +1 -2
- package/dist/demo/pb-progress.html +2 -2
- package/dist/demo/pb-repeat.html +1 -3
- package/dist/demo/pb-search.html +7 -4
- package/dist/demo/pb-search3.html +1 -1
- package/dist/demo/pb-search4.html +2 -2
- package/dist/demo/pb-view3.html +1 -1
- package/dist/{iron-form-3b8dcaa7.js → iron-form-dfb3e3b1.js} +95 -95
- package/dist/paper-checkbox-645e1077.js +200 -0
- package/dist/{paper-icon-button-b1d31571.js → paper-icon-button-984162bd.js} +1 -1
- package/dist/{paper-checkbox-515a5284.js → paper-inky-focus-behavior-fa16796b.js} +58 -247
- package/dist/{paper-listbox-a3b7175c.js → paper-listbox-5f5d1cec.js} +152 -162
- package/dist/pb-code-editor.js +25 -20
- package/dist/pb-component-docs.js +68 -64
- package/dist/pb-components-bundle.js +1983 -2293
- package/dist/pb-edit-app.js +167 -107
- package/dist/pb-elements.json +176 -120
- package/dist/{pb-i18n-0611135a.js → pb-i18n-4cc00bfe.js} +1 -1
- package/dist/pb-leaflet-map.js +23 -23
- package/dist/pb-mei.js +56 -41
- package/dist/{pb-mixin-b1caa22e.js → pb-mixin-886ece32.js} +1 -1
- package/dist/pb-odd-editor.js +1023 -782
- package/dist/pb-tify.js +2 -2
- package/dist/vaadin-element-mixin-beb74ffd.js +545 -0
- package/gh-pages.js +5 -3
- package/i18n/common/en.json +6 -0
- package/i18n/common/pl.json +2 -2
- package/lib/openseadragon.min.js +6 -6
- package/package.json +3 -3
- package/pb-elements.json +176 -120
- package/src/assets/components.css +5 -5
- package/src/authority/airtable.js +20 -21
- package/src/authority/anton.js +129 -129
- package/src/authority/custom.js +23 -21
- package/src/authority/geonames.js +38 -32
- package/src/authority/gnd.js +50 -42
- package/src/authority/kbga.js +137 -134
- package/src/authority/metagrid.js +44 -46
- package/src/authority/reconciliation.js +66 -67
- package/src/authority/registry.js +4 -4
- package/src/docs/pb-component-docs.js +2 -2
- package/src/docs/pb-component-view.js +5 -5
- package/src/docs/pb-components-list.js +2 -2
- package/src/docs/pb-demo-snippet.js +2 -2
- package/src/dts-client.js +299 -297
- package/src/dts-select-endpoint.js +90 -82
- package/src/parse-date-service.js +184 -135
- package/src/pb-ajax.js +158 -171
- package/src/pb-authority-lookup.js +191 -156
- package/src/pb-autocomplete.js +292 -280
- package/src/pb-blacklab-highlight.js +264 -259
- package/src/pb-blacklab-results.js +236 -221
- package/src/pb-browse-docs.js +540 -475
- package/src/pb-browse.js +68 -65
- package/src/pb-clipboard.js +79 -76
- package/src/pb-code-editor.js +110 -102
- package/src/pb-code-highlight.js +209 -204
- package/src/pb-codepen.js +79 -72
- package/src/pb-collapse.js +211 -151
- package/src/pb-combo-box.js +190 -190
- package/src/pb-components-bundle.js +1 -1
- package/src/pb-components.js +1 -0
- package/src/pb-custom-form.js +173 -153
- package/src/pb-dialog.js +98 -62
- package/src/pb-document.js +89 -90
- package/src/pb-download.js +212 -196
- package/src/pb-drawer.js +145 -148
- package/src/pb-edit-app.js +301 -229
- package/src/pb-edit-xml.js +100 -97
- package/src/pb-events.js +114 -107
- package/src/pb-facs-link.js +104 -102
- package/src/pb-facsimile.js +474 -410
- package/src/pb-formula.js +151 -153
- package/src/pb-geolocation.js +129 -131
- package/src/pb-grid-action.js +53 -56
- package/src/pb-grid.js +231 -228
- package/src/pb-highlight.js +140 -140
- package/src/pb-hotkeys.js +40 -42
- package/src/pb-i18n.js +101 -104
- package/src/pb-image-strip.js +84 -78
- package/src/pb-lang.js +142 -57
- package/src/pb-leaflet-map.js +488 -485
- package/src/pb-link.js +126 -124
- package/src/pb-load.js +431 -429
- package/src/pb-login.js +299 -244
- package/src/pb-manage-odds.js +352 -336
- package/src/pb-map-icon.js +89 -89
- package/src/pb-map-layer.js +85 -85
- package/src/pb-markdown.js +90 -99
- package/src/pb-media-query.js +74 -72
- package/src/pb-mei.js +306 -295
- package/src/pb-message.js +139 -97
- package/src/pb-mixin.js +269 -264
- package/src/pb-navigation.js +80 -95
- package/src/pb-observable.js +38 -38
- package/src/pb-odd-editor.js +1054 -958
- package/src/pb-odd-elementspec-editor.js +349 -298
- package/src/pb-odd-model-editor.js +1075 -909
- package/src/pb-odd-parameter-editor.js +200 -178
- package/src/pb-odd-rendition-editor.js +136 -124
- package/src/pb-page.js +431 -422
- package/src/pb-paginate.js +228 -179
- package/src/pb-panel.js +198 -182
- package/src/pb-popover-themes.js +15 -8
- package/src/pb-popover.js +296 -287
- package/src/pb-print-preview.js +127 -127
- package/src/pb-progress.js +51 -51
- package/src/pb-repeat.js +105 -104
- package/src/pb-restricted.js +84 -77
- package/src/pb-search.js +256 -228
- package/src/pb-select-feature.js +127 -120
- package/src/pb-select-odd.js +132 -124
- package/src/pb-select-template.js +89 -78
- package/src/pb-select.js +251 -227
- package/src/pb-split-list.js +179 -174
- package/src/pb-svg.js +80 -79
- package/src/pb-table-column.js +54 -54
- package/src/pb-table-grid.js +221 -203
- package/src/pb-tabs.js +61 -63
- package/src/pb-tify.js +154 -154
- package/src/pb-timeline.js +382 -249
- package/src/pb-toggle-feature.js +195 -187
- package/src/pb-upload.js +184 -174
- package/src/pb-version.js +30 -30
- package/src/pb-view-annotate.js +135 -98
- package/src/pb-view.js +1282 -1270
- package/src/pb-zoom.js +127 -45
- package/src/polymer-hack.js +1 -1
- package/src/search-result-service.js +256 -223
- package/src/seed-element.js +13 -20
- package/src/settings.js +4 -4
- package/src/theming.js +98 -91
- package/src/urls.js +289 -289
- package/src/utils.js +53 -51
- package/css/pb-styles.css +0 -51
- package/dist/vaadin-element-mixin-6e4cee3a.js +0 -527
- package/src/assets/pb-styles.css +0 -51
- package/src/pb-light-dom.js +0 -40
package/src/pb-view.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { LitElement, html, css } from 'lit-element';
|
|
2
2
|
import anime from 'animejs';
|
|
3
|
-
import { pbMixin, waitOnce } from
|
|
4
|
-
import { registry } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { loadStylesheets, themableMixin } from "./theming.js";
|
|
3
|
+
import { pbMixin, waitOnce } from './pb-mixin.js';
|
|
4
|
+
import { registry } from './urls.js';
|
|
5
|
+
import { typesetMath } from './pb-formula.js';
|
|
6
|
+
import { loadStylesheets, themableMixin } from './theming.js';
|
|
8
7
|
import '@polymer/iron-ajax';
|
|
9
|
-
import '@polymer/paper-dialog';
|
|
10
|
-
import '@polymer/paper-dialog-scrollable';
|
|
11
8
|
|
|
12
9
|
/**
|
|
13
10
|
* This is the main component for viewing text which has been transformed via an ODD.
|
|
14
11
|
* The document to be viewed is determined by the `pb-document` element the property
|
|
15
12
|
* `src` points to. If not overwritten, `pb-view` will use the settings defined by
|
|
16
13
|
* the connected document, like view type, ODD etc.
|
|
17
|
-
*
|
|
14
|
+
*
|
|
18
15
|
* `pb-view` can display an entire document or just a fragment of it
|
|
19
16
|
* as defined by the properties `xpath`, `xmlId` or `nodeId`. The most common use case
|
|
20
17
|
* is to set `xpath` to point to a specific part of a document.
|
|
21
|
-
*
|
|
18
|
+
*
|
|
22
19
|
* Navigating to the next or previous fragment would usually be triggered by a separate
|
|
23
20
|
* `pb-navigation` element, which sends a `pb-navigate` event to the `pb-view`. However,
|
|
24
21
|
* `pb-view` also implements automatic loading of next/previous fragments if the user
|
|
@@ -50,1368 +47,1383 @@ import '@polymer/paper-dialog-scrollable';
|
|
|
50
47
|
* @cssprop --pb-view-scroll-margin-top - Applied to any element with an id
|
|
51
48
|
* @csspart content - The root div around the displayed content
|
|
52
49
|
* @csspart footnotes - div containing the footnotes
|
|
53
|
-
|
|
50
|
+
|
|
54
51
|
* @fires pb-start-update - Fired before the element updates its content
|
|
55
52
|
* @fires pb-update - Fired when the component received content from the server
|
|
56
53
|
* @fires pb-end-update - Fired after the element has finished updating its content
|
|
57
54
|
* @fires pb-navigate - When received, navigate forward or backward in the document
|
|
58
|
-
* @fires pb-zoom - When received, zoom in or out by changing font size of the content
|
|
59
55
|
* @fires pb-refresh - When received, refresh the content based on the parameters passed in the event
|
|
60
56
|
* @fires pb-toggle - When received, toggle content properties
|
|
61
57
|
*/
|
|
62
58
|
export class PbView extends themableMixin(pbMixin(LitElement)) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
59
|
+
static get properties() {
|
|
60
|
+
return {
|
|
61
|
+
/**
|
|
62
|
+
* The id of a `pb-document` element this view should display.
|
|
63
|
+
* Settings like `odd` or `view` will be taken from the `pb-document`
|
|
64
|
+
* unless overwritten by properties in this component.
|
|
65
|
+
*
|
|
66
|
+
* This property is **required** and **must** point to an existing `pb-document` with
|
|
67
|
+
* the given id.
|
|
68
|
+
*
|
|
69
|
+
* Setting the property after initialization will clear the properties xmlId, nodeId and odd.
|
|
70
|
+
*/
|
|
71
|
+
src: {
|
|
72
|
+
type: String,
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* The ODD to use for rendering the document. Overwrites an ODD defined on
|
|
76
|
+
* `pb-document`. The odd should be specified by its name without path
|
|
77
|
+
* or the `.odd` suffix.
|
|
78
|
+
*/
|
|
79
|
+
odd: {
|
|
80
|
+
type: String,
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* The view type to use for paginating the document. Either `page`, `div` or `single`.
|
|
84
|
+
* Overwrites the same property specified on `pb-document`. Values have the following meaning:
|
|
85
|
+
*
|
|
86
|
+
* Value | Displayed content
|
|
87
|
+
* ------|------------------
|
|
88
|
+
* `page` | content is displayed page by page as determined by tei:pb
|
|
89
|
+
* `div` | content is displayed by divisions
|
|
90
|
+
* `single` | do not paginate but display entire content at once
|
|
91
|
+
*/
|
|
92
|
+
view: {
|
|
93
|
+
type: String,
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* Controls the pagination-by-div algorithm: if a page would have less than
|
|
97
|
+
* `fill` elements, it tries to fill
|
|
98
|
+
* up the page by pulling following divs in. When set to 0, it will never
|
|
99
|
+
* attempt to fill up the page. For the annotation editor this should
|
|
100
|
+
* always be 0.
|
|
101
|
+
*/
|
|
102
|
+
fill: {
|
|
103
|
+
type: Number,
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* An eXist nodeId. If specified, selects the root of the fragment of the document
|
|
107
|
+
* which should be displayed. Normally this property is set automatically by pagination.
|
|
108
|
+
*/
|
|
109
|
+
nodeId: {
|
|
110
|
+
type: String,
|
|
111
|
+
attribute: 'node-id',
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* An xml:id to be displayed. If specified, this determines the root of the fragment to be
|
|
115
|
+
* displayed. Use to directly navigate to a specific section.
|
|
116
|
+
*/
|
|
117
|
+
xmlId: {
|
|
118
|
+
type: Array,
|
|
119
|
+
attribute: 'xml-id',
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* An optional XPath expression: the root of the fragment to be processed is determined
|
|
123
|
+
* by evaluating the given XPath expression. The XPath expression should be absolute.
|
|
124
|
+
* The namespace of the document is declared as default namespace, so no prefixes should
|
|
125
|
+
* be used.
|
|
126
|
+
*
|
|
127
|
+
* If the `map` property is used, it may change scope for the displayed fragment.
|
|
128
|
+
*/
|
|
129
|
+
xpath: {
|
|
130
|
+
type: String,
|
|
131
|
+
},
|
|
132
|
+
/**
|
|
133
|
+
* If defined denotes the local name of an XQuery function in `modules/map.xql`, which will be called
|
|
134
|
+
* with the current root node and should return the node of a mapped fragment. This is helpful if one
|
|
135
|
+
* wants, for example, to show a translation fragment aligned with the part of the transcription currently
|
|
136
|
+
* shown. In this case, the properties of the `pb-view` would still point to the transcription, but the function
|
|
137
|
+
* identified by map would return the corresponding fragment from the translation to be processed.
|
|
138
|
+
*
|
|
139
|
+
* Navigation in the document is still determined by the current root as defined through the `root`, `xpath`
|
|
140
|
+
* and `xmlId` properties.
|
|
141
|
+
*/
|
|
142
|
+
map: {
|
|
143
|
+
type: String,
|
|
144
|
+
},
|
|
145
|
+
/**
|
|
146
|
+
* If set to true, the component will not load automatically. Instead it will wait until it receives a `pb-update`
|
|
147
|
+
* event. Use this to make one `pb-view` component dependent on another one. Default is 'false'.
|
|
148
|
+
*/
|
|
149
|
+
onUpdate: {
|
|
150
|
+
type: Boolean,
|
|
151
|
+
attribute: 'on-update',
|
|
152
|
+
},
|
|
153
|
+
/**
|
|
154
|
+
* Message to display if no content was returned by the server.
|
|
155
|
+
* Set to empty string to show nothing.
|
|
156
|
+
*/
|
|
157
|
+
notFound: {
|
|
158
|
+
type: String,
|
|
159
|
+
attribute: 'not-found',
|
|
160
|
+
},
|
|
161
|
+
/**
|
|
162
|
+
* The relative URL to the script on the server which will be called for loading content.
|
|
163
|
+
*/
|
|
164
|
+
url: {
|
|
165
|
+
type: String,
|
|
166
|
+
},
|
|
167
|
+
/**
|
|
168
|
+
* If set, rewrite URLs to load pages as static HTML files,
|
|
169
|
+
* so no TEI Publisher instance is required. Use this in combination with
|
|
170
|
+
* [tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).
|
|
171
|
+
* The value should point to the HTTP root path under which the static version
|
|
172
|
+
* will be hosted. This is used to resolve CSS stylesheets.
|
|
173
|
+
*/
|
|
174
|
+
static: {
|
|
175
|
+
type: String,
|
|
176
|
+
},
|
|
177
|
+
/**
|
|
178
|
+
* The server returns footnotes separately. Set this property
|
|
179
|
+
* if you wish to append them to the main text.
|
|
180
|
+
*/
|
|
181
|
+
appendFootnotes: {
|
|
182
|
+
type: Boolean,
|
|
183
|
+
attribute: 'append-footnotes',
|
|
184
|
+
},
|
|
185
|
+
/**
|
|
186
|
+
* Should matches be highlighted if a search has been executed?
|
|
187
|
+
*/
|
|
188
|
+
suppressHighlight: {
|
|
189
|
+
type: Boolean,
|
|
190
|
+
attribute: 'suppress-highlight',
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* CSS selector to find column breaks in the content returned
|
|
194
|
+
* from the server. If this property is set and column breaks
|
|
195
|
+
* are found, the component will display two columns side by side.
|
|
196
|
+
*/
|
|
197
|
+
columnSeparator: {
|
|
198
|
+
type: String,
|
|
199
|
+
attribute: 'column-separator',
|
|
200
|
+
},
|
|
201
|
+
/**
|
|
202
|
+
* The reading direction, i.e. 'ltr' or 'rtl'.
|
|
203
|
+
*
|
|
204
|
+
* @type {"ltr"|"rtl"}
|
|
205
|
+
*/
|
|
206
|
+
direction: {
|
|
207
|
+
type: String,
|
|
208
|
+
},
|
|
209
|
+
/**
|
|
210
|
+
* If set, points to an external stylesheet which should be applied to
|
|
211
|
+
* the text *after* the ODD-generated styles.
|
|
212
|
+
*/
|
|
213
|
+
loadCss: {
|
|
214
|
+
type: String,
|
|
215
|
+
attribute: 'load-css',
|
|
216
|
+
},
|
|
217
|
+
/**
|
|
218
|
+
* If set, relative links (img, a) will be made absolute.
|
|
219
|
+
*/
|
|
220
|
+
fixLinks: {
|
|
221
|
+
type: Boolean,
|
|
222
|
+
attribute: 'fix-links',
|
|
223
|
+
},
|
|
224
|
+
/**
|
|
225
|
+
* If set, a refresh will be triggered if a `pb-i18n-update` event is received,
|
|
226
|
+
* e.g. due to the user selecting a different interface language.
|
|
227
|
+
*
|
|
228
|
+
* Also requires `requireLanguage` to be set on the surrounding `pb-page`.
|
|
229
|
+
* See there for more information.
|
|
230
|
+
*/
|
|
231
|
+
useLanguage: {
|
|
232
|
+
type: Boolean,
|
|
233
|
+
attribute: 'use-language',
|
|
234
|
+
},
|
|
235
|
+
/**
|
|
236
|
+
* wether to animate the view when new page is loaded. Defaults to 'false' meaning that no
|
|
237
|
+
* animation takes place. If 'true' will apply a translateX transistion in forward/backward direction.
|
|
238
|
+
*/
|
|
239
|
+
animation: {
|
|
240
|
+
type: Boolean,
|
|
241
|
+
},
|
|
242
|
+
/**
|
|
243
|
+
* Experimental: if enabled, the view will incrementally load new document fragments if the user tries to scroll
|
|
244
|
+
* beyond the start or end of the visible text. The feature inserts a small blank section at the top
|
|
245
|
+
* and bottom. If this section becomes visible, a load operation will be triggered.
|
|
246
|
+
*
|
|
247
|
+
* Note: only browsers implementing the `IntersectionObserver` API are supported. Also the feature
|
|
248
|
+
* does not work in two-column mode or with animations.
|
|
249
|
+
*/
|
|
250
|
+
infiniteScroll: {
|
|
251
|
+
type: Boolean,
|
|
252
|
+
attribute: 'infinite-scroll',
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* Maximum number of fragments to keep in memory if `infinite-scroll`
|
|
256
|
+
* is enabled. If the user is scrolling beyond the maximum, fragements
|
|
257
|
+
* will be removed from the DOM before or after the current reading position.
|
|
258
|
+
* Default is 10. Set to zero to allow loading the entire document.
|
|
259
|
+
*/
|
|
260
|
+
infiniteScrollMax: {
|
|
261
|
+
type: Number,
|
|
262
|
+
attribute: 'infinite-scroll-max',
|
|
263
|
+
},
|
|
264
|
+
/**
|
|
265
|
+
* A selector pointing to other components this component depends on.
|
|
266
|
+
* When method `wait` is called, it will wait until all referenced
|
|
267
|
+
* components signal with a `pb-ready` event that they are ready and listening
|
|
268
|
+
* to events.
|
|
269
|
+
*
|
|
270
|
+
* `pb-view` by default sets this property to select `pb-toggle-feature` and `pb-select-feature`
|
|
271
|
+
* elements.
|
|
272
|
+
*/
|
|
273
|
+
waitFor: {
|
|
274
|
+
type: String,
|
|
275
|
+
attribute: 'wait-for',
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* By default, navigating to next/previous page will update browser parameters,
|
|
279
|
+
* so reloading the page will load the correct position within the document.
|
|
280
|
+
*
|
|
281
|
+
* Set this property to disable location tracking for the component altogether.
|
|
282
|
+
*/
|
|
283
|
+
disableHistory: {
|
|
284
|
+
type: Boolean,
|
|
285
|
+
attribute: 'disable-history',
|
|
286
|
+
},
|
|
287
|
+
/**
|
|
288
|
+
* If set to the name of an event, the content of the pb-view will not be replaced
|
|
289
|
+
* immediately upon updates. Instead, an event is emitted, which contains the new content
|
|
290
|
+
* in property `root`. An event handler intercepting the event can thus modify the content.
|
|
291
|
+
* Once it is done, it should pass the modified content to the callback function provided
|
|
292
|
+
* in the event detail under the name `render`. See the demo for an example.
|
|
293
|
+
*/
|
|
294
|
+
beforeUpdate: {
|
|
295
|
+
type: String,
|
|
296
|
+
attribute: 'before-update-event',
|
|
297
|
+
},
|
|
298
|
+
/**
|
|
299
|
+
* If set, do not scroll the view to target node (e.g. given in URL hash)
|
|
300
|
+
* after content was loaded.
|
|
301
|
+
*/
|
|
302
|
+
noScroll: {
|
|
303
|
+
type: Boolean,
|
|
304
|
+
attribute: 'no-scroll',
|
|
305
|
+
},
|
|
306
|
+
_features: {
|
|
307
|
+
type: Object,
|
|
308
|
+
},
|
|
309
|
+
_content: {
|
|
310
|
+
type: Node,
|
|
311
|
+
attribute: false,
|
|
312
|
+
},
|
|
313
|
+
_column1: {
|
|
314
|
+
type: Node,
|
|
315
|
+
attribute: false,
|
|
316
|
+
},
|
|
317
|
+
_column2: {
|
|
318
|
+
type: Node,
|
|
319
|
+
attribute: false,
|
|
320
|
+
},
|
|
321
|
+
_footnotes: {
|
|
322
|
+
type: Node,
|
|
323
|
+
attribute: false,
|
|
324
|
+
},
|
|
325
|
+
_style: {
|
|
326
|
+
type: Node,
|
|
327
|
+
attribute: false,
|
|
328
|
+
},
|
|
329
|
+
_additionalParams: {
|
|
330
|
+
type: Object,
|
|
331
|
+
},
|
|
332
|
+
...super.properties,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
constructor() {
|
|
337
|
+
super();
|
|
338
|
+
this.src = null;
|
|
339
|
+
this.url = null;
|
|
340
|
+
this.onUpdate = false;
|
|
341
|
+
this.appendFootnotes = false;
|
|
342
|
+
this.notFound = null;
|
|
343
|
+
this.animation = false;
|
|
344
|
+
this.direction = 'ltr';
|
|
345
|
+
this.suppressHighlight = false;
|
|
346
|
+
this.highlight = false;
|
|
347
|
+
this.infiniteScrollMax = 10;
|
|
348
|
+
this.disableHistory = false;
|
|
349
|
+
this.beforeUpdate = null;
|
|
350
|
+
this.noScroll = false;
|
|
351
|
+
this._features = {};
|
|
352
|
+
this._additionalParams = {};
|
|
353
|
+
this._selector = {};
|
|
354
|
+
this._chunks = [];
|
|
355
|
+
this._scrollTarget = null;
|
|
356
|
+
this.static = null;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
360
|
+
super.attributeChangedCallback(name, oldVal, newVal);
|
|
361
|
+
switch (name) {
|
|
362
|
+
case 'src':
|
|
363
|
+
this._updateSource(newVal, oldVal);
|
|
364
|
+
break;
|
|
329
365
|
}
|
|
366
|
+
}
|
|
330
367
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
this.src = null;
|
|
334
|
-
this.url = null;
|
|
335
|
-
this.onUpdate = false;
|
|
336
|
-
this.appendFootnotes = false;
|
|
337
|
-
this.notFound = null;
|
|
338
|
-
this.animation = false;
|
|
339
|
-
this.direction = 'ltr';
|
|
340
|
-
this.suppressHighlight = false;
|
|
341
|
-
this.highlight = false;
|
|
342
|
-
this.infiniteScrollMax = 10;
|
|
343
|
-
this.disableHistory = false;
|
|
344
|
-
this.beforeUpdate = null;
|
|
345
|
-
this.noScroll = false;
|
|
346
|
-
this._features = {};
|
|
347
|
-
this._additionalParams = {};
|
|
348
|
-
this._selector = {};
|
|
349
|
-
this._chunks = [];
|
|
350
|
-
this._scrollTarget = null;
|
|
351
|
-
this.static = null;
|
|
352
|
-
}
|
|
368
|
+
connectedCallback() {
|
|
369
|
+
super.connectedCallback();
|
|
353
370
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
371
|
+
if (this.loadCss) {
|
|
372
|
+
waitOnce('pb-page-ready', () => {
|
|
373
|
+
loadStylesheets([this.toAbsoluteURL(this.loadCss)]).then(theme => {
|
|
374
|
+
this.shadowRoot.adoptedStyleSheets = [...this.shadowRoot.adoptedStyleSheets, theme];
|
|
375
|
+
});
|
|
376
|
+
});
|
|
361
377
|
}
|
|
362
378
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
.then((theme) => {
|
|
370
|
-
this.shadowRoot.adoptedStyleSheets = [...this.shadowRoot.adoptedStyleSheets, theme];
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (this.infiniteScroll) {
|
|
376
|
-
this.columnSeparator = null;
|
|
377
|
-
this.animation = false;
|
|
378
|
-
this._content = document.createElement('div');
|
|
379
|
-
this._content.className = 'infinite-content';
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
if (!this.disableHistory) {
|
|
383
|
-
if (registry.state.id && !this.xmlId) {
|
|
384
|
-
this.xmlId = registry.state.id;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (registry.state.action && registry.state.action === 'search') {
|
|
388
|
-
this.highlight = true;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (this.view === 'single') {
|
|
392
|
-
this.nodeId = null;
|
|
393
|
-
} else if (registry.state.root && !this.nodeId) {
|
|
394
|
-
this.nodeId = registry.state.root;
|
|
395
|
-
}
|
|
379
|
+
if (this.infiniteScroll) {
|
|
380
|
+
this.columnSeparator = null;
|
|
381
|
+
this.animation = false;
|
|
382
|
+
this._content = document.createElement('div');
|
|
383
|
+
this._content.className = 'infinite-content';
|
|
384
|
+
}
|
|
396
385
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
386
|
+
if (!this.disableHistory) {
|
|
387
|
+
if (registry.state.id && !this.xmlId) {
|
|
388
|
+
this.xmlId = registry.state.id;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (registry.state.action && registry.state.action === 'search') {
|
|
392
|
+
this.highlight = true;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (this.view === 'single') {
|
|
396
|
+
this.nodeId = null;
|
|
397
|
+
} else if (registry.state.root && !this.nodeId) {
|
|
398
|
+
this.nodeId = registry.state.root;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const newState = {
|
|
402
|
+
id: this.xmlId,
|
|
403
|
+
view: this.getView(),
|
|
404
|
+
odd: this.getOdd(),
|
|
405
|
+
path: this.getDocument().path,
|
|
406
|
+
};
|
|
407
|
+
if (this.view !== 'single') {
|
|
408
|
+
newState.root = this.nodeId;
|
|
409
|
+
}
|
|
410
|
+
if (this.fill) {
|
|
411
|
+
newState.fill = this.fill;
|
|
412
|
+
}
|
|
413
|
+
console.log('id: %s; state: %o', this.id, newState);
|
|
414
|
+
registry.replace(this, newState);
|
|
415
|
+
|
|
416
|
+
registry.subscribe(this, state => {
|
|
417
|
+
this._setState(state);
|
|
418
|
+
this._refresh();
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
if (!this.waitFor) {
|
|
422
|
+
this.waitFor = 'pb-toggle-feature,pb-select-feature,pb-navigation';
|
|
423
|
+
}
|
|
408
424
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
425
|
+
this.subscribeTo('pb-navigate', ev => {
|
|
426
|
+
if (ev.detail.source && ev.detail.source === this) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
this.navigate(ev.detail.direction);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
this.subscribeTo('pb-toggle', ev => {
|
|
433
|
+
this.toggleFeature(ev);
|
|
434
|
+
});
|
|
435
|
+
this.subscribeTo(
|
|
436
|
+
'pb-i18n-update',
|
|
437
|
+
ev => {
|
|
438
|
+
const needsRefresh =
|
|
439
|
+
this._features.language && this._features.language !== ev.detail.language;
|
|
440
|
+
this._features.language = ev.detail.language;
|
|
441
|
+
if (this.useLanguage && needsRefresh) {
|
|
442
|
+
this._setState(registry.getState(this));
|
|
443
|
+
this._refresh();
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
[],
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
this.signalReady();
|
|
450
|
+
|
|
451
|
+
if (this.onUpdate) {
|
|
452
|
+
this.subscribeTo('pb-update', ev => {
|
|
453
|
+
this._refresh(ev);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
417
457
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
458
|
+
disconnectedCallback() {
|
|
459
|
+
super.disconnectedCallback();
|
|
460
|
+
if (this._scrollObserver) {
|
|
461
|
+
this._scrollObserver.disconnect();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
firstUpdated() {
|
|
466
|
+
super.firstUpdated();
|
|
467
|
+
this.enableScrollbar(true);
|
|
468
|
+
if (this.infiniteScroll) {
|
|
469
|
+
this._topObserver = this.shadowRoot.getElementById('top-observer');
|
|
470
|
+
this._bottomObserver = this.shadowRoot.getElementById('bottom-observer');
|
|
471
|
+
this._bottomObserver.style.display = 'none';
|
|
472
|
+
this._topObserver.style.display = 'none';
|
|
473
|
+
this._scrollObserver = new IntersectionObserver(entries => {
|
|
474
|
+
if (!this._content) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
entries.forEach(entry => {
|
|
478
|
+
if (entry.isIntersecting) {
|
|
479
|
+
if (entry.target.id === 'bottom-observer') {
|
|
480
|
+
const lastChild = this._content.lastElementChild;
|
|
481
|
+
if (lastChild) {
|
|
482
|
+
const next = lastChild.getAttribute('data-next');
|
|
483
|
+
if (next && !this._content.querySelector(`[data-root="${next}"]`)) {
|
|
484
|
+
console.log('<pb-view> Loading next page: %s', next);
|
|
485
|
+
this._checkChunks('forward');
|
|
486
|
+
this._load(next, 'forward');
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
} else {
|
|
490
|
+
const firstChild = this._content.firstElementChild;
|
|
491
|
+
if (firstChild) {
|
|
492
|
+
const previous = firstChild.getAttribute('data-previous');
|
|
493
|
+
if (previous && !this._content.querySelector(`[data-root="${previous}"]`)) {
|
|
494
|
+
this._checkChunks('backward');
|
|
495
|
+
this._load(previous, 'backward');
|
|
496
|
+
}
|
|
497
|
+
}
|
|
421
498
|
}
|
|
422
|
-
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (!this.onUpdate) {
|
|
504
|
+
waitOnce('pb-page-ready', data => {
|
|
505
|
+
if (data && data.language) {
|
|
506
|
+
this._features.language = data.language;
|
|
507
|
+
}
|
|
508
|
+
this.wait(() => {
|
|
509
|
+
if (!this.disableHistory) {
|
|
510
|
+
this._setState(registry.state);
|
|
511
|
+
}
|
|
512
|
+
this._refresh();
|
|
423
513
|
});
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
this.subscribeTo('pb-refresh', this._refresh.bind(this));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Returns the ODD used to render content.
|
|
521
|
+
*
|
|
522
|
+
* @returns the ODD being used
|
|
523
|
+
*/
|
|
524
|
+
getOdd() {
|
|
525
|
+
return this.odd || this.getDocument().odd || 'teipublisher';
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
getView() {
|
|
529
|
+
return this.view || this.getDocument().view || 'single';
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Trigger an update of this element's content
|
|
534
|
+
*/
|
|
535
|
+
forceUpdate() {
|
|
536
|
+
this._load(this.nodeId);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
animate() {
|
|
540
|
+
// animate new element if 'animation' property is 'true'
|
|
541
|
+
if (this.animation) {
|
|
542
|
+
if (this.lastDirection === 'forward') {
|
|
543
|
+
anime({
|
|
544
|
+
targets: this.shadowRoot.getElementById('view'),
|
|
545
|
+
opacity: [0, 1],
|
|
546
|
+
translateX: [1000, 0],
|
|
547
|
+
duration: 300,
|
|
548
|
+
easing: 'linear',
|
|
427
549
|
});
|
|
428
|
-
|
|
429
|
-
|
|
550
|
+
} else {
|
|
551
|
+
anime({
|
|
552
|
+
targets: this.shadowRoot.getElementById('view'),
|
|
553
|
+
opacity: [0, 1],
|
|
554
|
+
translateX: [-1000, 0],
|
|
555
|
+
duration: 300,
|
|
556
|
+
easing: 'linear',
|
|
430
557
|
});
|
|
431
|
-
|
|
432
|
-
const needsRefresh = this._features.language && this._features.language !== ev.detail.language;
|
|
433
|
-
this._features.language = ev.detail.language;
|
|
434
|
-
if (this.useLanguage && needsRefresh) {
|
|
435
|
-
this._setState(registry.getState(this));
|
|
436
|
-
this._refresh();
|
|
437
|
-
}
|
|
438
|
-
}, []);
|
|
439
|
-
|
|
440
|
-
this.signalReady();
|
|
441
|
-
|
|
442
|
-
if (this.onUpdate) {
|
|
443
|
-
this.subscribeTo('pb-update', (ev) => {
|
|
444
|
-
this._refresh(ev);
|
|
445
|
-
});
|
|
446
|
-
}
|
|
558
|
+
}
|
|
447
559
|
}
|
|
560
|
+
}
|
|
448
561
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
562
|
+
enableScrollbar(enable) {
|
|
563
|
+
if (enable) {
|
|
564
|
+
this.classList.add('noscroll');
|
|
565
|
+
} else {
|
|
566
|
+
this.classList.remove('noscroll');
|
|
454
567
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
if (entry.isIntersecting) {
|
|
470
|
-
if (entry.target.id === 'bottom-observer') {
|
|
471
|
-
const lastChild = this._content.lastElementChild;
|
|
472
|
-
if (lastChild) {
|
|
473
|
-
const next = lastChild.getAttribute('data-next');
|
|
474
|
-
if (next && !this._content.querySelector(`[data-root="${next}"]`)) {
|
|
475
|
-
console.log('<pb-view> Loading next page: %s', next);
|
|
476
|
-
this._checkChunks('forward');
|
|
477
|
-
this._load(next, 'forward');
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
} else {
|
|
481
|
-
const firstChild = this._content.firstElementChild;
|
|
482
|
-
if (firstChild) {
|
|
483
|
-
const previous = firstChild.getAttribute('data-previous');
|
|
484
|
-
if (previous && !this._content.querySelector(`[data-root="${previous}"]`)) {
|
|
485
|
-
this._checkChunks('backward');
|
|
486
|
-
this._load(previous, 'backward');
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
});
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
if (!this.onUpdate) {
|
|
495
|
-
waitOnce('pb-page-ready', (data) => {
|
|
496
|
-
if (data && data.language) {
|
|
497
|
-
this._features.language = data.language;
|
|
498
|
-
}
|
|
499
|
-
this.wait(() => {
|
|
500
|
-
if (!this.disableHistory) {
|
|
501
|
-
this._setState(registry.state);
|
|
502
|
-
}
|
|
503
|
-
this._refresh();
|
|
504
|
-
});
|
|
505
|
-
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
_refresh(ev) {
|
|
571
|
+
if (ev && ev.detail) {
|
|
572
|
+
if (
|
|
573
|
+
ev.detail.hash &&
|
|
574
|
+
!this.noScroll &&
|
|
575
|
+
!(ev.detail.id || ev.detail.path || ev.detail.odd || ev.detail.view || ev.detail.position)
|
|
576
|
+
) {
|
|
577
|
+
// if only the scroll target has changed: scroll to the element without reloading
|
|
578
|
+
this._scrollTarget = ev.detail.hash;
|
|
579
|
+
const target = this.shadowRoot.getElementById(this._scrollTarget);
|
|
580
|
+
if (target) {
|
|
581
|
+
setTimeout(() => target.scrollIntoView({ block: 'nearest' }));
|
|
506
582
|
}
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
if (ev.detail.path) {
|
|
586
|
+
const doc = this.getDocument();
|
|
587
|
+
doc.path = ev.detail.path;
|
|
588
|
+
}
|
|
589
|
+
if (ev.detail.id) {
|
|
590
|
+
this.xmlId = ev.detail.id;
|
|
591
|
+
} else if (ev.detail.id == null) {
|
|
592
|
+
this.xmlId = null;
|
|
593
|
+
}
|
|
594
|
+
this.odd = ev.detail.odd || this.odd;
|
|
595
|
+
if (ev.detail.columnSeparator !== undefined) {
|
|
596
|
+
this.columnSeparator = ev.detail.columnSeparator;
|
|
597
|
+
}
|
|
598
|
+
this.view = ev.detail.view || this.getView();
|
|
599
|
+
this.fill = ev.detail.fill || this.fill;
|
|
600
|
+
if (ev.detail.xpath) {
|
|
601
|
+
this.xpath = ev.detail.xpath;
|
|
602
|
+
this.nodeId = null;
|
|
603
|
+
}
|
|
604
|
+
// clear nodeId if set to null
|
|
605
|
+
if (ev.detail.root === null) {
|
|
606
|
+
this.nodeId = null;
|
|
607
|
+
} else {
|
|
608
|
+
this.nodeId =
|
|
609
|
+
(ev.detail.position !== undefined ? ev.detail.position : ev.detail.root) || this.nodeId;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// check if the URL template needs any other parameters
|
|
613
|
+
// and set them on this._additionalParams
|
|
614
|
+
registry.pathParams.forEach(key => {
|
|
615
|
+
this._additionalParams[key] = ev.detail[key];
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
if (!this.noScroll) {
|
|
619
|
+
this._scrollTarget = ev.detail.hash;
|
|
620
|
+
}
|
|
507
621
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
*
|
|
512
|
-
* @returns the ODD being used
|
|
513
|
-
*/
|
|
514
|
-
getOdd() {
|
|
515
|
-
return this.odd || this.getDocument().odd || "teipublisher";
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
getView() {
|
|
519
|
-
return this.view || this.getDocument().view || "single";
|
|
622
|
+
this._updateStyles();
|
|
623
|
+
if (this.infiniteScroll) {
|
|
624
|
+
this._clear();
|
|
520
625
|
}
|
|
626
|
+
this._load(this.nodeId);
|
|
627
|
+
}
|
|
521
628
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
*/
|
|
525
|
-
forceUpdate() {
|
|
526
|
-
this._load(this.nodeId);
|
|
629
|
+
_load(pos, direction) {
|
|
630
|
+
const doc = this.getDocument();
|
|
527
631
|
|
|
632
|
+
if (!doc.path) {
|
|
633
|
+
console.log('No path');
|
|
634
|
+
return;
|
|
528
635
|
}
|
|
529
636
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (this.animation) {
|
|
533
|
-
if (this.lastDirection === 'forward') {
|
|
534
|
-
anime({
|
|
535
|
-
targets: this.shadowRoot.getElementById('view'),
|
|
536
|
-
opacity: [0, 1],
|
|
537
|
-
translateX: [1000, 0],
|
|
538
|
-
duration: 300,
|
|
539
|
-
easing: 'linear'
|
|
540
|
-
});
|
|
541
|
-
} else {
|
|
542
|
-
anime({
|
|
543
|
-
targets: this.shadowRoot.getElementById('view'),
|
|
544
|
-
opacity: [0, 1],
|
|
545
|
-
translateX: [-1000, 0],
|
|
546
|
-
duration: 300,
|
|
547
|
-
easing: 'linear'
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
}
|
|
637
|
+
if (this._loading) {
|
|
638
|
+
return;
|
|
551
639
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
} else {
|
|
557
|
-
this.classList.remove('noscroll');
|
|
558
|
-
}
|
|
640
|
+
this._loading = true;
|
|
641
|
+
const params = this.getParameters(pos);
|
|
642
|
+
if (direction) {
|
|
643
|
+
params._dir = direction;
|
|
559
644
|
}
|
|
645
|
+
// this.$.view.style.opacity=0;
|
|
560
646
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
if (ev.detail.hash && !this.noScroll && !(ev.detail.id || ev.detail.path || ev.detail.odd || ev.detail.view || ev.detail.position)) {
|
|
564
|
-
// if only the scroll target has changed: scroll to the element without reloading
|
|
565
|
-
this._scrollTarget = ev.detail.hash;
|
|
566
|
-
const target = this.shadowRoot.getElementById(this._scrollTarget);
|
|
567
|
-
if (target) {
|
|
568
|
-
setTimeout(() => target.scrollIntoView({block: 'nearest'}));
|
|
569
|
-
}
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
if (ev.detail.path) {
|
|
573
|
-
const doc = this.getDocument();
|
|
574
|
-
doc.path = ev.detail.path;
|
|
575
|
-
}
|
|
576
|
-
if (ev.detail.id) {
|
|
577
|
-
this.xmlId = ev.detail.id;
|
|
578
|
-
} else if (ev.detail.id == null) {
|
|
579
|
-
this.xmlId = null;
|
|
580
|
-
}
|
|
581
|
-
this.odd = ev.detail.odd || this.odd;
|
|
582
|
-
if (ev.detail.columnSeparator !== undefined) {
|
|
583
|
-
this.columnSeparator = ev.detail.columnSeparator;
|
|
584
|
-
}
|
|
585
|
-
this.view = ev.detail.view || this.getView();
|
|
586
|
-
if (ev.detail.xpath) {
|
|
587
|
-
this.xpath = ev.detail.xpath;
|
|
588
|
-
this.nodeId = null;
|
|
589
|
-
}
|
|
590
|
-
// clear nodeId if set to null
|
|
591
|
-
if (ev.detail.root === null) {
|
|
592
|
-
this.nodeId = null;
|
|
593
|
-
} else {
|
|
594
|
-
this.nodeId = (ev.detail.position !== undefined ? ev.detail.position : ev.detail.root) || this.nodeId;
|
|
595
|
-
}
|
|
647
|
+
this._doLoad(params);
|
|
648
|
+
}
|
|
596
649
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
registry.pathParams.forEach((key) => {
|
|
600
|
-
this._additionalParams[key] = ev.detail[key];
|
|
601
|
-
});
|
|
650
|
+
_doLoad(params) {
|
|
651
|
+
this.emitTo('pb-start-update', params);
|
|
602
652
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
}
|
|
607
|
-
this._updateStyles();
|
|
608
|
-
if (this.infiniteScroll) {
|
|
609
|
-
this._clear();
|
|
610
|
-
}
|
|
611
|
-
this._load(this.nodeId);
|
|
653
|
+
console.log('<pb-view> Loading view with params %o', params);
|
|
654
|
+
if (!this.infiniteScroll) {
|
|
655
|
+
this._clear();
|
|
612
656
|
}
|
|
613
657
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (this._loading) {
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
this._loading = true;
|
|
626
|
-
const params = this.getParameters(pos);
|
|
627
|
-
if (direction) {
|
|
628
|
-
params._dir = direction;
|
|
629
|
-
}
|
|
630
|
-
// this.$.view.style.opacity=0;
|
|
631
|
-
|
|
632
|
-
this._doLoad(params);
|
|
658
|
+
if (this._scrollObserver) {
|
|
659
|
+
if (this._bottomObserver) {
|
|
660
|
+
this._scrollObserver.unobserve(this._bottomObserver);
|
|
661
|
+
}
|
|
662
|
+
if (this._topObserver) {
|
|
663
|
+
this._scrollObserver.unobserve(this._topObserver);
|
|
664
|
+
}
|
|
633
665
|
}
|
|
634
666
|
|
|
635
|
-
|
|
636
|
-
this.emitTo('pb-start-update', params);
|
|
637
|
-
|
|
638
|
-
console.log("<pb-view> Loading view with params %o", params);
|
|
639
|
-
if (!this.infiniteScroll) {
|
|
640
|
-
this._clear();
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
if (this._scrollObserver) {
|
|
644
|
-
if (this._bottomObserver) {
|
|
645
|
-
this._scrollObserver.unobserve(this._bottomObserver);
|
|
646
|
-
}
|
|
647
|
-
if (this._topObserver) {
|
|
648
|
-
this._scrollObserver.unobserve(this._topObserver);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
const loadContent = this.shadowRoot.getElementById('loadContent');
|
|
653
|
-
|
|
654
|
-
if (this.static !== null) {
|
|
655
|
-
this._staticUrl(params).then((url) => {
|
|
656
|
-
loadContent.url = url;
|
|
657
|
-
loadContent.generateRequest();
|
|
658
|
-
});
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
if (!this.url) {
|
|
663
|
-
if (this.minApiVersion('1.0.0')) {
|
|
664
|
-
this.url = "api/parts";
|
|
665
|
-
} else {
|
|
666
|
-
this.url = "modules/lib/components.xql";
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
let url = `${this.getEndpoint()}/${this.url}`;
|
|
671
|
-
|
|
672
|
-
if (this.minApiVersion('1.0.0')) {
|
|
673
|
-
url += `/${encodeURIComponent(this.getDocument().path)}/json`;
|
|
674
|
-
}
|
|
667
|
+
const loadContent = this.shadowRoot.getElementById('loadContent');
|
|
675
668
|
|
|
669
|
+
if (this.static !== null) {
|
|
670
|
+
this._staticUrl(params).then(url => {
|
|
676
671
|
loadContent.url = url;
|
|
677
|
-
loadContent.params = params;
|
|
678
672
|
loadContent.generateRequest();
|
|
673
|
+
});
|
|
674
|
+
return;
|
|
679
675
|
}
|
|
680
676
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
paramNames.sort().forEach(key => {
|
|
688
|
-
if (params.hasOwnProperty(key)) {
|
|
689
|
-
urlComponents.push(`${key}=${params[key]}`);
|
|
690
|
-
}
|
|
691
|
-
});
|
|
692
|
-
return urlComponents.join('&');
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
const index = await fetch(`index.json`)
|
|
696
|
-
.then((response) => response.json());
|
|
697
|
-
const paramNames = ['odd', 'view', 'xpath', 'map'];
|
|
698
|
-
this.querySelectorAll('pb-param').forEach((param) => paramNames.push(`user.${param.getAttribute('name')}`));
|
|
699
|
-
let url = params.id ? createKey([...paramNames, 'id']) : createKey([...paramNames, 'root']);
|
|
700
|
-
let file = index[url];
|
|
701
|
-
if (!file) {
|
|
702
|
-
url = createKey(paramNames);
|
|
703
|
-
file = index[url];
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
console.log('<pb-view> Static lookup %s: %s', url, file);
|
|
707
|
-
return `${file}`;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
_clear() {
|
|
711
|
-
if (this.infiniteScroll) {
|
|
712
|
-
this._content = document.createElement('div');
|
|
713
|
-
this._content.className = 'infinite-content';
|
|
714
|
-
} else {
|
|
715
|
-
this._content = null;
|
|
716
|
-
}
|
|
717
|
-
this._column1 = null;
|
|
718
|
-
this._column2 = null;
|
|
719
|
-
this._footnotes = null;
|
|
720
|
-
this._chunks = [];
|
|
677
|
+
if (!this.url) {
|
|
678
|
+
if (this.minApiVersion('1.0.0')) {
|
|
679
|
+
this.url = 'api/parts';
|
|
680
|
+
} else {
|
|
681
|
+
this.url = 'modules/lib/components.xql';
|
|
682
|
+
}
|
|
721
683
|
}
|
|
722
684
|
|
|
723
|
-
|
|
724
|
-
this._clear();
|
|
725
|
-
const loader = this.shadowRoot.getElementById('loadContent');
|
|
726
|
-
let message;
|
|
727
|
-
const { response } = loader.lastError;
|
|
728
|
-
|
|
729
|
-
if (response) {
|
|
730
|
-
message = response.description;
|
|
731
|
-
} else {
|
|
732
|
-
message = '<pb-i18n key="dialogs.serverError"></pb-i18n>';
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
let content;
|
|
736
|
-
if (this.notFound != null) {
|
|
737
|
-
content = `<p>${this.notFound}</p>`;
|
|
738
|
-
} else {
|
|
739
|
-
content = `<p><pb-i18n key="dialogs.serverError"></pb-i18n>: ${message} </p>`;
|
|
740
|
-
}
|
|
685
|
+
let url = `${this.getEndpoint()}/${this.url}`;
|
|
741
686
|
|
|
742
|
-
|
|
743
|
-
|
|
687
|
+
if (this.minApiVersion('1.0.0')) {
|
|
688
|
+
url += `/${encodeURIComponent(this.getDocument().path)}/json`;
|
|
689
|
+
}
|
|
744
690
|
|
|
691
|
+
loadContent.url = url;
|
|
692
|
+
loadContent.params = params;
|
|
693
|
+
loadContent.generateRequest();
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Use a static URL to load pre-generated content.
|
|
698
|
+
*/
|
|
699
|
+
async _staticUrl(params) {
|
|
700
|
+
function createKey(paramNames) {
|
|
701
|
+
const urlComponents = [];
|
|
702
|
+
paramNames.sort().forEach(key => {
|
|
703
|
+
if (params.hasOwnProperty(key)) {
|
|
704
|
+
urlComponents.push(`${key}=${params[key]}`);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
return urlComponents.join('&');
|
|
745
708
|
}
|
|
746
709
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
710
|
+
const index = await fetch(`index.json`).then(response => response.json());
|
|
711
|
+
const paramNames = ['odd', 'view', 'xpath', 'map'];
|
|
712
|
+
this.querySelectorAll('pb-param').forEach(param =>
|
|
713
|
+
paramNames.push(`user.${param.getAttribute('name')}`),
|
|
714
|
+
);
|
|
715
|
+
let url = params.id ? createKey([...paramNames, 'id']) : createKey([...paramNames, 'root']);
|
|
716
|
+
let file = index[url];
|
|
717
|
+
if (!file) {
|
|
718
|
+
url = createKey(paramNames);
|
|
719
|
+
file = index[url];
|
|
720
|
+
}
|
|
750
721
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
755
|
-
if (resp.error) {
|
|
756
|
-
if (this.notFound != null) {
|
|
757
|
-
this._content = this.notFound;
|
|
758
|
-
}
|
|
759
|
-
this.emitTo('pb-end-update', null);
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
722
|
+
console.log('<pb-view> Static lookup %s: %s', url, file);
|
|
723
|
+
return `${file}`;
|
|
724
|
+
}
|
|
762
725
|
|
|
763
|
-
|
|
726
|
+
_clear() {
|
|
727
|
+
if (this.infiniteScroll) {
|
|
728
|
+
this._content = document.createElement('div');
|
|
729
|
+
this._content.className = 'infinite-content';
|
|
730
|
+
} else {
|
|
731
|
+
this._content = null;
|
|
732
|
+
}
|
|
733
|
+
this._column1 = null;
|
|
734
|
+
this._column2 = null;
|
|
735
|
+
this._footnotes = null;
|
|
736
|
+
this._chunks = [];
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
_handleError() {
|
|
740
|
+
this._clear();
|
|
741
|
+
const loader = this.shadowRoot.getElementById('loadContent');
|
|
742
|
+
let message;
|
|
743
|
+
const { response } = loader.lastError;
|
|
744
|
+
|
|
745
|
+
if (response) {
|
|
746
|
+
message = response.description;
|
|
747
|
+
} else {
|
|
748
|
+
message = '<pb-i18n key="dialogs.serverError"></pb-i18n>';
|
|
749
|
+
}
|
|
764
750
|
|
|
765
|
-
|
|
751
|
+
let content;
|
|
752
|
+
if (this.notFound != null) {
|
|
753
|
+
content = `<p>${this.notFound}</p>`;
|
|
754
|
+
} else {
|
|
755
|
+
content = `<p><pb-i18n key="dialogs.serverError"></pb-i18n>: ${message} </p>`;
|
|
756
|
+
}
|
|
766
757
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
this.shadowRoot.querySelector(`[node-id="${this._scrollTarget}"]`);
|
|
771
|
-
if (target) {
|
|
772
|
-
window.requestAnimationFrame(() =>
|
|
773
|
-
setTimeout(() => {
|
|
774
|
-
target.scrollIntoView({block: 'nearest'});
|
|
775
|
-
}, 400)
|
|
776
|
-
);
|
|
777
|
-
}
|
|
778
|
-
this._scrollTarget = null;
|
|
779
|
-
});
|
|
780
|
-
}
|
|
758
|
+
this._replaceContent({ content });
|
|
759
|
+
this.emitTo('pb-end-update');
|
|
760
|
+
}
|
|
781
761
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
this.previousId = resp.previousId;
|
|
786
|
-
this.nodeId = resp.root;
|
|
787
|
-
this.switchView = resp.switchView;
|
|
788
|
-
|
|
789
|
-
this.updateComplete.then(() => {
|
|
790
|
-
const view = this.shadowRoot.getElementById('view');
|
|
791
|
-
this._applyToggles(view);
|
|
792
|
-
this._fixLinks(view);
|
|
793
|
-
typesetMath(view);
|
|
794
|
-
|
|
795
|
-
const eventOptions = {
|
|
796
|
-
data: resp,
|
|
797
|
-
root: view,
|
|
798
|
-
params: loader.params,
|
|
799
|
-
id: this.xmlId,
|
|
800
|
-
position: this.nodeId
|
|
801
|
-
};
|
|
802
|
-
this.emitTo('pb-update', eventOptions);
|
|
803
|
-
this._scroll();
|
|
804
|
-
});
|
|
762
|
+
_handleContent() {
|
|
763
|
+
const loader = this.shadowRoot.getElementById('loadContent');
|
|
764
|
+
const resp = loader.lastResponse;
|
|
805
765
|
|
|
806
|
-
|
|
766
|
+
if (!resp) {
|
|
767
|
+
console.error('<pb-view> No response received');
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
if (resp.error) {
|
|
771
|
+
if (this.notFound != null) {
|
|
772
|
+
this._content = this.notFound;
|
|
773
|
+
}
|
|
774
|
+
this.emitTo('pb-end-update', null);
|
|
775
|
+
return;
|
|
807
776
|
}
|
|
808
777
|
|
|
809
|
-
_replaceContent(resp,
|
|
810
|
-
const fragment = document.createDocumentFragment();
|
|
811
|
-
const elem = document.createElement('div');
|
|
812
|
-
// elem.style.opacity = 0; //hide it - animation has to make sure to blend it in
|
|
813
|
-
fragment.appendChild(elem);
|
|
814
|
-
elem.innerHTML = resp.content;
|
|
778
|
+
this._replaceContent(resp, loader.params._dir);
|
|
815
779
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
780
|
+
this.animate();
|
|
781
|
+
|
|
782
|
+
if (this._scrollTarget) {
|
|
783
|
+
this.updateComplete.then(() => {
|
|
784
|
+
const target =
|
|
785
|
+
this.shadowRoot.getElementById(this._scrollTarget) ||
|
|
786
|
+
this.shadowRoot.querySelector(`[node-id="${this._scrollTarget}"]`);
|
|
787
|
+
if (target) {
|
|
788
|
+
window.requestAnimationFrame(() =>
|
|
789
|
+
setTimeout(() => {
|
|
790
|
+
target.scrollIntoView({ block: 'nearest' });
|
|
791
|
+
}, 400),
|
|
792
|
+
);
|
|
828
793
|
}
|
|
794
|
+
this._scrollTarget = null;
|
|
795
|
+
});
|
|
829
796
|
}
|
|
830
797
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
798
|
+
this.next = resp.next;
|
|
799
|
+
this.nextId = resp.nextId;
|
|
800
|
+
this.previous = resp.previous;
|
|
801
|
+
this.previousId = resp.previousId;
|
|
802
|
+
this.nodeId = resp.root;
|
|
803
|
+
this.switchView = resp.switchView;
|
|
804
|
+
|
|
805
|
+
this.updateComplete.then(() => {
|
|
806
|
+
const view = this.shadowRoot.getElementById('view');
|
|
807
|
+
this._applyToggles(view);
|
|
808
|
+
this._fixLinks(view);
|
|
809
|
+
typesetMath(view);
|
|
810
|
+
|
|
811
|
+
const eventOptions = {
|
|
812
|
+
data: resp,
|
|
813
|
+
root: view,
|
|
814
|
+
params: loader.params,
|
|
815
|
+
id: this.xmlId,
|
|
816
|
+
position: this.nodeId,
|
|
817
|
+
};
|
|
818
|
+
this.emitTo('pb-update', eventOptions);
|
|
819
|
+
this._scroll();
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
this.emitTo('pb-end-update', null);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
_replaceContent(resp, direction) {
|
|
826
|
+
const fragment = document.createDocumentFragment();
|
|
827
|
+
const elem = document.createElement('div');
|
|
828
|
+
// elem.style.opacity = 0; //hide it - animation has to make sure to blend it in
|
|
829
|
+
fragment.appendChild(elem);
|
|
830
|
+
elem.innerHTML = resp.content;
|
|
831
|
+
|
|
832
|
+
// if before-update-event is set, we do not replace the content immediately,
|
|
833
|
+
// but emit an event
|
|
834
|
+
if (this.beforeUpdate) {
|
|
835
|
+
this.emitTo(this.beforeUpdate, {
|
|
836
|
+
data: resp,
|
|
837
|
+
root: elem,
|
|
838
|
+
render: content => {
|
|
839
|
+
this._doReplaceContent(content, resp, direction);
|
|
840
|
+
},
|
|
841
|
+
});
|
|
842
|
+
} else {
|
|
843
|
+
this._doReplaceContent(elem, resp, direction);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
_doReplaceContent(elem, resp, direction) {
|
|
848
|
+
if (this.columnSeparator) {
|
|
849
|
+
this._replaceColumns(elem);
|
|
850
|
+
this._loading = false;
|
|
851
|
+
} else if (this.infiniteScroll) {
|
|
852
|
+
elem.className = 'scroll-fragment';
|
|
853
|
+
elem.setAttribute('data-root', resp.root);
|
|
854
|
+
if (resp.next) {
|
|
855
|
+
elem.setAttribute('data-next', resp.next);
|
|
856
|
+
}
|
|
857
|
+
if (resp.previous) {
|
|
858
|
+
elem.setAttribute('data-previous', resp.previous);
|
|
859
|
+
}
|
|
860
|
+
let refNode;
|
|
861
|
+
switch (direction) {
|
|
862
|
+
case 'backward':
|
|
863
|
+
refNode = this._content.firstElementChild;
|
|
864
|
+
this._chunks.unshift(elem);
|
|
865
|
+
this.updateComplete.then(() => {
|
|
866
|
+
refNode.scrollIntoView(true);
|
|
834
867
|
this._loading = false;
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
let refNode;
|
|
845
|
-
switch (direction) {
|
|
846
|
-
case 'backward':
|
|
847
|
-
refNode = this._content.firstElementChild;
|
|
848
|
-
this._chunks.unshift(elem);
|
|
849
|
-
this.updateComplete.then(() => {
|
|
850
|
-
refNode.scrollIntoView(true);
|
|
851
|
-
this._loading = false;
|
|
852
|
-
this._checkVisibility();
|
|
853
|
-
this._scrollObserver.observe(this._bottomObserver);
|
|
854
|
-
this._scrollObserver.observe(this._topObserver);
|
|
855
|
-
});
|
|
856
|
-
this._content.insertBefore(elem, refNode);
|
|
857
|
-
break;
|
|
858
|
-
default:
|
|
859
|
-
this.updateComplete.then(() => {
|
|
860
|
-
this._loading = false;
|
|
861
|
-
this._checkVisibility();
|
|
862
|
-
this._scrollObserver.observe(this._bottomObserver);
|
|
863
|
-
this._scrollObserver.observe(this._topObserver);
|
|
864
|
-
});
|
|
865
|
-
this._chunks.push(elem);
|
|
866
|
-
this._content.appendChild(elem);
|
|
867
|
-
break;
|
|
868
|
-
}
|
|
869
|
-
} else {
|
|
870
|
-
this._content = elem;
|
|
868
|
+
this._checkVisibility();
|
|
869
|
+
this._scrollObserver.observe(this._bottomObserver);
|
|
870
|
+
this._scrollObserver.observe(this._topObserver);
|
|
871
|
+
});
|
|
872
|
+
this._content.insertBefore(elem, refNode);
|
|
873
|
+
break;
|
|
874
|
+
default:
|
|
875
|
+
this.updateComplete.then(() => {
|
|
871
876
|
this._loading = false;
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
877
|
+
this._checkVisibility();
|
|
878
|
+
this._scrollObserver.observe(this._bottomObserver);
|
|
879
|
+
this._scrollObserver.observe(this._topObserver);
|
|
880
|
+
});
|
|
881
|
+
this._chunks.push(elem);
|
|
882
|
+
this._content.appendChild(elem);
|
|
883
|
+
break;
|
|
884
|
+
}
|
|
885
|
+
} else {
|
|
886
|
+
this._content = elem;
|
|
887
|
+
this._loading = false;
|
|
888
|
+
}
|
|
883
889
|
|
|
884
|
-
|
|
890
|
+
if (this.appendFootnotes) {
|
|
891
|
+
const footnotes = document.createElement('div');
|
|
892
|
+
if (resp.footnotes) {
|
|
893
|
+
footnotes.innerHTML = resp.footnotes;
|
|
894
|
+
}
|
|
895
|
+
this._footnotes = footnotes;
|
|
885
896
|
}
|
|
886
897
|
|
|
887
|
-
|
|
888
|
-
const bottomActive = this._chunks[this._chunks.length - 1].hasAttribute('data-next');
|
|
889
|
-
this._bottomObserver.style.display = bottomActive ? '' : 'none';
|
|
898
|
+
this._initFootnotes(this._footnotes);
|
|
890
899
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
}
|
|
900
|
+
return elem;
|
|
901
|
+
}
|
|
894
902
|
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const cbs = elem.querySelectorAll(this.columnSeparator);
|
|
899
|
-
// use last separator only
|
|
900
|
-
if (cbs.length > 1) {
|
|
901
|
-
cb = cbs[cbs.length - 1];
|
|
902
|
-
}
|
|
903
|
-
}
|
|
903
|
+
_checkVisibility() {
|
|
904
|
+
const bottomActive = this._chunks[this._chunks.length - 1].hasAttribute('data-next');
|
|
905
|
+
this._bottomObserver.style.display = bottomActive ? '' : 'none';
|
|
904
906
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
const fragmentBefore = this._getFragmentBefore(elem, cb);
|
|
909
|
-
const fragmentAfter = this._getFragmentAfter(elem, cb);
|
|
910
|
-
if (this.direction === 'ltr') {
|
|
911
|
-
this._column1 = fragmentBefore;
|
|
912
|
-
this._column2 = fragmentAfter;
|
|
913
|
-
} else {
|
|
914
|
-
this._column2 = fragmentBefore;
|
|
915
|
-
this._column1 = fragmentAfter;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
907
|
+
const topActive = this._chunks[0].hasAttribute('data-previous');
|
|
908
|
+
this._topObserver.style.display = topActive ? '' : 'none';
|
|
909
|
+
}
|
|
919
910
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
window.requestAnimationFrame(() =>
|
|
929
|
-
setTimeout(() => {
|
|
930
|
-
target.scrollIntoView({ block: "center", inline: "nearest" });
|
|
931
|
-
}, 400)
|
|
932
|
-
);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
911
|
+
_replaceColumns(elem) {
|
|
912
|
+
let cb;
|
|
913
|
+
if (this.columnSeparator) {
|
|
914
|
+
const cbs = elem.querySelectorAll(this.columnSeparator);
|
|
915
|
+
// use last separator only
|
|
916
|
+
if (cbs.length > 1) {
|
|
917
|
+
cb = cbs[cbs.length - 1];
|
|
918
|
+
}
|
|
935
919
|
}
|
|
936
920
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
921
|
+
if (!cb) {
|
|
922
|
+
this._content = elem;
|
|
923
|
+
} else {
|
|
924
|
+
const fragmentBefore = this._getFragmentBefore(elem, cb);
|
|
925
|
+
const fragmentAfter = this._getFragmentAfter(elem, cb);
|
|
926
|
+
if (this.direction === 'ltr') {
|
|
927
|
+
this._column1 = fragmentBefore;
|
|
928
|
+
this._column2 = fragmentAfter;
|
|
929
|
+
} else {
|
|
930
|
+
this._column2 = fragmentBefore;
|
|
931
|
+
this._column1 = fragmentAfter;
|
|
932
|
+
}
|
|
944
933
|
}
|
|
934
|
+
}
|
|
945
935
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
936
|
+
_scroll() {
|
|
937
|
+
if (this.noScroll) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (registry.hash) {
|
|
941
|
+
const target = this.shadowRoot.getElementById(registry.hash.substring(1));
|
|
942
|
+
console.log('hash target: %o', target);
|
|
943
|
+
if (target) {
|
|
944
|
+
window.requestAnimationFrame(() =>
|
|
945
|
+
setTimeout(() => {
|
|
946
|
+
target.scrollIntoView({ block: 'center', inline: 'nearest' });
|
|
947
|
+
}, 400),
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
_scrollToElement(ev, link) {
|
|
954
|
+
const target = this.shadowRoot.getElementById(link.hash.substring(1));
|
|
955
|
+
if (target) {
|
|
956
|
+
ev.preventDefault();
|
|
957
|
+
console.log('<pb-view> Scrolling to element %s', target.id);
|
|
958
|
+
target.scrollIntoView({ block: 'center', inline: 'nearest' });
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
_updateStyles() {
|
|
963
|
+
const link = document.createElement('link');
|
|
964
|
+
link.setAttribute('rel', 'stylesheet');
|
|
965
|
+
link.setAttribute('type', 'text/css');
|
|
966
|
+
if (this.static !== null) {
|
|
967
|
+
link.setAttribute('href', `${this.static}/css/${this.getOdd()}.css`);
|
|
968
|
+
} else {
|
|
969
|
+
link.setAttribute('href', `${this.getEndpoint()}/transform/${this.getOdd()}.css`);
|
|
970
|
+
}
|
|
971
|
+
this._style = link;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
_fixLinks(content) {
|
|
975
|
+
if (this.fixLinks) {
|
|
976
|
+
const doc = this.getDocument();
|
|
977
|
+
const base = this.toAbsoluteURL(doc.path);
|
|
978
|
+
content.querySelectorAll('img').forEach(image => {
|
|
979
|
+
const oldSrc = image.getAttribute('src');
|
|
980
|
+
const src = new URL(oldSrc, base);
|
|
981
|
+
image.src = src;
|
|
982
|
+
});
|
|
983
|
+
content.querySelectorAll('a').forEach(link => {
|
|
984
|
+
const oldHref = link.getAttribute('href');
|
|
985
|
+
if (oldHref === link.hash) {
|
|
986
|
+
link.addEventListener('click', ev => this._scrollToElement(ev, link));
|
|
976
987
|
} else {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
if (oldHref === link.hash) {
|
|
980
|
-
link.addEventListener('click', (ev) => this._scrollToElement(ev, link));
|
|
981
|
-
}
|
|
982
|
-
});
|
|
988
|
+
const href = new URL(oldHref, base);
|
|
989
|
+
link.href = href;
|
|
983
990
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
ev.preventDefault();
|
|
991
|
-
const fn = this.shadowRoot.getElementById('content').querySelector(elem.hash);
|
|
992
|
-
if (fn) {
|
|
993
|
-
fn.scrollIntoView();
|
|
994
|
-
}
|
|
995
|
-
});
|
|
996
|
-
});
|
|
991
|
+
});
|
|
992
|
+
} else {
|
|
993
|
+
content.querySelectorAll('a').forEach(link => {
|
|
994
|
+
const oldHref = link.getAttribute('href');
|
|
995
|
+
if (oldHref === link.hash) {
|
|
996
|
+
link.addEventListener('click', ev => this._scrollToElement(ev, link));
|
|
997
997
|
}
|
|
998
|
+
});
|
|
998
999
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
_initFootnotes(content) {
|
|
1003
|
+
if (content) {
|
|
1004
|
+
content.querySelectorAll('.note, .fn-back').forEach(elem => {
|
|
1005
|
+
elem.addEventListener('click', ev => {
|
|
1006
|
+
ev.preventDefault();
|
|
1007
|
+
const fn = this.shadowRoot.getElementById('content').querySelector(elem.hash);
|
|
1008
|
+
if (fn) {
|
|
1009
|
+
fn.scrollIntoView();
|
|
1010
|
+
}
|
|
1004
1011
|
});
|
|
1005
|
-
|
|
1006
|
-
for (const [key, value] of Object.entries(this._features)) {
|
|
1007
|
-
params['user.' + key] = value;
|
|
1008
|
-
}
|
|
1009
|
-
// add parameters for user-defined parameters supplied via pb-link
|
|
1010
|
-
if (this._additionalParams) {
|
|
1011
|
-
for (const [key, value] of Object.entries(this._additionalParams)) {
|
|
1012
|
-
params[key] = value;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
return params;
|
|
1012
|
+
});
|
|
1016
1013
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
}
|
|
1028
|
-
params.odd = this.getOdd() + '.odd';
|
|
1029
|
-
params.view = this.getView();
|
|
1030
|
-
if (pos) {
|
|
1031
|
-
params['root'] = pos;
|
|
1032
|
-
}
|
|
1033
|
-
if (this.xpath) {
|
|
1034
|
-
params.xpath = this.xpath;
|
|
1035
|
-
}
|
|
1036
|
-
if (this.xmlId) {
|
|
1037
|
-
params.id = this.xmlId;
|
|
1038
|
-
}
|
|
1039
|
-
if (!this.suppressHighlight && this.highlight) {
|
|
1040
|
-
params.highlight = "yes";
|
|
1041
|
-
}
|
|
1042
|
-
if (this.map) {
|
|
1043
|
-
params.map = this.map;
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
return params;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
_getParameters() {
|
|
1017
|
+
const params = [];
|
|
1018
|
+
this.querySelectorAll('pb-param').forEach(param => {
|
|
1019
|
+
params[`user.${param.getAttribute('name')}`] = param.getAttribute('value');
|
|
1020
|
+
});
|
|
1021
|
+
// add parameters for features set with pb-toggle-feature
|
|
1022
|
+
for (const [key, value] of Object.entries(this._features)) {
|
|
1023
|
+
params[`user.${key}`] = value;
|
|
1047
1024
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (node.command) {
|
|
1054
|
-
node.command(command, setting.state);
|
|
1055
|
-
}
|
|
1056
|
-
if (setting.state) {
|
|
1057
|
-
node.classList.add(command);
|
|
1058
|
-
} else {
|
|
1059
|
-
node.classList.remove(command);
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1062
|
-
}
|
|
1025
|
+
// add parameters for user-defined parameters supplied via pb-link
|
|
1026
|
+
if (this._additionalParams) {
|
|
1027
|
+
for (const [key, value] of Object.entries(this._additionalParams)) {
|
|
1028
|
+
params[key] = value;
|
|
1029
|
+
}
|
|
1063
1030
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
*
|
|
1077
|
-
* @param {String} xmlId The xml:id to be loaded
|
|
1078
|
-
*/
|
|
1079
|
-
gotoId(xmlId) {
|
|
1080
|
-
this.xmlId = xmlId;
|
|
1081
|
-
this._load();
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
/**
|
|
1085
|
-
* Navigate the document either forward or backward and refresh the view.
|
|
1086
|
-
* The navigation method is determined by property `view`.
|
|
1087
|
-
*
|
|
1088
|
-
* @param {string} direction either `backward` or `forward`
|
|
1089
|
-
*/
|
|
1090
|
-
navigate(direction) {
|
|
1091
|
-
// in single view mode there should be no navigation
|
|
1092
|
-
if (this.getView() === 'single') {
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
this.lastDirection = direction;
|
|
1097
|
-
|
|
1098
|
-
if (direction === 'backward') {
|
|
1099
|
-
if (this.previous) {
|
|
1100
|
-
if (!this.disableHistory && !this.map) {
|
|
1101
|
-
registry.commit(this, {
|
|
1102
|
-
id: this.previousId || null,
|
|
1103
|
-
root: this.previousId ? null : this.previous
|
|
1104
|
-
});
|
|
1105
|
-
}
|
|
1106
|
-
this.xmlId = this.previousId;
|
|
1107
|
-
this._load(this.xmlId ? null : this.previous, direction);
|
|
1108
|
-
}
|
|
1109
|
-
} else if (this.next) {
|
|
1110
|
-
if (!this.disableHistory && !this.map) {
|
|
1111
|
-
registry.commit(this, {
|
|
1112
|
-
id: this.nextId || null,
|
|
1113
|
-
root: this.nextId ? null : this.next
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
this.xmlId = this.nextId;
|
|
1117
|
-
this._load(this.xmlId ? null : this.next, direction);
|
|
1118
|
-
}
|
|
1031
|
+
return params;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Return the parameter object which would be passed to the server by this component
|
|
1036
|
+
*/
|
|
1037
|
+
getParameters(pos) {
|
|
1038
|
+
pos = pos || this.nodeId;
|
|
1039
|
+
const doc = this.getDocument();
|
|
1040
|
+
const params = this._getParameters();
|
|
1041
|
+
if (!this.minApiVersion('1.0.0')) {
|
|
1042
|
+
params.doc = doc.path;
|
|
1119
1043
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
*
|
|
1126
|
-
* @param {string} direction either 'forward' or 'backward'
|
|
1127
|
-
*/
|
|
1128
|
-
_checkChunks(direction) {
|
|
1129
|
-
if (!this.infiniteScroll || this.infiniteScrollMax === 0) {
|
|
1130
|
-
return;
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
if (this._chunks.length === this.infiniteScrollMax) {
|
|
1134
|
-
switch (direction) {
|
|
1135
|
-
case 'forward':
|
|
1136
|
-
this._content.removeChild(this._chunks.shift());
|
|
1137
|
-
break;
|
|
1138
|
-
default:
|
|
1139
|
-
this._content.removeChild(this._chunks.pop());
|
|
1140
|
-
break;
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
this.emitTo('pb-navigate', {
|
|
1144
|
-
direction,
|
|
1145
|
-
source: this
|
|
1146
|
-
});
|
|
1044
|
+
params.odd = `${this.getOdd()}.odd`;
|
|
1045
|
+
params.view = this.getView();
|
|
1046
|
+
params.fill = this.fill;
|
|
1047
|
+
if (pos) {
|
|
1048
|
+
params.root = pos;
|
|
1147
1049
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
* Zoom the displayed content by increasing or decreasing font size.
|
|
1151
|
-
*
|
|
1152
|
-
* @param {string} direction either `in` or `out`
|
|
1153
|
-
*/
|
|
1154
|
-
zoom(direction) {
|
|
1155
|
-
const view = this.shadowRoot.getElementById('view');
|
|
1156
|
-
const fontSize = window.getComputedStyle(view).getPropertyValue('font-size');
|
|
1157
|
-
const size = parseInt(fontSize.replace(/^(\d+)px/, "$1"));
|
|
1158
|
-
|
|
1159
|
-
if (direction === 'in') {
|
|
1160
|
-
view.style.fontSize = (size + 1) + 'px';
|
|
1161
|
-
} else {
|
|
1162
|
-
view.style.fontSize = (size - 1) + 'px';
|
|
1163
|
-
}
|
|
1050
|
+
if (this.xpath) {
|
|
1051
|
+
params.xpath = this.xpath;
|
|
1164
1052
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
if (ev.detail.refresh) {
|
|
1174
|
-
this._updateStyles();
|
|
1175
|
-
this._load();
|
|
1176
|
-
} else {
|
|
1177
|
-
const view = this.shadowRoot.getElementById('view');
|
|
1178
|
-
this._applyToggles(view);
|
|
1179
|
-
}
|
|
1180
|
-
registry.commit(this, properties);
|
|
1053
|
+
if (this.xmlId) {
|
|
1054
|
+
params.id = this.xmlId;
|
|
1055
|
+
}
|
|
1056
|
+
if (!this.suppressHighlight && this.highlight) {
|
|
1057
|
+
params.highlight = 'yes';
|
|
1058
|
+
}
|
|
1059
|
+
if (this.map) {
|
|
1060
|
+
params.map = this.map;
|
|
1181
1061
|
}
|
|
1182
1062
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
// check if URL template needs the parameter and if
|
|
1186
|
-
// yes, add it to the additional parameter list
|
|
1187
|
-
if (registry.pathParams.has(key)) {
|
|
1188
|
-
this._additionalParams[key] = value;
|
|
1189
|
-
} else {
|
|
1190
|
-
switch (key) {
|
|
1191
|
-
case 'odd':
|
|
1192
|
-
case 'view':
|
|
1193
|
-
case 'columnSeparator':
|
|
1194
|
-
case 'xpath':
|
|
1195
|
-
case 'nodeId':
|
|
1196
|
-
case 'path':
|
|
1197
|
-
case 'root':
|
|
1198
|
-
break;
|
|
1199
|
-
default:
|
|
1200
|
-
this._features[key] = value;
|
|
1201
|
-
break;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
if (properties.odd && !this.getAttribute('odd')) {
|
|
1206
|
-
this.odd = properties.odd;
|
|
1207
|
-
}
|
|
1208
|
-
if (properties.view && !this.getAttribute('view')) {
|
|
1209
|
-
this.view = properties.view;
|
|
1210
|
-
if (this.view === 'single') {
|
|
1211
|
-
// when switching to single view, clear current node id
|
|
1212
|
-
this.nodeId = null;
|
|
1213
|
-
} else {
|
|
1214
|
-
// otherwise use value for alternate view returned from server
|
|
1215
|
-
this.nodeId = this.switchView;
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
if (properties.xpath && !this.getAttribute('xpath')) {
|
|
1219
|
-
this.xpath = properties.xpath;
|
|
1220
|
-
}
|
|
1221
|
-
if (properties.hasOwnProperty('columnSeparator')) {
|
|
1222
|
-
this.columnSeparator = properties.columnSeparator;
|
|
1223
|
-
}
|
|
1224
|
-
this.xmlId = (!this.getAttribute('xml-id') && properties.id) || this.xmlId;
|
|
1225
|
-
this.nodeId = (!this.getAttribute('xml-id') && properties.root) || null;
|
|
1063
|
+
return params;
|
|
1064
|
+
}
|
|
1226
1065
|
|
|
1227
|
-
|
|
1228
|
-
|
|
1066
|
+
_applyToggles(elem) {
|
|
1067
|
+
for (const [selector, setting] of Object.entries(this._selector)) {
|
|
1068
|
+
elem.querySelectorAll(selector).forEach(node => {
|
|
1069
|
+
const command = setting.command || 'toggle';
|
|
1070
|
+
if (node.command) {
|
|
1071
|
+
node.command(command, setting.state);
|
|
1229
1072
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
state: sc.state,
|
|
1235
|
-
command: sc.command || 'toggle'
|
|
1236
|
-
};
|
|
1237
|
-
});
|
|
1073
|
+
if (setting.state) {
|
|
1074
|
+
node.classList.add(command);
|
|
1075
|
+
} else {
|
|
1076
|
+
node.classList.remove(command);
|
|
1238
1077
|
}
|
|
1078
|
+
});
|
|
1239
1079
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* Load a part of the document identified by the given eXist nodeId
|
|
1084
|
+
*
|
|
1085
|
+
* @param {String} nodeId The eXist nodeId of the root element to load
|
|
1086
|
+
*/
|
|
1087
|
+
goto(nodeId) {
|
|
1088
|
+
this._load(nodeId);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Load a part of the document identified by the given xml:id
|
|
1093
|
+
*
|
|
1094
|
+
* @param {String} xmlId The xml:id to be loaded
|
|
1095
|
+
*/
|
|
1096
|
+
gotoId(xmlId) {
|
|
1097
|
+
this.xmlId = xmlId;
|
|
1098
|
+
this._load();
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Navigate the document either forward or backward and refresh the view.
|
|
1103
|
+
* The navigation method is determined by property `view`.
|
|
1104
|
+
*
|
|
1105
|
+
* @param {string} direction either `backward` or `forward`
|
|
1106
|
+
*/
|
|
1107
|
+
navigate(direction) {
|
|
1108
|
+
// in single view mode there should be no navigation
|
|
1109
|
+
if (this.getView() === 'single') {
|
|
1110
|
+
return;
|
|
1247
1111
|
}
|
|
1248
1112
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1113
|
+
this.lastDirection = direction;
|
|
1114
|
+
|
|
1115
|
+
if (direction === 'backward') {
|
|
1116
|
+
if (this.previous) {
|
|
1117
|
+
if (!this.disableHistory && !this.map) {
|
|
1118
|
+
registry.commit(this, {
|
|
1119
|
+
id: this.previousId || null,
|
|
1120
|
+
root: this.previousId ? null : this.previous,
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
this.xmlId = this.previousId;
|
|
1124
|
+
this._load(this.xmlId ? null : this.previous, direction);
|
|
1125
|
+
}
|
|
1126
|
+
} else if (this.next) {
|
|
1127
|
+
if (!this.disableHistory && !this.map) {
|
|
1128
|
+
registry.commit(this, {
|
|
1129
|
+
id: this.nextId || null,
|
|
1130
|
+
root: this.nextId ? null : this.next,
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
this.xmlId = this.nextId;
|
|
1134
|
+
this._load(this.xmlId ? null : this.next, direction);
|
|
1255
1135
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* Check the number of fragments which were already loaded in infinite
|
|
1140
|
+
* scroll mode. If they exceed `infiniteScrollMax`, remove either the
|
|
1141
|
+
* first or last fragment from the DOM, depending on the scroll direction.
|
|
1142
|
+
*
|
|
1143
|
+
* @param {string} direction either 'forward' or 'backward'
|
|
1144
|
+
*/
|
|
1145
|
+
_checkChunks(direction) {
|
|
1146
|
+
if (!this.infiniteScroll || this.infiniteScrollMax === 0) {
|
|
1147
|
+
return;
|
|
1264
1148
|
}
|
|
1265
1149
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
#view {
|
|
1288
|
-
position: relative;
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
.columns {
|
|
1292
|
-
display: grid;
|
|
1293
|
-
grid-template-columns: calc(50% - var(--pb-view-column-gap, 10px) / 2) calc(50% - var(--pb-view-column-gap, 10px) / 2);
|
|
1294
|
-
grid-column-gap: var(--pb-view-column-gap, 10px);
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
.margin-note {
|
|
1298
|
-
display: none;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
@media (min-width: 769px) {
|
|
1302
|
-
.content.margin-right {
|
|
1303
|
-
margin-right: 200px;
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
.margin-note {
|
|
1307
|
-
background: rgba(153, 153, 153, 0.2);
|
|
1308
|
-
display: block;
|
|
1309
|
-
font-size: small;
|
|
1310
|
-
margin-right: -200px;
|
|
1311
|
-
margin-bottom: 5px;
|
|
1312
|
-
padding: 5px 0;
|
|
1313
|
-
float: right;
|
|
1314
|
-
clear: both;
|
|
1315
|
-
width: 180px;
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
.margin-note .n {
|
|
1319
|
-
color: #777777;
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
a[rel=footnote] {
|
|
1324
|
-
font-size: var(--pb-footnote-font-size, var(--pb-content-font-size, 75%));
|
|
1325
|
-
font-family: var(--pb-footnote-font-family, --pb-content-font-family);
|
|
1326
|
-
vertical-align: super;
|
|
1327
|
-
color: var(--pb-footnote-color, var(--pb-color-primary, #333333));
|
|
1328
|
-
text-decoration: none;
|
|
1329
|
-
padding: var(--pb-footnote-padding, 0 0 0 .25em);
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
.list dt {
|
|
1333
|
-
float: left;
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
.footnote .fn-number {
|
|
1337
|
-
float: left;
|
|
1338
|
-
font-size: var(--pb-footnote-font-size, var(--pb-content-font-size, 75%));
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
.observer {
|
|
1342
|
-
display: block;
|
|
1343
|
-
width: 100%;
|
|
1344
|
-
height: var(--pb-view-loader-height, 16px);
|
|
1345
|
-
font-family: var(--pb-view-loader-font, --pb-base-font);
|
|
1346
|
-
color: var(--pb-view-loader-color, black);
|
|
1347
|
-
background: var(--pb-view-loader-background, #909090);
|
|
1348
|
-
background-image: var(--pb-view-loader-background-image, repeating-linear-gradient(45deg, transparent, transparent 35px, rgba(255,255,255,.5) 35px, rgba(255,255,255,.5) 70px));
|
|
1349
|
-
animation-name: loader;
|
|
1350
|
-
animation-timing-function: linear;
|
|
1351
|
-
animation-duration: 2s;
|
|
1352
|
-
animation-fill-mode: forwards;
|
|
1353
|
-
animation-iteration-count: infinite;
|
|
1354
|
-
}
|
|
1150
|
+
if (this._chunks.length === this.infiniteScrollMax) {
|
|
1151
|
+
switch (direction) {
|
|
1152
|
+
case 'forward':
|
|
1153
|
+
this._content.removeChild(this._chunks.shift());
|
|
1154
|
+
break;
|
|
1155
|
+
default:
|
|
1156
|
+
this._content.removeChild(this._chunks.pop());
|
|
1157
|
+
break;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
this.emitTo('pb-navigate', {
|
|
1161
|
+
direction,
|
|
1162
|
+
source: this,
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
toggleFeature(ev) {
|
|
1167
|
+
const properties = registry.getState(this);
|
|
1168
|
+
if (properties) {
|
|
1169
|
+
this._setState(properties);
|
|
1170
|
+
}
|
|
1355
1171
|
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1172
|
+
if (ev.detail.refresh) {
|
|
1173
|
+
this._updateStyles();
|
|
1174
|
+
this._load();
|
|
1175
|
+
} else {
|
|
1176
|
+
const view = this.shadowRoot.getElementById('view');
|
|
1177
|
+
this._applyToggles(view);
|
|
1178
|
+
}
|
|
1179
|
+
registry.commit(this, properties);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
_setState(properties) {
|
|
1183
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
1184
|
+
// check if URL template needs the parameter and if
|
|
1185
|
+
// yes, add it to the additional parameter list
|
|
1186
|
+
if (registry.pathParams.has(key)) {
|
|
1187
|
+
this._additionalParams[key] = value;
|
|
1188
|
+
} else {
|
|
1189
|
+
switch (key) {
|
|
1190
|
+
case 'odd':
|
|
1191
|
+
case 'view':
|
|
1192
|
+
case 'columnSeparator':
|
|
1193
|
+
case 'xpath':
|
|
1194
|
+
case 'nodeId':
|
|
1195
|
+
case 'path':
|
|
1196
|
+
case 'root':
|
|
1197
|
+
break;
|
|
1198
|
+
default:
|
|
1199
|
+
this._features[key] = value;
|
|
1200
|
+
break;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (properties.odd && !this.getAttribute('odd')) {
|
|
1205
|
+
this.odd = properties.odd;
|
|
1206
|
+
}
|
|
1207
|
+
if (properties.view && !this.getAttribute('view')) {
|
|
1208
|
+
this.view = properties.view;
|
|
1209
|
+
if (this.view === 'single') {
|
|
1210
|
+
// when switching to single view, clear current node id
|
|
1211
|
+
this.nodeId = null;
|
|
1212
|
+
} else {
|
|
1213
|
+
// otherwise use value for alternate view returned from server
|
|
1214
|
+
this.nodeId = this.switchView;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
if (properties.fill && !this.getAttribute('fill')) {
|
|
1218
|
+
this.fill = properties.fill;
|
|
1219
|
+
}
|
|
1220
|
+
if (properties.xpath && !this.getAttribute('xpath')) {
|
|
1221
|
+
this.xpath = properties.xpath;
|
|
1222
|
+
}
|
|
1223
|
+
if (properties.hasOwnProperty('columnSeparator')) {
|
|
1224
|
+
this.columnSeparator = properties.columnSeparator;
|
|
1225
|
+
}
|
|
1226
|
+
this.xmlId = (!this.getAttribute('xml-id') && properties.id) || this.xmlId;
|
|
1227
|
+
this.nodeId = (!this.getAttribute('xml-id') && properties.root) || null;
|
|
1365
1228
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1229
|
+
if (properties.path) {
|
|
1230
|
+
this.getDocument().path = properties.path;
|
|
1231
|
+
}
|
|
1369
1232
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
</div>
|
|
1403
|
-
</paper-dialog>
|
|
1404
|
-
<iron-ajax
|
|
1405
|
-
id="loadContent"
|
|
1406
|
-
verbose
|
|
1407
|
-
handle-as="json"
|
|
1408
|
-
method="get"
|
|
1409
|
-
with-credentials
|
|
1410
|
-
@response="${this._handleContent}"
|
|
1411
|
-
@error="${this._handleError}"></iron-ajax>
|
|
1412
|
-
`
|
|
1413
|
-
]
|
|
1233
|
+
if (properties.selectors) {
|
|
1234
|
+
properties.selectors.forEach(sc => {
|
|
1235
|
+
this._selector[sc.selector] = {
|
|
1236
|
+
state: sc.state,
|
|
1237
|
+
command: sc.command || 'toggle',
|
|
1238
|
+
};
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
_getFragmentBefore(node, ms) {
|
|
1244
|
+
const range = document.createRange();
|
|
1245
|
+
range.setStartBefore(node);
|
|
1246
|
+
range.setEndBefore(ms);
|
|
1247
|
+
|
|
1248
|
+
return range.cloneContents();
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
_getFragmentAfter(node, ms) {
|
|
1252
|
+
const range = document.createRange();
|
|
1253
|
+
range.setStartBefore(ms);
|
|
1254
|
+
range.setEndAfter(node);
|
|
1255
|
+
|
|
1256
|
+
return range.cloneContents();
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
_updateSource(newVal, oldVal) {
|
|
1260
|
+
if (typeof oldVal !== 'undefined' && newVal !== oldVal) {
|
|
1261
|
+
this.xpath = null;
|
|
1262
|
+
this.odd = null;
|
|
1263
|
+
this.xmlId = null;
|
|
1264
|
+
this.nodeId = null;
|
|
1414
1265
|
}
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
static get styles() {
|
|
1269
|
+
return css`
|
|
1270
|
+
:host {
|
|
1271
|
+
display: block;
|
|
1272
|
+
background: transparent;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
:host(.noscroll) {
|
|
1276
|
+
scrollbar-width: none; /* Firefox 64 */
|
|
1277
|
+
-ms-overflow-style: none;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
:host(.noscroll)::-webkit-scrollbar {
|
|
1281
|
+
width: 0 !important;
|
|
1282
|
+
display: none;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
[id] {
|
|
1286
|
+
scroll-margin-top: var(--pb-view-scroll-margin-top);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
#view {
|
|
1290
|
+
position: relative;
|
|
1291
|
+
font-size: clamp(
|
|
1292
|
+
calc(var(--pb-content-font-size, 1rem) * var(--pb-min-zoom, 0.5)),
|
|
1293
|
+
calc(var(--pb-content-font-size, 1rem) * var(--pb-zoom-factor)),
|
|
1294
|
+
calc(var(--pb-content-font-size, 1rem) * var(--pb-max-zoom, 3.0))
|
|
1295
|
+
);
|
|
1296
|
+
line-height: calc(var(--pb-content-line-height, 1.5) * var(--pb-zoom-factor));
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
.columns {
|
|
1300
|
+
display: grid;
|
|
1301
|
+
grid-template-columns: calc(50% - var(--pb-view-column-gap, 10px) / 2) calc(
|
|
1302
|
+
50% - var(--pb-view-column-gap, 10px) / 2
|
|
1303
|
+
);
|
|
1304
|
+
grid-column-gap: var(--pb-view-column-gap, 10px);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.margin-note {
|
|
1308
|
+
display: none;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
@media (min-width: 769px) {
|
|
1312
|
+
.content.margin-right {
|
|
1313
|
+
margin-right: 200px;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
.margin-note {
|
|
1317
|
+
background: rgba(153, 153, 153, 0.2);
|
|
1318
|
+
display: block;
|
|
1319
|
+
font-size: small;
|
|
1320
|
+
margin-right: -200px;
|
|
1321
|
+
margin-bottom: 5px;
|
|
1322
|
+
padding: 5px 0;
|
|
1323
|
+
float: right;
|
|
1324
|
+
clear: both;
|
|
1325
|
+
width: 180px;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
.margin-note .n {
|
|
1329
|
+
color: #777777;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
a[rel='footnote'] {
|
|
1334
|
+
font-size: calc(var(--pb-footnote-font-size, var(--pb-content-font-size, 75%)) * var(--pb-zoom-factor, 1));
|
|
1335
|
+
font-family: var(--pb-footnote-font-family, --pb-content-font-family);
|
|
1336
|
+
vertical-align: super;
|
|
1337
|
+
color: var(--pb-footnote-color, var(--pb-color-primary, #333333));
|
|
1338
|
+
text-decoration: none;
|
|
1339
|
+
padding: var(--pb-footnote-padding, 0 0 0 0.25em);
|
|
1340
|
+
line-height: 1;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
.list dt {
|
|
1344
|
+
float: left;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
.footnote .fn-number {
|
|
1348
|
+
float: left;
|
|
1349
|
+
font-size: var(--pb-footnote-font-size, var(--pb-content-font-size, 75%));
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
.observer {
|
|
1353
|
+
display: block;
|
|
1354
|
+
width: 100%;
|
|
1355
|
+
height: var(--pb-view-loader-height, 16px);
|
|
1356
|
+
font-family: var(--pb-view-loader-font, --pb-base-font);
|
|
1357
|
+
color: var(--pb-view-loader-color, black);
|
|
1358
|
+
background: var(--pb-view-loader-background, #909090);
|
|
1359
|
+
background-image: var(
|
|
1360
|
+
--pb-view-loader-background-image,
|
|
1361
|
+
repeating-linear-gradient(
|
|
1362
|
+
45deg,
|
|
1363
|
+
transparent,
|
|
1364
|
+
transparent 35px,
|
|
1365
|
+
rgba(255, 255, 255, 0.5) 35px,
|
|
1366
|
+
rgba(255, 255, 255, 0.5) 70px
|
|
1367
|
+
)
|
|
1368
|
+
);
|
|
1369
|
+
animation-name: loader;
|
|
1370
|
+
animation-timing-function: linear;
|
|
1371
|
+
animation-duration: 2s;
|
|
1372
|
+
animation-fill-mode: forwards;
|
|
1373
|
+
animation-iteration-count: infinite;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
@keyframes loader {
|
|
1377
|
+
0% {
|
|
1378
|
+
background-position: 3rem 0;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
100% {
|
|
1382
|
+
background-position: 0 0;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
.scroll-fragment {
|
|
1387
|
+
animation: fadeIn ease 500ms;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
@keyframes fadeIn {
|
|
1391
|
+
0% {
|
|
1392
|
+
opacity: 0;
|
|
1393
|
+
}
|
|
1394
|
+
100% {
|
|
1395
|
+
opacity: 1;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
`;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
render() {
|
|
1402
|
+
return [
|
|
1403
|
+
html`
|
|
1404
|
+
<div id="view" part="content">
|
|
1405
|
+
${this._style}
|
|
1406
|
+
${this.infiniteScroll ? html`<div id="top-observer" class="observer"></div>` : null}
|
|
1407
|
+
<div class="columns">
|
|
1408
|
+
<div id="column1">${this._column1}</div>
|
|
1409
|
+
<div id="column2">${this._column2}</div>
|
|
1410
|
+
</div>
|
|
1411
|
+
<div id="content">${this._content}</div>
|
|
1412
|
+
${this.infiniteScroll ? html`<div id="bottom-observer" class="observer"></div>` : null}
|
|
1413
|
+
<div id="footnotes" part="footnotes">${this._footnotes}</div>
|
|
1414
|
+
</div>
|
|
1415
|
+
<iron-ajax
|
|
1416
|
+
id="loadContent"
|
|
1417
|
+
verbose
|
|
1418
|
+
handle-as="json"
|
|
1419
|
+
method="get"
|
|
1420
|
+
with-credentials
|
|
1421
|
+
@response="${this._handleContent}"
|
|
1422
|
+
@error="${this._handleError}"
|
|
1423
|
+
></iron-ajax>
|
|
1424
|
+
`,
|
|
1425
|
+
];
|
|
1426
|
+
}
|
|
1415
1427
|
}
|
|
1416
1428
|
|
|
1417
1429
|
customElements.define('pb-view', PbView);
|