@teipublisher/pb-components 1.44.1 → 2.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/demo/demos.json +2 -1
  3. package/dist/demo/pb-browse-docs.html +2 -1
  4. package/dist/demo/pb-combo-box.html +1 -1
  5. package/dist/demo/pb-document.html +2 -2
  6. package/dist/demo/pb-load.html +2 -2
  7. package/dist/demo/pb-select-feature.html +1 -1
  8. package/dist/demo/pb-select-feature2.html +10 -3
  9. package/dist/demo/pb-select-feature3.html +1 -1
  10. package/dist/demo/pb-select-odd.html +1 -1
  11. package/dist/demo/pb-table-grid.html +1 -1
  12. package/dist/demo/pb-tabs.html +8 -2
  13. package/dist/demo/pb-toggle-feature.html +2 -2
  14. package/dist/demo/pb-toggle-feature2.html +2 -2
  15. package/dist/demo/pb-toggle-feature3.html +2 -2
  16. package/dist/demo/pb-view.html +1 -1
  17. package/dist/demo/pb-view4.html +86 -0
  18. package/dist/pb-code-editor.js +1 -1
  19. package/dist/pb-component-docs.js +33 -33
  20. package/dist/pb-components-bundle.js +173 -173
  21. package/dist/pb-edit-app.js +6 -6
  22. package/dist/pb-elements.json +94 -28
  23. package/dist/{pb-i18n-3963b098.js → pb-i18n-8a90c591.js} +1 -1
  24. package/dist/pb-leaflet-map.js +1 -1
  25. package/dist/pb-mixin-8a593923.js +158 -0
  26. package/dist/pb-odd-editor.js +47 -47
  27. package/dist/{vaadin-element-mixin-08cf11b5.js → vaadin-element-mixin-672938e3.js} +18 -18
  28. package/i18n/common/en.json +9 -1
  29. package/package.json +5 -4
  30. package/pb-elements.json +94 -28
  31. package/src/dts-client.js +14 -14
  32. package/src/dts-select-endpoint.js +5 -5
  33. package/src/pb-ajax.js +4 -4
  34. package/src/pb-authority-lookup.js +2 -2
  35. package/src/pb-autocomplete.js +9 -11
  36. package/src/pb-blacklab-highlight.js +3 -3
  37. package/src/pb-browse-docs.js +44 -27
  38. package/src/pb-browse.js +9 -3
  39. package/src/pb-combo-box.js +2 -2
  40. package/src/pb-document.js +15 -1
  41. package/src/pb-download.js +2 -2
  42. package/src/pb-edit-app.js +2 -2
  43. package/src/pb-edit-xml.js +2 -2
  44. package/src/pb-events.js +26 -18
  45. package/src/pb-facsimile.js +28 -4
  46. package/src/pb-grid.js +55 -53
  47. package/src/pb-lang.js +2 -2
  48. package/src/pb-link.js +10 -16
  49. package/src/pb-load.js +35 -25
  50. package/src/pb-login.js +2 -2
  51. package/src/pb-manage-odds.js +2 -2
  52. package/src/pb-markdown.js +2 -2
  53. package/src/pb-mei.js +2 -2
  54. package/src/pb-mixin.js +103 -196
  55. package/src/pb-odd-editor.js +2 -2
  56. package/src/pb-page.js +30 -21
  57. package/src/pb-paginate.js +24 -19
  58. package/src/pb-print-preview.js +2 -2
  59. package/src/pb-repeat.js +2 -1
  60. package/src/pb-search.js +34 -8
  61. package/src/pb-select-feature.js +62 -39
  62. package/src/pb-select-odd.js +8 -7
  63. package/src/pb-select-template.js +5 -4
  64. package/src/pb-select.js +31 -28
  65. package/src/pb-split-list.js +18 -11
  66. package/src/pb-table-grid.js +9 -8
  67. package/src/pb-tabs.js +29 -12
  68. package/src/pb-toggle-feature.js +51 -55
  69. package/src/pb-upload.js +10 -3
  70. package/src/pb-view.js +118 -95
  71. package/src/theming.js +148 -149
  72. package/src/urls.js +233 -0
  73. package/dist/pb-mixin-88125cb2.js +0 -158
@@ -1,6 +1,20 @@
1
1
  import { LitElement, html } from 'lit-element';
2
- import { pbMixin } from './pb-mixin';
3
2
  import '@polymer/paper-checkbox';
