@teipublisher/pb-components 1.34.3 → 1.35.2

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.
@@ -754,6 +754,18 @@
754
754
  "type": "array",
755
755
  "default": "[]"
756
756
  },
757
+ {
758
+ "name": "preload",
759
+ "description": "If set, the entire list of possible suggestions will be preloaded upon initialization of the\ncomponent.",
760
+ "type": "boolean",
761
+ "default": "false"
762
+ },
763
+ {
764
+ "name": "substring",
765
+ "description": "By default suggestions are filtered by prefix, i.e. only suggestions starting with the prefix\ntyped by the user are shown. Set this property to true to search for the user-provided string\nanywhere within the suggestion text.",
766
+ "type": "boolean",
767
+ "default": "false"
768
+ },
757
769
  {
758
770
  "name": "subscribe",
759
771
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -828,6 +840,20 @@
828
840
  {
829
841
  "name": "lastSelected"
830
842
  },
843
+ {
844
+ "name": "preload",
845
+ "attribute": "preload",
846
+ "description": "If set, the entire list of possible suggestions will be preloaded upon initialization of the\ncomponent.",
847
+ "type": "boolean",
848
+ "default": "false"
849
+ },
850
+ {
851
+ "name": "substring",
852
+ "attribute": "substring",
853
+ "description": "By default suggestions are filtered by prefix, i.e. only suggestions starting with the prefix\ntyped by the user are shown. Set this property to true to search for the user-provided string\nanywhere within the suggestion text.",
854
+ "type": "boolean",
855
+ "default": "false"
856
+ },
831
857
  {
832
858
  "name": "subscribe",
833
859
  "attribute": "subscribe",
@@ -8258,6 +8284,11 @@
8258
8284
  "type": "string",
8259
8285
  "default": "\"search.placeholder\""
8260
8286
  },
8287
+ {
8288
+ "name": "disable-autocomplete",
8289
+ "type": "boolean",
8290
+ "default": "false"
8291
+ },
8261
8292
  {
8262
8293
  "name": "subscribe",
8263
8294
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -8330,6 +8361,12 @@
8330
8361
  "type": "string",
8331
8362
  "default": "\"search.placeholder\""
8332
8363
  },
8364
+ {
8365
+ "name": "disableAutocomplete",
8366
+ "attribute": "disable-autocomplete",
8367
+ "type": "boolean",
8368
+ "default": "false"
8369
+ },
8333
8370
  {
8334
8371
  "name": "subscribe",
8335
8372
  "attribute": "subscribe",
@@ -10222,6 +10259,12 @@
10222
10259
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10223
10260
  "type": "string"
10224
10261
  },
10262
+ {
10263
+ "name": "no-scroll",
10264
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10265
+ "type": "boolean",
10266
+ "default": "false"
10267
+ },
10225
10268
  {
10226
10269
  "name": "static",
10227
10270
  "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).\nThe value should point to the HTTP root path under which the static version\nwill be hosted. This is used to resolve CSS stylesheets.",
@@ -10422,6 +10465,13 @@
10422
10465
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10423
10466
  "type": "string"
10424
10467
  },
10468
+ {
10469
+ "name": "noScroll",
10470
+ "attribute": "no-scroll",
10471
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10472
+ "type": "boolean",
10473
+ "default": "false"
10474
+ },
10425
10475
  {
10426
10476
  "name": "static",
10427
10477
  "attribute": "static",
@@ -10688,6 +10738,12 @@
10688
10738
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10689
10739
  "type": "string"
10690
10740
  },
10741
+ {
10742
+ "name": "no-scroll",
10743
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10744
+ "type": "boolean",
10745
+ "default": "false"
10746
+ },
10691
10747
  {
10692
10748
  "name": "static",
10693
10749
  "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).\nThe value should point to the HTTP root path under which the static version\nwill be hosted. This is used to resolve CSS stylesheets.",
@@ -10871,6 +10927,13 @@
10871
10927
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10872
10928
  "type": "string"
10873
10929
  },
10930
+ {
10931
+ "name": "noScroll",
10932
+ "attribute": "no-scroll",
10933
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10934
+ "type": "boolean",
10935
+ "default": "false"
10936
+ },
10874
10937
  {
10875
10938
  "name": "static",
10876
10939
  "attribute": "static",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teipublisher/pb-components",
3
- "version": "1.34.3",
3
+ "version": "1.35.2",
4
4
  "description": "Collection of webcomponents underlying TEI Publisher",
5
5
  "repository": "https://github.com/eeditiones/tei-publisher-components.git",
6
6
  "main": "index.html",
package/pb-elements.json CHANGED
@@ -754,6 +754,18 @@
754
754
  "type": "array",
755
755
  "default": "[]"
756
756
  },
757
+ {
758
+ "name": "preload",
759
+ "description": "If set, the entire list of possible suggestions will be preloaded upon initialization of the\ncomponent.",
760
+ "type": "boolean",
761
+ "default": "false"
762
+ },
763
+ {
764
+ "name": "substring",
765
+ "description": "By default suggestions are filtered by prefix, i.e. only suggestions starting with the prefix\ntyped by the user are shown. Set this property to true to search for the user-provided string\nanywhere within the suggestion text.",
766
+ "type": "boolean",
767
+ "default": "false"
768
+ },
757
769
  {
758
770
  "name": "subscribe",
759
771
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -828,6 +840,20 @@
828
840
  {
829
841
  "name": "lastSelected"
830
842
  },
843
+ {
844
+ "name": "preload",
845
+ "attribute": "preload",
846
+ "description": "If set, the entire list of possible suggestions will be preloaded upon initialization of the\ncomponent.",
847
+ "type": "boolean",
848
+ "default": "false"
849
+ },
850
+ {
851
+ "name": "substring",
852
+ "attribute": "substring",
853
+ "description": "By default suggestions are filtered by prefix, i.e. only suggestions starting with the prefix\ntyped by the user are shown. Set this property to true to search for the user-provided string\nanywhere within the suggestion text.",
854
+ "type": "boolean",
855
+ "default": "false"
856
+ },
831
857
  {
832
858
  "name": "subscribe",
833
859
  "attribute": "subscribe",
@@ -8258,6 +8284,11 @@
8258
8284
  "type": "string",
8259
8285
  "default": "\"search.placeholder\""
8260
8286
  },
8287
+ {
8288
+ "name": "disable-autocomplete",
8289
+ "type": "boolean",
8290
+ "default": "false"
8291
+ },
8261
8292
  {
8262
8293
  "name": "subscribe",
8263
8294
  "description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
@@ -8330,6 +8361,12 @@
8330
8361
  "type": "string",
8331
8362
  "default": "\"search.placeholder\""
8332
8363
  },
8364
+ {
8365
+ "name": "disableAutocomplete",
8366
+ "attribute": "disable-autocomplete",
8367
+ "type": "boolean",
8368
+ "default": "false"
8369
+ },
8333
8370
  {
8334
8371
  "name": "subscribe",
8335
8372
  "attribute": "subscribe",
@@ -10222,6 +10259,12 @@
10222
10259
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10223
10260
  "type": "string"
10224
10261
  },
10262
+ {
10263
+ "name": "no-scroll",
10264
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10265
+ "type": "boolean",
10266
+ "default": "false"
10267
+ },
10225
10268
  {
10226
10269
  "name": "static",
10227
10270
  "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).\nThe value should point to the HTTP root path under which the static version\nwill be hosted. This is used to resolve CSS stylesheets.",
@@ -10422,6 +10465,13 @@
10422
10465
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10423
10466
  "type": "string"
10424
10467
  },
10468
+ {
10469
+ "name": "noScroll",
10470
+ "attribute": "no-scroll",
10471
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10472
+ "type": "boolean",
10473
+ "default": "false"
10474
+ },
10425
10475
  {
10426
10476
  "name": "static",
10427
10477
  "attribute": "static",
@@ -10688,6 +10738,12 @@
10688
10738
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10689
10739
  "type": "string"
10690
10740
  },
10741
+ {
10742
+ "name": "no-scroll",
10743
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10744
+ "type": "boolean",
10745
+ "default": "false"
10746
+ },
10691
10747
  {
10692
10748
  "name": "static",
10693
10749
  "description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).\nThe value should point to the HTTP root path under which the static version\nwill be hosted. This is used to resolve CSS stylesheets.",
@@ -10871,6 +10927,13 @@
10871
10927
  "description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
10872
10928
  "type": "string"
10873
10929
  },
10930
+ {
10931
+ "name": "noScroll",
10932
+ "attribute": "no-scroll",
10933
+ "description": "If set, do not scroll the view to target node (e.g. given in URL hash) \nafter content was loaded.",
10934
+ "type": "boolean",
10935
+ "default": "false"
10936
+ },
10874
10937
  {
10875
10938
  "name": "static",
10876
10939
  "attribute": "static",
@@ -6,6 +6,31 @@ import '@polymer/iron-ajax';
6
6
  import '@polymer/iron-icon';
7
7
  import '@cwmr/paper-autocomplete/paper-autocomplete-suggestions.js';
8
8
 
9
+ function _query(datasource, query) {
10
+ const queryResult = [];
11
+ datasource.forEach((item) => {
12
+ let objText, objValue;
13
+
14
+ if (typeof item === 'object') {
15
+ objText = item.text;
16
+ objValue = item.value;
17
+ } else {
18
+ objText = item.toString();
19
+ objValue = objText;
20
+ }
21
+
22
+ if (objText.toLowerCase().indexOf(query) > -1) {
23
+ // NOTE: the structure of the result object matches with the current template. For custom templates, you
24
+ // might need to return more data
25
+ const resultItem = {};
26
+ resultItem.text = objText;
27
+ resultItem.value = objValue;
28
+ queryResult.push(resultItem);
29
+ }
30
+ });
31
+ return queryResult;
32
+ }
33
+
9
34
  /**
10
35
  * Provides an input with attached autocomplete. The autocomplete suggestions can be read
11
36
  * either from a static list or a remote endpoint to which the current user input is sent.
@@ -52,6 +77,13 @@ export class PbAutocomplete extends pbMixin(LitElement) {
52
77
  source: {
53
78
  type: String
54
79
  },
80
+ /**
81
+ * If set, the entire list of possible suggestions will be preloaded upon initialization of the
82
+ * component.
83
+ */
84
+ preload: {
85
+ type: Boolean
86
+ },
55
87
  /**
56
88
  * A static list of suggestions. Use instead of `source`. May either be a flat array of strings,
57
89
  * or an array containing objects of the form `{"text": "", "value": ""}, in which case "value" denotes
@@ -60,6 +92,14 @@ export class PbAutocomplete extends pbMixin(LitElement) {
60
92
  suggestions: {
61
93
  type: Array
62
94
  },
95
+ /**
96
+ * By default suggestions are filtered by prefix, i.e. only suggestions starting with the prefix
97
+ * typed by the user are shown. Set this property to true to search for the user-provided string
98
+ * anywhere within the suggestion text.
99
+ */
100
+ substring: {
101
+ type: Boolean
102
+ },
63
103
  /**
64
104
  * An icon to display next to the input.
65
105
  */
@@ -74,6 +114,8 @@ export class PbAutocomplete extends pbMixin(LitElement) {
74
114
  this.placeholder = 'search.placeholder';
75
115
  this.suggestions = [];
76
116
  this.lastSelected = null;
117
+ this.preload = false;
118
+ this.substring = false;
77
119
  this._hiddenInput = null;
78
120
  this._initialized = false;
79
121
  }
@@ -94,7 +136,14 @@ export class PbAutocomplete extends pbMixin(LitElement) {
94
136
  const autocomplete = this.shadowRoot.getElementById('autocomplete');
95
137
  autocomplete.addEventListener('autocomplete-change', this._autocomplete.bind(this));
96
138
 
97
- if (this.value) {
139
+ if (this.preload && this.source) {
140
+ if (this.substring) {
141
+ autocomplete.queryFn = _query;
142
+ }
143
+ PbAutocomplete.waitOnce('pb-page-ready', () => {
144
+ this._sendRequest();
145
+ });
146
+ } else if (this.value) {
98
147
  if (this.source) {
99
148
  PbAutocomplete.waitOnce('pb-page-ready', () => {
100
149
  //console.log('send autocomplete request for remote source %s on value %s', this.source, this.value);
@@ -140,7 +189,7 @@ export class PbAutocomplete extends pbMixin(LitElement) {
140
189
  always-float-label>
141
190
  ${this.icon ? html`<iron-icon icon="${this.icon}" slot="prefix"></iron-icon>` : null}
142
191
  </paper-input>
143
- <paper-autocomplete-suggestions id="autocomplete" for="search" .source="${this.suggestions}" ?remote-source="${this.source}"
192
+ <paper-autocomplete-suggestions id="autocomplete" for="search" .source="${this.suggestions}" ?remote-source="${!this.preload && this.source}"
144
193
  @autocomplete-selected="${this._autocompleteSelected}"></paper-autocomplete-suggestions>
145
194
 
146
195
  <iron-ajax
@@ -179,7 +228,6 @@ export class PbAutocomplete extends pbMixin(LitElement) {
179
228
  this._sendRequest(search.value);
180
229
  }
181
230
 
182
-
183
231
  _sendRequest(query) {
184
232
  const loader = this.shadowRoot.getElementById('autocompleteLoader');
185
233
  loader.url = this.toAbsoluteURL(this.source);
@@ -195,35 +243,33 @@ export class PbAutocomplete extends pbMixin(LitElement) {
195
243
 
196
244
  _updateSuggestions() {
197
245
  const loader = this.shadowRoot.getElementById('autocompleteLoader');
198
-
199
246
  if (this._initialized) {
200
247
  const autocomplete = this.shadowRoot.getElementById('autocomplete');
201
248
  if (loader.lastResponse) {
202
249
  this.suggestions = loader.lastResponse;
203
250
  autocomplete.suggestions(this.suggestions);
204
251
  }
205
- } else {
206
- if (loader.lastResponse) {
207
- let suggestions = loader.lastResponse;
208
- //console.log('suggestions received', suggestions);
252
+ } else if (loader.lastResponse) {
253
+ const suggestions = loader.lastResponse;
209
254
 
210
- const input = this.shadowRoot.getElementById('search');
211
- const value = suggestions.find((suggestion) => {
212
- if (suggestion.text) {
213
- return suggestion.value === this.value;
214
- }
215
- return suggestion === this.value;
216
- });
217
- if (value) {
218
- input.value = value.text || value;
219
- if (this._hiddenInput) {
220
- this._hiddenInput.value = value.value || value;
221
- }
222
- } else {
223
- if (this._hiddenInput) {
224
- this._hiddenInput.value = this.value;
225
- }
255
+ const input = this.shadowRoot.getElementById('search');
256
+ const value = suggestions.find((suggestion) => {
257
+ if (suggestion.text) {
258
+ return suggestion.value === this.value;
226
259
  }
260
+ return suggestion === this.value;
261
+ });
262
+ if (value) {
263
+ input.value = value.text || value;
264
+ if (this._hiddenInput) {
265
+ this._hiddenInput.value = value.value || value;
266
+ }
267
+ } else if (this._hiddenInput) {
268
+ this._hiddenInput.value = this.value;
269
+ }
270
+
271
+ if (this.preload) {
272
+ this.suggestions = suggestions;
227
273
  }
228
274
  }
229
275
  this._initialized = true;
@@ -242,22 +288,48 @@ export class PbAutocomplete extends pbMixin(LitElement) {
242
288
  _autocompleteSelected(ev) {
243
289
  this.lastSelected = ev.detail.text;
244
290
  const input = this.shadowRoot.getElementById('search');
245
- console.log('autocomplete selected %s', ev.detail.text);
246
291
  input.value = ev.detail.text;
247
292
  this.value = ev.detail.value;
248
293
  if (this._hiddenInput) {
249
294
  this._hiddenInput.value = this.value;
250
295
  }
296
+
297
+ this.emitTo('pb-autocomplete-selected', {
298
+ text: ev.detail.text,
299
+ value: ev.detail.value
300
+ });
251
301
  }
252
302
 
253
303
  _setInput(ev) {
254
304
  const input = this.shadowRoot.getElementById('search');
255
- console.log('Autocomplete set manually to %s', input.value);
256
-
257
305
  this.value = input.value;
306
+
258
307
  if (this._hiddenInput) {
259
308
  this._hiddenInput.value = this.value;
260
309
  }
310
+
311
+ if (ev.keyCode === 13) {
312
+ const entry = this.suggestions.find((suggestion) => {
313
+ if (suggestion.text) {
314
+ return suggestion.value === this.value;
315
+ }
316
+ return suggestion === this.value;
317
+ });
318
+ if (!entry) {
319
+ return;
320
+ }
321
+ if (entry.value) {
322
+ this.emitTo('pb-autocomplete-selected', {
323
+ text: entry.text,
324
+ value: entry.value
325
+ });
326
+ } else {
327
+ this.emitTo('pb-autocomplete-selected', {
328
+ text: entry,
329
+ value: entry
330
+ });
331
+ }
332
+ }
261
333
  }
262
334
 
263
335
 
package/src/pb-search.js CHANGED
@@ -51,6 +51,10 @@ export class PbSearch extends pbMixin(LitElement) {
51
51
  },
52
52
  subforms: {
53
53
  type: String
54
+ },
55
+ disableAutocomplete: {
56
+ type: Boolean,
57
+ attribute: 'disable-autocomplete'
54
58
  }
55
59
  };
56
60
  }
@@ -61,6 +65,7 @@ export class PbSearch extends pbMixin(LitElement) {
61
65
  this.redirect = false;
62
66
  this.submitOnLoad = false;
63
67
  this.placeHolder = 'search.placeholder';
68
+ this.disableAutocomplete = false;
64
69
  }
65
70
 
66
71
  connectedCallback() {
@@ -70,8 +75,10 @@ export class PbSearch extends pbMixin(LitElement) {
70
75
  }
71
76
 
72
77
  firstUpdated() {
73
- const autocomplete = this.shadowRoot.getElementById('autocomplete');
74
- autocomplete.addEventListener('autocomplete-change', this._autocomplete.bind(this));
78
+ if (!this.disableAutocomplete) {
79
+ const autocomplete = this.shadowRoot.getElementById('autocomplete');
80
+ autocomplete.addEventListener('autocomplete-change', this._autocomplete.bind(this));
81
+ }
75
82
  const ironform = this.shadowRoot.getElementById('ironform');
76
83
  ironform.addEventListener('iron-form-response', (event) =>
77
84
  event.detail.completes.then((r) => this.emitTo('pb-search', r.parseResponse()))
package/src/pb-view.js CHANGED
@@ -294,6 +294,14 @@ export class PbView extends pbMixin(LitElement) {
294
294
  type: String,
295
295
  attribute: 'before-update-event'
296
296
  },
297
+ /**
298
+ * If set, do not scroll the view to target node (e.g. given in URL hash)
299
+ * after content was loaded.
300
+ */
301
+ noScroll: {
302
+ type: Boolean,
303
+ attribute: 'no-scroll'
304
+ },
297
305
  _features: {
298
306
  type: Object
299
307
  },
@@ -335,6 +343,7 @@ export class PbView extends pbMixin(LitElement) {
335
343
  this.infiniteScrollMax = 10;
336
344
  this.disableHistory = false;
337
345
  this.beforeUpdate = null;
346
+ this.noScroll = false;
338
347
  this._features = {};
339
348
  this._selector = new Map();
340
349
  this._chunks = [];
@@ -520,7 +529,7 @@ export class PbView extends pbMixin(LitElement) {
520
529
 
521
530
  _refresh(ev) {
522
531
  if (ev && ev.detail) {
523
- if (ev.detail.hash && !(ev.detail.id || ev.detail.path || ev.detail.odd || ev.detail.view || ev.detail.position)) {
532
+ if (ev.detail.hash && !this.noScroll && !(ev.detail.id || ev.detail.path || ev.detail.odd || ev.detail.view || ev.detail.position)) {
524
533
  // if only the scroll target has changed: scroll to the element without reloading
525
534
  this._scrollTarget = ev.detail.hash;
526
535
  const target = this.shadowRoot.getElementById(this._scrollTarget);
@@ -541,13 +550,19 @@ export class PbView extends pbMixin(LitElement) {
541
550
  this.columnSeparator = ev.detail.columnSeparator;
542
551
  }
543
552
  this.view = ev.detail.view || this.view;
553
+ if (ev.detail.xpath) {
554
+ this.xpath = ev.detail.xpath;
555
+ this.nodeId = null;
556
+ }
544
557
  // clear nodeId if set to null
545
558
  if (ev.detail.position === null) {
546
559
  this.nodeId = null;
547
560
  } else {
548
561
  this.nodeId = ev.detail.position || this.nodeId;
549
562
  }
550
- this._scrollTarget = ev.detail.hash;
563
+ if (!this.noScroll) {
564
+ this._scrollTarget = ev.detail.hash;
565
+ }
551
566
  }
552
567
  this._updateStyles();
553
568
  if (this.infiniteScroll) {
@@ -863,12 +878,19 @@ export class PbView extends pbMixin(LitElement) {
863
878
  }
864
879
 
865
880
  _scroll() {
881
+ if (this.noScroll) {
882
+ return;
883
+ }
866
884
  const { hash } = this.getUrl();
867
885
  if (hash) {
868
886
  const target = this.shadowRoot.getElementById(hash.substring(1));
869
887
  console.log('hash target: %o', target);
870
888
  if (target) {
871
- target.scrollIntoView({ block: "center", inline: "nearest" });
889
+ window.requestAnimationFrame(() =>
890
+ setTimeout(() => {
891
+ target.scrollIntoView({block: 'nearest'});
892
+ }, 400)
893
+ );
872
894
  }
873
895
  }
874
896
  }