3
+ import { pbMixin } from './pb-mixin.js';
4
+ import { registry } from "./urls.js";
5
+
6
+ /**
7
+ * @param {{ selector: any; command: string; state: boolean; }} newConfig
8
+ * @param {any[]} configs
9
+ */
10
+ export function addSelector(newConfig, configs) {
11
+ const idx = configs.findIndex((item) => item.selector === newConfig.selector);
12
+ if (idx > -1) {
13
+ configs[idx] = newConfig;
14
+ } else {
15
+ configs.push(newConfig);
16
+ }
17
+ }
4
18
 
5
19
  /**
6
20
  * Enable or disable a particular display feature by setting a predefined or custom parameter.
@@ -153,6 +167,8 @@ export class PbToggleFeature extends pbMixin(LitElement) {
153
167
  constructor() {
154
168
  super();
155
169
  this.default = 'on';
170
+ this.on = 'on';
171
+ this.off = 'off';
156
172
  this.action = 'toggle';
157
173
  this.propertiesOn = {};
158
174
  this.propertiesOff = {};
@@ -168,58 +184,36 @@ export class PbToggleFeature extends pbMixin(LitElement) {
168
184
  connectedCallback() {
169
185
  super.connectedCallback();
170
186
 
171
- if (this.initFromView) {
172
- const initHandler = this.subscribeTo('pb-update', (ev) => {
173
- if (this.name === 'infiniteScroll') {
174
- this.checked = ev.detail.infiniteScroll === this.propertiesOn[this.name];
175
- } else if (this.name === 'view' || this.name === 'odd' || this.name === 'xpath') {
176
- this.checked = ev.detail.data[this.name] === this.propertiesOn[this.name];
177
- }
178
- initHandler.forEach((handler) => document.removeEventListener('pb-update', handler));
179
- });
180
- this.waitForChannel(() => {
181
- const params = {
182
- selectors: [{
183
- selector: this.selector,
184
- command: this.action,
185
- state: this.checked
186
- }],
187
- properties: {},
188
- action: 'init'
189
- };
190
- this.emitTo('pb-toggle', params);
191
- this.signalReady();
192
- });
187
+ registry.subscribe(this, (state) => {
188
+ const param = state[this.name];
189
+ this._setChecked(param);
190
+ });
191
+
192
+ const param = registry.state[this.name];
193
+ this._setChecked(param);
194
+
195
+ const newState = {};
196
+ newState[this.name] = this.checked ? this.on : this.off;
197
+ registry.replace(this, newState);
198
+ this._saveState();
199
+ this.signalReady();
200
+ }
201
+
202
+ _setChecked(param) {
203
+ if (typeof param !== 'undefined') {
204
+ this.checked = param === this.on;
193
205
  } else {
194
- const param = this.getParameter(this.name);
195
- if (typeof param !== 'undefined') {
196
- this.checked = param === 'on';
197
- } else {
198
- this.checked = this.default === 'on';
199
- }
200
- this.waitForChannel(() => {
201
- const params = {
202
- selectors: [{
203
- selector: this.selector,
204
- command: this.action,
205
- state: this.checked
206
- }],
207
- properties: this.checked ? this.propertiesOn : this.propertiesOff,
208
- action: 'init'
209
- };
210
- this.emitTo('pb-toggle', params);
211
- this.signalReady();
212
- });
206
+ this.checked = this.default === this.on;
213
207
  }
214
208
  }
215
209
 
216
210
  attributeChangedCallback(name, oldVal, newVal) {
217
211
  super.attributeChangedCallback(name, oldVal, newVal);
218
212
  switch (name) {
219
- case 'on':
213
+ case this.on:
220
214
  this.propertiesOn[this.name] = newVal;
221
215
  break;
222
- case 'off':
216
+ case this.off:
223
217
  this.propertiesOff[this.name] = newVal;
224
218
  break;
225
219
  default:
@@ -229,21 +223,23 @@ export class PbToggleFeature extends pbMixin(LitElement) {
229
223
 
230
224
  _changed() {
231
225
  this.checked = this.shadowRoot.getElementById('checkbox').checked;
232
- if (this.name) {
233
- this.setParameter(this.name, this.checked ? 'on' : 'off');
234
- this.pushHistory('toggle feature ' + this.name);
235
- }
236
226
 
237
- const params = {
238
- selectors: [{
227
+ this._saveState();
228
+ this.emitTo('pb-toggle', {refresh: !this.selector});
229
+ }
230
+
231
+ _saveState() {
232
+ const state = registry.getState(this);
233
+ state[this.name] = this.checked ? this.on : this.off;
234
+ Object.assign(state, this.checked ? this.propertiesOn : this.propertiesOff);
235
+ if (this.selector) {
236
+ state.selectors = state.selectors || [];
237
+ addSelector({
239
238
  selector: this.selector,
240
239
  command: this.action,
241
240
  state: this.checked
242
- }],
243
- properties: this.checked ? this.propertiesOn : this.propertiesOff,
244
- action: 'refresh'
245
- };
246
- this.emitTo('pb-toggle', params);
241
+ }, state.selectors);
242
+ }
247
243
  }
248
244
  }
249
245
 
package/src/pb-upload.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import { pbMixin } from './pb-mixin.js';
2
+ import { pbMixin, waitOnce } from './pb-mixin.js';
3
3
  import { translate } from "./pb-i18n.js";
4
4
  import { getCSSProperty } from "./utils.js";
5
5
  import '@vaadin/vaadin-upload';
@@ -37,6 +37,12 @@ export class PbUpload extends pbMixin(LitElement) {
37
37
  },
38
38
  _files: {
39
39
  type: Object
40
+ },
41
+ /**
42
+ * the event to emit when the upload has completed (default: 'pb-load')
43
+ */
44
+ event: {
45
+ type: String
40
46
  }
41
47
  };
42
48
  }
@@ -44,6 +50,7 @@ export class PbUpload extends pbMixin(LitElement) {
44
50
  constructor() {
45
51
  super();
46
52
  this._files = new Map();
53
+ this.event = 'pb-load';
47
54
  }
48
55
 
49
56
  connectedCallback() {
@@ -93,13 +100,13 @@ export class PbUpload extends pbMixin(LitElement) {
93
100
  });
94
101
  if (done) {
95
102
  this.emitTo('pb-end-update');
96
- this.emitTo('pb-load');
103
+ this.emitTo(this.event);
97
104
  if (oddsUploaded.length > 0) {
98
105
  this.emitTo('pb-refresh-odds', { 'odds': oddsUploaded });
99
106
  }
100
107
  }
101
108
  });
102
- PbUpload.waitOnce('pb-page-ready', () => {
109
+ waitOnce('pb-page-ready', () => {
103
110
  if (this.minApiVersion('1.0.0')) {
104
111
  uploader.target = `${this.getEndpoint()}/api/upload/`;
105
112
  } else {
package/src/pb-view.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
2
  import anime from 'animejs';
3
3
  import { pbMixin, waitOnce } from "./pb-mixin.js";
4
+ import { registry } from "./urls.js";
4
5
  import { translate } from "./pb-i18n.js";
5
6
  import { typesetMath } from "./pb-formula.js";
6
7
  import { loadStylesheets, themableMixin } from "./theming.js";
@@ -81,8 +82,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
81
82
  * or the `.odd` suffix.
82
83
  */
83
84
  odd: {
84
- type: String,
85
- reflect: true
85
+ type: String
86
86
  },
87
87
  /**
88
88
  * The view type to use for paginating the document. Either `page`, `div` or `single`.
@@ -95,8 +95,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
95
95
  * `single` | do not paginate but display entire content at once
96
96
  */
97
97
  view: {
98
- type: String,
99
- reflect: true
98
+ type: String
100
99
  },
101
100
  /**
102
101
  * An eXist nodeId. If specified, selects the root of the fragment of the document
@@ -104,7 +103,6 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
104
103
  */
105
104
  nodeId: {
106
105
  type: String,
107
- reflect: true,
108
106
  attribute: 'node-id'
109
107
  },
110
108
  /**
@@ -113,7 +111,6 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
113
111
  */
114
112
  xmlId: {
115
113
  type: Array,
116
- reflect: true,
117
114
  attribute: 'xml-id'
118
115
  },
119
116
  /**
@@ -125,8 +122,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
125
122
  * If the `map` property is used, it may change scope for the displayed fragment.
126
123
  */
127
124
  xpath: {
128
- type: String,
129
- reflect: true
125
+ type: String
130
126
  },
131
127
  /**
132
128
  * If defined denotes the local name of an XQuery function in `modules/map.xql`, which will be called
@@ -186,8 +182,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
186
182
  */
187
183
  suppressHighlight: {
188
184
  type: Boolean,
189
- attribute: 'suppress-highlight',
190
- reflect: true
185
+ attribute: 'suppress-highlight'
191
186
  },
192
187
  /**
193
188
  * CSS selector to find column breaks in the content returned
@@ -346,7 +341,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
346
341
  this.beforeUpdate = null;
347
342
  this.noScroll = false;
348
343
  this._features = {};
349
- this._selector = new Map();
344
+ this._selector = {};
350
345
  this._chunks = [];
351
346
  this._scrollTarget = null;
352
347
  this.static = null;
@@ -381,22 +376,36 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
381
376
  }
382
377
 
383
378
  if (!this.disableHistory) {
384
- const id = this.getParameter('id');
385
- if (id && !this.xmlId) {
386
- this.xmlId = id;
379
+ if (registry.state.id && !this.xmlId) {
380
+ this.xmlId = registry.state.id;
387
381
  }
388
382
 
389
- const action = this.getParameter('action');
390
- if (action && action === 'search') {
383
+ if (registry.state.action && registry.state.action === 'search') {
391
384
  this.highlight = true;
392
385
  }
393
386
 
394
- const nodeId = this.getParameter('root');
395
387
  if (this.view === 'single') {
396
388
  this.nodeId = null;
397
- } else if (nodeId && !this.nodeId) {
398
- this.nodeId = nodeId;
389
+ } else if (registry.state.root && !this.nodeId) {
390
+ this.nodeId = registry.state.root;
399
391
  }
392
+
393
+ const newState = {
394
+ id: this.xmlId,
395
+ view: this.getView(),
396
+ odd: this.getOdd(),
397
+ path: this.getDocument().path
398
+ };
399
+ if (this.view !== 'single') {
400
+ newState.root = this.nodeId;
401
+ }
402
+ console.log('id: %s; state: %o', this.id, newState);
403
+ registry.replace(this, newState);
404
+
405
+ registry.subscribe(this, (state) => {
406
+ this._setState(state);
407
+ this._refresh();
408
+ });
400
409
  }
401
410
  if (!this.waitFor) {
402
411
  this.waitFor = 'pb-toggle-feature,pb-select-feature,pb-navigation';
@@ -419,6 +428,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
419
428
  const needsRefresh = this._features.language && this._features.language !== ev.detail.language;
420
429
  this._features.language = ev.detail.language;
421
430
  if (this.useLanguage && needsRefresh) {
431
+ this._setState(registry.getState(this));
422
432
  this._refresh();
423
433
  }
424
434
  }, []);
@@ -426,7 +436,9 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
426
436
  this.signalReady();
427
437
 
428
438
  if (this.onUpdate) {
429
- this.subscribeTo('pb-update', this._refresh.bind(this));
439
+ this.subscribeTo('pb-update', () => {
440
+ this._refresh();
441
+ });
430
442
  }
431
443
  }
432
444
 
@@ -476,11 +488,16 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
476
488
  });
477
489
  }
478
490
  if (!this.onUpdate) {
479
- PbView.waitOnce('pb-page-ready', (data) => {
491
+ waitOnce('pb-page-ready', (data) => {
480
492
  if (data && data.language) {
481
493
  this._features.language = data.language;
482
494
  }
483
- this.wait(() => this._refresh());
495
+ this.wait(() => {
496
+ if (!this.disableHistory) {
497
+ this._setState(registry.state);
498
+ }
499
+ this._refresh();
500
+ });
484
501
  });
485
502
  }
486
503
  }
@@ -559,16 +576,16 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
559
576
  if (ev.detail.columnSeparator !== undefined) {
560
577
  this.columnSeparator = ev.detail.columnSeparator;
561
578
  }
562
- this.view = ev.detail.view || this.view;
579
+ this.view = ev.detail.view || this.getView();
563
580
  if (ev.detail.xpath) {
564
581
  this.xpath = ev.detail.xpath;
565
582
  this.nodeId = null;
566
583
  }
567
584
  // clear nodeId if set to null
568
- if (ev.detail.position === null) {
585
+ if (ev.detail.root === null) {
569
586
  this.nodeId = null;
570
587
  } else {
571
- this.nodeId = ev.detail.position || this.nodeId;
588
+ this.nodeId = ev.detail.root || this.nodeId;
572
589
  }
573
590
  if (!this.noScroll) {
574
591
  this._scrollTarget = ev.detail.hash;
@@ -626,22 +643,26 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
626
643
  loadContent.url = url;
627
644
  loadContent.generateRequest();
628
645
  });
629
- } else {
630
- if (!this.url) {
631
- if (this.minApiVersion('1.0.0')) {
632
- this.url = "api/parts";
633
- } else {
634
- this.url = "modules/lib/components.xql";
635
- }
636
- }
646
+ return;
647
+ }
648
+
649
+ if (!this.url) {
637
650
  if (this.minApiVersion('1.0.0')) {
638
- loadContent.url = `${this.getEndpoint()}/${this.url}/${encodeURIComponent(this.getDocument().path)}/json`;
651
+ this.url = "api/parts";
639
652
  } else {
640
- loadContent.url = `${this.getEndpoint()}/${this.url}`;
653
+ this.url = "modules/lib/components.xql";
641
654
  }
642
- loadContent.params = params;
643
- loadContent.generateRequest();
644
655
  }
656
+
657
+ let url = `${this.getEndpoint()}/${this.url}`;
658
+
659
+ if (this.minApiVersion('1.0.0')) {
660
+ url += `/${encodeURIComponent(this.getDocument().path)}/json`;
661
+ }
662
+
663
+ loadContent.url = url;
664
+ loadContent.params = params;
665
+ loadContent.generateRequest();
645
666
  }
646
667
 
647
668
  /**
@@ -749,11 +770,6 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
749
770
  this.previousId = resp.previousId;
750
771
  this.nodeId = resp.root;
751
772
  this.switchView = resp.switchView;
752
- if (!this.disableHistory && this.xmlId && !this.map) {
753
- //this.setParameter('root', this.nodeId);
754
- this.setParameter('id', this.xmlId);
755
- this.pushHistory('Navigate to xml:id');
756
- }
757
773
  this.xmlId = null;
758
774
 
759
775
  this.updateComplete.then(() => {
@@ -891,9 +907,8 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
891
907
  if (this.noScroll) {
892
908
  return;
893
909
  }
894
- const { hash } = this.getUrl();
895
- if (hash) {
896
- const target = this.shadowRoot.getElementById(hash.substring(1));
910
+ if (registry.state.id) {
911
+ const target = this.shadowRoot.getElementById(registry.state.id);
897
912
  console.log('hash target: %o', target);
898
913
  if (target) {
899
914
  window.requestAnimationFrame(() =>
@@ -1012,10 +1027,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1012
1027
  }
1013
1028
 
1014
1029
  _applyToggles(elem) {
1015
- if (this._selector.size === 0) {
1016
- return;
1017
- }
1018
- this._selector.forEach((setting, selector) => {
1030
+ for (const [selector, setting] of Object.entries(this._selector)) {
1019
1031
  elem.querySelectorAll(selector).forEach(node => {
1020
1032
  const command = setting.command || 'toggle';
1021
1033
  if (node.command) {
@@ -1027,7 +1039,7 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1027
1039
  node.classList.remove(command);
1028
1040
  }
1029
1041
  });
1030
- });
1042
+ }
1031
1043
  }
1032
1044
 
1033
1045
  /**
@@ -1056,28 +1068,29 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1056
1068
  * @param {string} direction either `backward` or `forward`
1057
1069
  */
1058
1070
  navigate(direction) {
1071
+ // in single view mode there should be no navigation
1072
+ if (this.getView() === 'single') {
1073
+ return;
1074
+ }
1075
+
1059
1076
  this.lastDirection = direction;
1060
1077
 
1061
1078
  if (direction === 'backward') {
1062
1079
  if (this.previous) {
1063
1080
  if (!this.disableHistory && !this.map) {
1064
- if (this.previousId) {
1065
- this.setParameter('id', this.previousId);
1066
- } else {
1067
- this.setParameter('root', this.previous);
1068
- }
1069
- this.pushHistory('Navigate backward');
1081
+ registry.commit(this, {
1082
+ id: this.previousId || null,
1083
+ root: this.previousId ? null : this.previous
1084
+ });
1070
1085
  }
1071
1086
  this._load(this.previous, direction);
1072
1087
  }
1073
1088
  } else if (this.next) {
1074
1089
  if (!this.disableHistory && !this.map) {
1075
- if (this.nextId) {
1076
- this.setParameter('id', this.nextId);
1077
- } else {
1078
- this.setParameter('root', this.next);
1079
- }
1080
- this.pushHistory('Navigate forward');
1090
+ registry.commit(this, {
1091
+ id: this.nextId || null,
1092
+ root: this.nextId ? null : this.next
1093
+ });
1081
1094
  }
1082
1095
  this._load(this.next, direction);
1083
1096
  }
@@ -1129,12 +1142,23 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1129
1142
  }
1130
1143
 
1131
1144
  toggleFeature(ev) {
1132
- const applyToggles = () => {
1145
+ const properties = registry.getState(this);
1146
+ if (properties) {
1147
+ this._setState(properties);
1148
+
1149
+ }
1150
+
1151
+ if (ev.detail.refresh) {
1152
+ this._updateStyles();
1153
+ this._load();
1154
+ } else {
1133
1155
  const view = this.shadowRoot.getElementById('view');
1134
1156
  this._applyToggles(view);
1135
1157
  }
1158
+ registry.commit(this, properties);
1159
+ }
1136
1160
 
1137
- const properties = ev.detail.properties;
1161
+ _setState(properties) {
1138
1162
  for (const [key, value] of Object.entries(properties)) {
1139
1163
  switch (key) {
1140
1164
  case 'odd':
@@ -1142,49 +1166,48 @@ export class PbView extends themableMixin(pbMixin(LitElement)) {
1142
1166
  case 'columnSeparator':
1143
1167
  case 'xpath':
1144
1168
  case 'nodeId':
1169
+ case 'path':
1170
+ case 'root':
1145
1171
  break;
1146
1172
  default:
1147
1173
  this._features[key] = value;
1148
1174
  break;
1149
1175
  }
1150
1176
  }
1151
- if (properties) {
1152
- if (properties.odd) {
1153
- this.odd = properties.odd;
1154
- }
1155
- if (properties.view) {
1156
- this.view = properties.view;
1157
- if (this.view === 'single') {
1158
- // when switching to single view, clear current node id
1159
- this.nodeId = null;
1160
- } else {
1161
- // otherwise use value for alternate view returned from server
1162
- this.nodeId = this.switchView;
1163
- }
1164
- }
1165
- if (properties.xpath) {
1166
- this.xpath = properties.xpath;
1167
- }
1168
- if (properties.hasOwnProperty('columnSeparator')) {
1169
- this.columnSeparator = properties.columnSeparator;
1177
+ if (properties.odd && !this.getAttribute('odd')) {
1178
+ this.odd = properties.odd;
1179
+ }
1180
+ if (properties.view && !this.getAttribute('view')) {
1181
+ this.view = properties.view;
1182
+ if (this.view === 'single') {
1183
+ // when switching to single view, clear current node id
1184
+ this.nodeId = null;
1185
+ } else {
1186
+ // otherwise use value for alternate view returned from server
1187
+ this.nodeId = this.switchView;
1170
1188
  }
1171
1189
  }
1172
- if (ev.detail.selectors) {
1173
- ev.detail.selectors.forEach(sc => {
1174
- this._selector.set(sc.selector, {
1190
+ if (properties.xpath && !this.getAttribute('xpath')) {
1191
+ this.xpath = properties.xpath;
1192
+ }
1193
+ if (properties.hasOwnProperty('columnSeparator')) {
1194
+ this.columnSeparator = properties.columnSeparator;
1195
+ }
1196
+ this.xmlId = (!this.getAttribute('xml-id') && properties.id) || this.xmlId;
1197
+ this.nodeId = (!this.getAttribute('xml-id') && properties.root) || null;
1198
+
1199
+ if (properties.path) {
1200
+ this.getDocument().path = properties.path;
1201
+ }
1202
+
1203
+ if (properties.selectors) {
1204
+ properties.selectors.forEach(sc => {
1205
+ this._selector[sc.selector] = {
1175
1206
  state: sc.state,
1176
1207
  command: sc.command || 'toggle'
1177
- });
1208
+ };
1178
1209
  });
1179
1210
  }
1180
- if (ev.detail.action === 'refresh') {
1181
- if (Object.keys(properties).length > 0) {
1182
- this._updateStyles();
1183
- this._load();
1184
- } else {
1185
- applyToggles();
1186
- }
1187
- }
1188
1211
  }
1189
1212
 
1190
1213
  _getFragmentBefore(node, ms) {