@teipublisher/pb-components 2.26.0-next-3.12 → 2.26.0-next-3.14

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 (136) hide show
  1. package/.github/workflows/main.yml +3 -3
  2. package/.github/workflows/node.js.yml +3 -3
  3. package/.github/workflows/release.js.yml +3 -3
  4. package/CHANGELOG.md +43 -0
  5. package/Dockerfile +78 -70
  6. package/css/components.css +5 -5
  7. package/dist/demo/pb-drawer2.html +1 -1
  8. package/dist/demo/pb-grid.html +19 -6
  9. package/dist/demo/pb-leaflet-map.html +1 -1
  10. package/dist/demo/pb-progress.html +2 -2
  11. package/dist/demo/pb-repeat.html +1 -3
  12. package/dist/demo/pb-view3.html +1 -1
  13. package/dist/{iron-form-277f9d42.js → iron-form-78b43d38.js} +1 -1
  14. package/dist/{paper-checkbox-4f410b1f.js → paper-checkbox-d16f23be.js} +44 -44
  15. package/dist/{paper-icon-button-0fb125c4.js → paper-icon-button-2cd9e0b4.js} +3 -3
  16. package/dist/{paper-listbox-c2468542.js → paper-listbox-2ad5c882.js} +7 -7
  17. package/dist/pb-code-editor.js +25 -20
  18. package/dist/pb-component-docs.js +58 -54
  19. package/dist/pb-components-bundle.js +2057 -2351
  20. package/dist/pb-edit-app.js +167 -107
  21. package/dist/pb-elements.json +45 -45
  22. package/dist/{pb-i18n-0611135a.js → pb-i18n-4cc00bfe.js} +1 -1
  23. package/dist/pb-leaflet-map.js +23 -23
  24. package/dist/pb-mei.js +56 -41
  25. package/dist/{pb-mixin-b1caa22e.js → pb-mixin-886ece32.js} +1 -1
  26. package/dist/pb-odd-editor.js +923 -756
  27. package/dist/pb-tify.js +2 -2
  28. package/dist/{vaadin-element-mixin-49ab4037.js → vaadin-element-mixin-c200b196.js} +179 -164
  29. package/gh-pages.js +5 -3
  30. package/i18n/common/pl.json +2 -2
  31. package/lib/openseadragon.min.js +1 -1
  32. package/package.json +2 -2
  33. package/pb-elements.json +45 -45
  34. package/src/assets/components.css +5 -5
  35. package/src/authority/airtable.js +20 -21
  36. package/src/authority/anton.js +129 -129
  37. package/src/authority/custom.js +23 -21
  38. package/src/authority/geonames.js +38 -32
  39. package/src/authority/gnd.js +47 -42
  40. package/src/authority/kbga.js +137 -134
  41. package/src/authority/metagrid.js +44 -46
  42. package/src/authority/reconciliation.js +66 -67
  43. package/src/authority/registry.js +4 -4
  44. package/src/docs/pb-component-docs.js +2 -2
  45. package/src/docs/pb-component-view.js +5 -5
  46. package/src/docs/pb-components-list.js +2 -2
  47. package/src/docs/pb-demo-snippet.js +2 -2
  48. package/src/dts-client.js +299 -297
  49. package/src/dts-select-endpoint.js +90 -82
  50. package/src/parse-date-service.js +184 -135
  51. package/src/pb-ajax.js +150 -146
  52. package/src/pb-authority-lookup.js +183 -146
  53. package/src/pb-autocomplete.js +292 -280
  54. package/src/pb-blacklab-highlight.js +264 -259
  55. package/src/pb-blacklab-results.js +236 -221
  56. package/src/pb-browse-docs.js +540 -475
  57. package/src/pb-browse.js +68 -65
  58. package/src/pb-clipboard.js +79 -76
  59. package/src/pb-code-editor.js +110 -102
  60. package/src/pb-code-highlight.js +209 -204
  61. package/src/pb-codepen.js +79 -72
  62. package/src/pb-collapse.js +212 -207
  63. package/src/pb-combo-box.js +190 -190
  64. package/src/pb-components-bundle.js +1 -1
  65. package/src/pb-custom-form.js +151 -149
  66. package/src/pb-dialog.js +94 -85
  67. package/src/pb-document.js +89 -90
  68. package/src/pb-download.js +210 -198
  69. package/src/pb-drawer.js +145 -148
  70. package/src/pb-edit-app.js +301 -229
  71. package/src/pb-edit-xml.js +98 -96
  72. package/src/pb-events.js +114 -107
  73. package/src/pb-facs-link.js +104 -102
  74. package/src/pb-facsimile.js +419 -414
  75. package/src/pb-formula.js +151 -153
  76. package/src/pb-geolocation.js +129 -131
  77. package/src/pb-grid-action.js +53 -56
  78. package/src/pb-grid.js +231 -228
  79. package/src/pb-highlight.js +140 -140
  80. package/src/pb-hotkeys.js +40 -42
  81. package/src/pb-i18n.js +101 -104
  82. package/src/pb-image-strip.js +84 -78
  83. package/src/pb-lang.js +132 -128
  84. package/src/pb-leaflet-map.js +488 -485
  85. package/src/pb-link.js +126 -124
  86. package/src/pb-load.js +431 -426
  87. package/src/pb-login.js +291 -248
  88. package/src/pb-manage-odds.js +364 -318
  89. package/src/pb-map-icon.js +89 -89
  90. package/src/pb-map-layer.js +85 -85
  91. package/src/pb-markdown.js +90 -99
  92. package/src/pb-media-query.js +74 -72
  93. package/src/pb-mei.js +306 -295
  94. package/src/pb-message.js +144 -144
  95. package/src/pb-mixin.js +269 -264
  96. package/src/pb-navigation.js +80 -82
  97. package/src/pb-observable.js +38 -38
  98. package/src/pb-odd-editor.js +1053 -955
  99. package/src/pb-odd-elementspec-editor.js +348 -297
  100. package/src/pb-odd-model-editor.js +1061 -901
  101. package/src/pb-odd-parameter-editor.js +200 -178
  102. package/src/pb-odd-rendition-editor.js +136 -124
  103. package/src/pb-page.js +431 -421
  104. package/src/pb-paginate.js +202 -190
  105. package/src/pb-panel.js +198 -182
  106. package/src/pb-popover-themes.js +7 -5
  107. package/src/pb-popover.js +296 -287
  108. package/src/pb-print-preview.js +127 -127
  109. package/src/pb-progress.js +51 -51
  110. package/src/pb-repeat.js +105 -104
  111. package/src/pb-restricted.js +84 -77
  112. package/src/pb-search.js +252 -241
  113. package/src/pb-select-feature.js +127 -120
  114. package/src/pb-select-odd.js +132 -124
  115. package/src/pb-select-template.js +89 -78
  116. package/src/pb-select.js +251 -227
  117. package/src/pb-split-list.js +179 -174
  118. package/src/pb-svg.js +80 -79
  119. package/src/pb-table-column.js +54 -54
  120. package/src/pb-table-grid.js +221 -203
  121. package/src/pb-tabs.js +61 -63
  122. package/src/pb-tify.js +154 -154
  123. package/src/pb-timeline.js +271 -229
  124. package/src/pb-toggle-feature.js +182 -175
  125. package/src/pb-upload.js +184 -174
  126. package/src/pb-version.js +30 -30
  127. package/src/pb-view-annotate.js +132 -98
  128. package/src/pb-view.js +1290 -1270
  129. package/src/pb-zoom.js +75 -59
  130. package/src/polymer-hack.js +1 -1
  131. package/src/search-result-service.js +256 -223
  132. package/src/seed-element.js +13 -20
  133. package/src/settings.js +4 -4
  134. package/src/theming.js +96 -96
  135. package/src/urls.js +289 -289
  136. package/src/utils.js +53 -51
@@ -1,10 +1,10 @@
1
1
  // @ts-nocheck
2
2
  import { LitElement, html, css } from 'lit-element';
3
- import { supported as fsSupported, fileSave } from "browser-fs-access";
4
- import { pbMixin, waitOnce } from './pb-mixin.js';
5
- import { pbHotkeys } from './pb-hotkeys.js';
3
+ import { supported as fsSupported, fileSave } from 'browser-fs-access';
6
4
  import { repeat } from 'lit-html/directives/repeat';
7
5
  import { ifDefined } from 'lit-html/directives/if-defined';
6
+ import { pbMixin, waitOnce } from './pb-mixin.js';
7
+ import { pbHotkeys } from './pb-hotkeys.js';
8
8
 
9
9
  import '@vaadin/vaadin-tabs/vaadin-tabs';
10
10
  import '@vaadin/vaadin-tabs/vaadin-tab';
@@ -19,11 +19,10 @@ import '@polymer/paper-item/paper-item';
19
19
  import '@cwmr/paper-autocomplete/paper-autocomplete';
20
20
  import './pb-collapse';
21
21
  import '@polymer/paper-checkbox/paper-checkbox';
22
- import './pb-odd-elementspec-editor.js';
22
+ import { PbOddElementspecEditor } from './pb-odd-elementspec-editor.js';
23
23
  import './pb-message.js';
24
24
 
25
- import { get as i18n, translate } from "./pb-i18n.js";
26
- import { PbOddElementspecEditor } from "./pb-odd-elementspec-editor";
25
+ import { get as i18n, translate } from './pb-i18n.js';
27
26
 
28
27
  /**
29
28
  * ODD editor component
@@ -35,903 +34,1000 @@ import { PbOddElementspecEditor } from "./pb-odd-elementspec-editor";
35
34
  * @cssprop --pb-heading-line-height
36
35
  */
37
36
  export class PbOddEditor extends pbHotkeys(pbMixin(LitElement)) {
38
-
39
- static get styles() {
40
- return css`
41
- :host {
42
- display: flex;
43
- /*margin: 30px 20px;*/
44
- margin:0;
45
- padding:0;
46
- height:auto;
47
- }
48
-
49
- #layout {
50
- width: 100%;
51
- display: grid;
52
- grid-template-columns: auto 1fr;
53
- grid-template-rows: auto 1fr;
54
- }
55
-
56
- #drawer {
57
- grid-column: 1 / 1;
58
- min-width: 320px;
59
- }
60
-
61
- #navlist {
62
- grid-column: 1 / 1;
63
- grid-row: 2 / 2;
64
- overflow: auto;
65
- height: 100%;
66
- }
67
-
68
- .specs {
69
- grid-column: 2 / 2;
70
- grid-row: 1 / span 2;
71
- overflow: auto;
72
- }
73
-
74
- section{
75
- padding:20px;
76
- }
77
-
78
- h3, h4 {
79
- font-family: var(--pb-heading-font-family);
80
- font-weight: var(--pb-heading-font-weight);
81
- line-height: var(--pb-heading-line-height);
82
- }
83
-
84
- /* ported over but not checked yet */
85
-
86
- .specs {
87
- padding:6px;
88
- }
89
-
90
- .metadata {
91
- display: block;
92
- }
93
-
94
- .metadata div {
95
- padding: 0 16px 16px;
96
- }
97
-
98
- .metadata paper-input {
99
- margin-bottom: 10px;
100
- }
101
-
102
- .metadata .extCssEdit {
103
- display: flex;
104
- align-items: center;
105
- padding: 0;
106
- }
107
- .metadata .extCssEdit paper-input {
108
- flex: 2;
109
- }
110
- .metadata .extCssEdit pb-edit-xml {
111
- width: 40px;
112
- }
113
-
114
- #jump-to {
115
- margin-top: 1em;
116
- }
117
-
118
- odd-model {
119
- border-bottom: 1px solid #E0E0E0;
120
- }
121
- odd-model h4 {
122
- margin-top: 15px;
123
- padding-top: 5px;
124
- border-top: 1px solid #E0E0E0;
125
- }
126
- .renditions {
127
- margin-top: 10px;
128
- }
129
- .icons{
130
- display:inline-block;
131
- white-space: nowrap;
132
- }
133
-
134
- details {
135
- --details-transition-duration:0.8s;
136
- }
137
- details[open] {
138
- padding: 0;
139
- }
140
-
141
- pb-message#errorMsg{
142
- background: var(--paper-red-500);
143
- color:white;
144
- }
145
- .card-content{
146
- height:100%;
147
- overflow:auto;
148
- }
149
-
150
- paper-tab{
151
- width:100px;
152
- }
153
-
154
- .editingView {
155
- width:100%;
156
- }
157
-
158
- vaadin-tabs{
159
- margin-top:10px;
160
- }
161
-
162
- vaadin-tab{
163
- background:var(--paper-grey-200);
164
- padding:0 6px;
165
- border:thin solid var(--paper-grey-300);
166
- border-bottom:none;
167
- }
168
- vaadin-tab[selected]{
169
- background:white;
170
- border-top-right-radius:20px;
171
- box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
172
- 0 1px 5px 0 rgba(0, 0, 0, 0.12),
173
- 0 3px 1px -2px rgba(0, 0, 0, 0.2);
174
-
175
- }
176
-
177
- `;
178
- }
179
-
180
- static get properties() {
181
- return {
182
- ...super.properties,
183
- ident: {
184
- type: String
185
- },
186
- /**
187
- * ElementSpec mode. Can be ´add´, ´change´ or undefined.
188
- */
189
- mode: {
190
- type: String
191
- },
192
- /**
193
- * Array of ´odd-model´ Elements
194
- */
195
- models: {
196
- type: Array
197
- },
198
- /**
199
- * the odd file being edited
200
- */
201
- odd: {
202
- type: String,
203
- reflect: true
204
- },
205
- /**
206
- * array of ´element-spec´ Elements of given odd file
207
- */
208
- elementSpecs: {
209
- type: Array
210
- },
211
- source: {
212
- type: String
213
- },
214
- title: {
215
- type: String
216
- },
217
- titleShort: {
218
- type: String,
219
- reflect: true,
220
- attribute: 'title-short'
221
- },
222
- description: {
223
- type: String
224
- },
225
- namespace: {
226
- type: String
227
- },
228
- rootPath: {
229
- type: String,
230
- attribute: 'root-path'
231
- },
232
- loading: {
233
- type: Boolean
234
- },
235
- indentString: {
236
- type: String
237
- },
238
- outputPrefix: {
239
- type: String,
240
- attribute: 'output-prefix'
241
- },
242
- outputRoot: {
243
- type: String,
244
- attribute: 'output-root'
245
- },
246
- currentSelection: {
247
- type: Object
248
- },
249
- useNamespace: {
250
- type: Boolean
251
- },
252
- loggedIn: {
253
- type: Boolean
254
- },
255
- tabs: {
256
- type: Array
257
- },
258
- tabIndex: {
259
- type: Number,
260
- reflect: true
261
- }
262
- };
263
- }
264
-
265
- constructor() {
266
- super();
267
- this.ident = '';
268
- this.mode = '';
269
- this.models = () => [];
270
- this.odd = '';
271
- this.elementSpecs = [];
272
- this.source = '';
273
- this.title = '';
274
- this.titleShort = '';
275
- this.description = '';
276
- this.namespace = '';
277
- this.rootPath = '';
278
- this.loading = false;
279
- this.indentString = ' ';
280
- this.outputPrefix = '';
281
- this.outputRoot = '';
282
- this.currentSelection = {};
283
- this.useNamespace = false;
284
- this.loggedIn = true;
285
- this.tabs = [];
286
- this.tabIndex = undefined;
287
- this.selectedNavIndex = 0;
288
- this.cssFile = '';
289
- this.hotkeys = {
290
- save: 'ctrl+shift+s,command+shift+s'
291
- }
292
- this._hasChanges = false;
293
- }
294
-
295
- render() {
296
- return html`
297
- <iron-ajax id="loadContent"
298
- handle-as="json" content-type="application/x-www-form-urlencoded"
299
- with-credentials
300
- method="GET"></iron-ajax>
301
-
302
- <iron-ajax id="saveOdd"
303
- handle-as="json"
304
- with-credentials></iron-ajax>
305
-
306
- <div id="layout">
307
- <div id="drawer">
308
- <slot id="slot"></slot>
309
- <h3>
310
- <span>${this.odd}</span>
311
-
312
- <span class="icons">
313
- <pb-edit-xml id="editSource"><paper-icon-button icon="code" title="${translate('odd.editor.odd-source')}"></paper-icon-button></pb-edit-xml>
314
- <paper-icon-button @click="${() => this.save(true)}" icon="icons:cloud-download" title="${fsSupported ? translate('odd.editor.save-as'): translate('odd.editor.download')}"></paper-icon-button>
315
- <paper-icon-button @click="${this._reload}" icon="refresh" title="${translate('odd.editor.reload')}"></paper-icon-button>
316
- <paper-icon-button @click="${() => this.save(false)}" icon="save" title="${translate('odd.editor.save')} ${this.display('save')}"
317
- ?disabled="${!this.loggedIn}"></paper-icon-button>
318
- </span>
319
- </h3>
320
- <div id="new-element" class="input-group">
321
- <paper-input id="identNew" label="${translate('odd.editor.add-element')}" always-float-label="always-float-label">
322
- <paper-icon-button slot="suffix" @click="${this.addElementSpec}" icon="add" tabindex="-1"></paper-icon-button>
323
- </paper-input>
324
- </div>
325
-
326
- <div id="jump-to">
327
- <paper-autocomplete id="jumpTo" label="${translate('odd.editor.jump-to')}" always-float-label="always-float-label"></paper-autocomplete>
328
- </div>
329
-
330
- <h3>${translate('odd.editor.specs')}</h3>
331
- </div>
332
- <div id="navlist">
333
- ${repeat(this.elementSpecs, (i) => i.ident, (i, index) =>
334
- html`
335
- <paper-item id="es_${i.ident}"
336
- index="${index}"
337
- @click="${(ev) => this._openElementSpec(ev, index)}">${i.ident}</paper-item>
338
- `)}
339
- </div>
340
- <section class="specs" id="specs">
341
-
342
- <paper-card class="metadata">
343
- <pb-collapse id="meta">
344
- <h4 slot="collapse-trigger" class="panel-title">
345
- ${this._computedTitle()}
346
- </h4>
347
- <div slot="collapse-content">
348
- <paper-input id="title" name="title" value="${this.title}" label="${translate('odd.editor.title')}"
349
- placeholder="[${translate('odd.editor.title-placeholder')}]"
350
- @change="${this._inputTitle}"></paper-input>
351
- <paper-input id="titleShort" name="short-title" .value="${this.titleShort}" label="${translate('odd.editor.title-short')}"
352
- placeholder="[${translate('odd.editor.title-short-placeholder')}]"
353
- @change="${(e) => this.titleShort = e.composedPath()[0].value}"></paper-input>
354
- <paper-input id="description" name="description" .value="${ifDefined(this.description)}" label="${translate('odd.editor.description-label')}"
355
- placeholder="[${translate('odd.editor.description-placeholder')}]"
356
- @change="${(e) => this.description = e.composedPath()[0].value}"></paper-input>
357
- <paper-input id="source" name="source" ?value="${this.source}" label="${translate('odd.editor.source-label')}"
358
- placeholder="[${translate('odd.editor.source-placeholder')}]"
359
- @change="${(e) => this.source = e.composedPath()[0].value}"></paper-input>
360
- <paper-checkbox id="useNamespace" @change="${this.setUseNamespace}">${translate('odd.editor.use-namespace')}</paper-checkbox>
361
- <paper-input id="namespace" name="namespace" value="${this.namespace}" label="Namespace" ?disabled="${!this.useNamespace}"
362
- placeholder="[${translate('odd.editor.namespace-placeholder')}]"
363
- @change="${(e) => this.namespace = e.composedPath()[0].value}"></paper-input>
364
- <div class="extCssEdit">
365
- <paper-input name="cssFile" value="${this.cssFile}" label="External CSS File"
366
- placeholder="[External CSS file with additional class definitions]"
367
- @change="${this._cssFileChanged}"></paper-input>
368
- <pb-edit-xml id="editCSS"><paper-icon-button icon="create" title="${translate('odd.editor.css-source')}"></paper-icon-button></pb-edit-xml>
369
- </div>
370
- </div>
371
- </pb-collapse>
372
- </paper-card>
373
-
374
- <!-- todo: import elementspec to make it function -->
375
-
376
- <div class="editingView">
377
- <vaadin-tabs id="tabs" selected="${this.tabIndex}">
378
- ${repeat(this.tabs, (i) => i.id, (i, index) =>
379
- html`
380
- <vaadin-tab name="${i}" @click="${(e) => this._selectTab(e, i)}"><span style="padding-right:20px;">${i}</span><paper-icon-button icon="close" @click="${(ev) => this._closeTabHandler(ev, index)}"></paper-icon-button></vaadin-tab>
381
- `)}
382
- </vaadin-tabs>
383
-
384
- <div id="currentElement"></div>
385
- </div>
386
- </section>
387
-
37
+ static get styles() {
38
+ return css`
39
+ :host {
40
+ display: flex;
41
+ /*margin: 30px 20px;*/
42
+ margin: 0;
43
+ padding: 0;
44
+ height: auto;
45
+ }
46
+
47
+ #layout {
48
+ width: 100%;
49
+ display: grid;
50
+ grid-template-columns: auto 1fr;
51
+ grid-template-rows: auto 1fr;
52
+ }
53
+
54
+ #drawer {
55
+ grid-column: 1 / 1;
56
+ min-width: 320px;
57
+ }
58
+
59
+ #navlist {
60
+ grid-column: 1 / 1;
61
+ grid-row: 2 / 2;
62
+ overflow: auto;
63
+ height: 100%;
64
+ }
65
+
66
+ .specs {
67
+ grid-column: 2 / 2;
68
+ grid-row: 1 / span 2;
69
+ overflow: auto;
70
+ }
71
+
72
+ section {
73
+ padding: 20px;
74
+ }
75
+
76
+ h3,
77
+ h4 {
78
+ font-family: var(--pb-heading-font-family);
79
+ font-weight: var(--pb-heading-font-weight);
80
+ line-height: var(--pb-heading-line-height);
81
+ }
82
+
83
+ /* ported over but not checked yet */
84
+
85
+ .specs {
86
+ padding: 6px;
87
+ }
88
+
89
+ .metadata {
90
+ display: block;
91
+ }
92
+
93
+ .metadata div {
94
+ padding: 0 16px 16px;
95
+ }
96
+
97
+ .metadata paper-input {
98
+ margin-bottom: 10px;
99
+ }
100
+
101
+ .metadata .extCssEdit {
102
+ display: flex;
103
+ align-items: center;
104
+ padding: 0;
105
+ }
106
+ .metadata .extCssEdit paper-input {
107
+ flex: 2;
108
+ }
109
+ .metadata .extCssEdit pb-edit-xml {
110
+ width: 40px;
111
+ }
112
+
113
+ #jump-to {
114
+ margin-top: 1em;
115
+ }
116
+
117
+ odd-model {
118
+ border-bottom: 1px solid #e0e0e0;
119
+ }
120
+ odd-model h4 {
121
+ margin-top: 15px;
122
+ padding-top: 5px;
123
+ border-top: 1px solid #e0e0e0;
124
+ }
125
+ .renditions {
126
+ margin-top: 10px;
127
+ }
128
+ .icons {
129
+ display: inline-block;
130
+ white-space: nowrap;
131
+ }
132
+
133
+ details {
134
+ --details-transition-duration: 0.8s;
135
+ }
136
+ details[open] {
137
+ padding: 0;
138
+ }
139
+
140
+ pb-message#errorMsg {
141
+ background: var(--paper-red-500);
142
+ color: white;
143
+ }
144
+ .card-content {
145
+ height: 100%;
146
+ overflow: auto;
147
+ }
148
+
149
+ paper-tab {
150
+ width: 100px;
151
+ }
152
+
153
+ .editingView {
154
+ width: 100%;
155
+ }
156
+
157
+ vaadin-tabs {
158
+ margin-top: 10px;
159
+ }
160
+
161
+ vaadin-tab {
162
+ background: var(--paper-grey-200);
163
+ padding: 0 6px;
164
+ border: thin solid var(--paper-grey-300);
165
+ border-bottom: none;
166
+ }
167
+ vaadin-tab[selected] {
168
+ background: white;
169
+ border-top-right-radius: 20px;
170
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),
171
+ 0 3px 1px -2px rgba(0, 0, 0, 0.2);
172
+ }
173
+ `;
174
+ }
175
+
176
+ static get properties() {
177
+ return {
178
+ ...super.properties,
179
+ ident: {
180
+ type: String,
181
+ },
182
+ /**
183
+ * ElementSpec mode. Can be ´add´, ´change´ or undefined.
184
+ */
185
+ mode: {
186
+ type: String,
187
+ },
188
+ /**
189
+ * Array of ´odd-model´ Elements
190
+ */
191
+ models: {
192
+ type: Array,
193
+ },
194
+ /**
195
+ * the odd file being edited
196
+ */
197
+ odd: {
198
+ type: String,
199
+ reflect: true,
200
+ },
201
+ /**
202
+ * array of ´element-spec´ Elements of given odd file
203
+ */
204
+ elementSpecs: {
205
+ type: Array,
206
+ },
207
+ source: {
208
+ type: String,
209
+ },
210
+ title: {
211
+ type: String,
212
+ },
213
+ titleShort: {
214
+ type: String,
215
+ reflect: true,
216
+ attribute: 'title-short',
217
+ },
218
+ description: {
219
+ type: String,
220
+ },
221
+ namespace: {
222
+ type: String,
223
+ },
224
+ rootPath: {
225
+ type: String,
226
+ attribute: 'root-path',
227
+ },
228
+ loading: {
229
+ type: Boolean,
230
+ },
231
+ indentString: {
232
+ type: String,
233
+ },
234
+ outputPrefix: {
235
+ type: String,
236
+ attribute: 'output-prefix',
237
+ },
238
+ outputRoot: {
239
+ type: String,
240
+ attribute: 'output-root',
241
+ },
242
+ currentSelection: {
243
+ type: Object,
244
+ },
245
+ useNamespace: {
246
+ type: Boolean,
247
+ },
248
+ loggedIn: {
249
+ type: Boolean,
250
+ },
251
+ tabs: {
252
+ type: Array,
253
+ },
254
+ tabIndex: {
255
+ type: Number,
256
+ reflect: true,
257
+ },
258
+ };
259
+ }
260
+
261
+ constructor() {
262
+ super();
263
+ this.ident = '';
264
+ this.mode = '';
265
+ this.models = () => [];
266
+ this.odd = '';
267
+ this.elementSpecs = [];
268
+ this.source = '';
269
+ this.title = '';
270
+ this.titleShort = '';
271
+ this.description = '';
272
+ this.namespace = '';
273
+ this.rootPath = '';
274
+ this.loading = false;
275
+ this.indentString = ' ';
276
+ this.outputPrefix = '';
277
+ this.outputRoot = '';
278
+ this.currentSelection = {};
279
+ this.useNamespace = false;
280
+ this.loggedIn = true;
281
+ this.tabs = [];
282
+ this.tabIndex = undefined;
283
+ this.selectedNavIndex = 0;
284
+ this.cssFile = '';
285
+ this.hotkeys = {
286
+ save: 'ctrl+shift+s,command+shift+s',
287
+ };
288
+ this._hasChanges = false;
289
+ }
290
+
291
+ render() {
292
+ return html`
293
+ <iron-ajax
294
+ id="loadContent"
295
+ handle-as="json"
296
+ content-type="application/x-www-form-urlencoded"
297
+ with-credentials
298
+ method="GET"
299
+ ></iron-ajax>
300
+
301
+ <iron-ajax id="saveOdd" handle-as="json" with-credentials></iron-ajax>
302
+
303
+ <div id="layout">
304
+ <div id="drawer">
305
+ <slot id="slot"></slot>
306
+ <h3>
307
+ <span>${this.odd}</span>
308
+
309
+ <span class="icons">
310
+ <pb-edit-xml id="editSource"
311
+ ><paper-icon-button
312
+ icon="code"
313
+ title="${translate('odd.editor.odd-source')}"
314
+ ></paper-icon-button
315
+ ></pb-edit-xml>
316
+ <paper-icon-button
317
+ @click="${() => this.save(true)}"
318
+ icon="icons:cloud-download"
319
+ title="${fsSupported
320
+ ? translate('odd.editor.save-as')
321
+ : translate('odd.editor.download')}"
322
+ ></paper-icon-button>
323
+ <paper-icon-button
324
+ @click="${this._reload}"
325
+ icon="refresh"
326
+ title="${translate('odd.editor.reload')}"
327
+ ></paper-icon-button>
328
+ <paper-icon-button
329
+ @click="${() => this.save(false)}"
330
+ icon="save"
331
+ title="${translate('odd.editor.save')} ${this.display('save')}"
332
+ ?disabled="${!this.loggedIn}"
333
+ ></paper-icon-button>
334
+ </span>
335
+ </h3>
336
+ <div id="new-element" class="input-group">
337
+ <paper-input
338
+ id="identNew"
339
+ label="${translate('odd.editor.add-element')}"
340
+ always-float-label="always-float-label"
341
+ >
342
+ <paper-icon-button
343
+ slot="suffix"
344
+ @click="${this.addElementSpec}"
345
+ icon="add"
346
+ tabindex="-1"
347
+ ></paper-icon-button>
348
+ </paper-input>
349
+ </div>
350
+
351
+ <div id="jump-to">
352
+ <paper-autocomplete
353
+ id="jumpTo"
354
+ label="${translate('odd.editor.jump-to')}"
355
+ always-float-label="always-float-label"
356
+ ></paper-autocomplete>
357
+ </div>
358
+
359
+ <h3>${translate('odd.editor.specs')}</h3>
388
360
  </div>
389
-
390
-
391
- <pb-message id="dialog" hidden></pb-message>
392
- <pb-message id="errorMsg"></pb-message>
393
- `;
394
- }
395
-
396
- firstUpdated(changedProperties) {
397
- this.shadowRoot.getElementById('useNamespace').checked = this.useNamespace;
398
-
399
- // console.log('firstUpdated ', changedProperties);
400
- // console.log('firstUpdated endpoint', this.getEndpoint());
401
- // console.log('firstUpdated rootpath', this.rootPath);
402
- this.jumpCtrl = this.shadowRoot.getElementById('jumpTo');
403
- this.jumpCtrl.addEventListener('autocomplete-selected', this.jumpTo.bind(this));
404
-
405
- const oddSelector = this.querySelector('odd-selector');
406
-
407
- if (this.odd && oddSelector) {
408
- oddSelector.selected = this.odd;
409
-
410
- oddSelector.addEventListener('odd-selected', e => {
411
- if (confirm('Any unsaved changes will be lost. Continue?')) {
412
- this.odd = e.detail.odd;
413
- window.history.pushState({}, "", '?odd=' + this.odd)
414
- }
415
- oddSelector.selected = this.odd;
416
- })
361
+ <div id="navlist">
362
+ ${repeat(
363
+ this.elementSpecs,
364
+ i => i.ident,
365
+ (i, index) =>
366
+ html`
367
+ <paper-item
368
+ id="es_${i.ident}"
369
+ index="${index}"
370
+ @click="${ev => this._openElementSpec(ev, index)}"
371
+ >${i.ident}</paper-item
372
+ >
373
+ `,
374
+ )}
375
+ </div>
376
+ <section class="specs" id="specs">
377
+ <paper-card class="metadata">
378
+ <pb-collapse id="meta">
379
+ <h4 slot="collapse-trigger" class="panel-title">${this._computedTitle()}</h4>
380
+ <div slot="collapse-content">
381
+ <paper-input
382
+ id="title"
383
+ name="title"
384
+ value="${this.title}"
385
+ label="${translate('odd.editor.title')}"
386
+ placeholder="[${translate('odd.editor.title-placeholder')}]"
387
+ @change="${this._inputTitle}"
388
+ ></paper-input>
389
+ <paper-input
390
+ id="titleShort"
391
+ name="short-title"
392
+ .value="${this.titleShort}"
393
+ label="${translate('odd.editor.title-short')}"
394
+ placeholder="[${translate('odd.editor.title-short-placeholder')}]"
395
+ @change="${e => (this.titleShort = e.composedPath()[0].value)}"
396
+ ></paper-input>
397
+ <paper-input
398
+ id="description"
399
+ name="description"
400
+ .value="${ifDefined(this.description)}"
401
+ label="${translate('odd.editor.description-label')}"
402
+ placeholder="[${translate('odd.editor.description-placeholder')}]"
403
+ @change="${e => (this.description = e.composedPath()[0].value)}"
404
+ ></paper-input>
405
+ <paper-input
406
+ id="source"
407
+ name="source"
408
+ ?value="${this.source}"
409
+ label="${translate('odd.editor.source-label')}"
410
+ placeholder="[${translate('odd.editor.source-placeholder')}]"
411
+ @change="${e => (this.source = e.composedPath()[0].value)}"
412
+ ></paper-input>
413
+ <paper-checkbox id="useNamespace" @change="${this.setUseNamespace}"
414
+ >${translate('odd.editor.use-namespace')}</paper-checkbox
415
+ >
416
+ <paper-input
417
+ id="namespace"
418
+ name="namespace"
419
+ value="${this.namespace}"
420
+ label="Namespace"
421
+ ?disabled="${!this.useNamespace}"
422
+ placeholder="[${translate('odd.editor.namespace-placeholder')}]"
423
+ @change="${e => (this.namespace = e.composedPath()[0].value)}"
424
+ ></paper-input>
425
+ <div class="extCssEdit">
426
+ <paper-input
427
+ name="cssFile"
428
+ value="${this.cssFile}"
429
+ label="External CSS File"
430
+ placeholder="[External CSS file with additional class definitions]"
431
+ @change="${this._cssFileChanged}"
432
+ ></paper-input>
433
+ <pb-edit-xml id="editCSS"
434
+ ><paper-icon-button
435
+ icon="create"
436
+ title="${translate('odd.editor.css-source')}"
437
+ ></paper-icon-button
438
+ ></pb-edit-xml>
439
+ </div>
440
+ </div>
441
+ </pb-collapse>
442
+ </paper-card>
443
+
444
+ <!-- todo: import elementspec to make it function -->
445
+
446
+ <div class="editingView">
447
+ <vaadin-tabs id="tabs" selected="${this.tabIndex}">
448
+ ${repeat(
449
+ this.tabs,
450
+ i => i.id,
451
+ (i, index) =>
452
+ html`
453
+ <vaadin-tab name="${i}" @click="${e => this._selectTab(e, i)}"
454
+ ><span style="padding-right:20px;">${i}</span
455
+ ><paper-icon-button
456
+ icon="close"
457
+ @click="${ev => this._closeTabHandler(ev, index)}"
458
+ ></paper-icon-button
459
+ ></vaadin-tab>
460
+ `,
461
+ )}
462
+ </vaadin-tabs>
463
+
464
+ <div id="currentElement"></div>
465
+ </div>
466
+ </section>
467
+ </div>
468
+
469
+ <pb-message id="dialog" hidden></pb-message>
470
+ <pb-message id="errorMsg"></pb-message>
471
+ `;
472
+ }
473
+
474
+ firstUpdated(changedProperties) {
475
+ this.shadowRoot.getElementById('useNamespace').checked = this.useNamespace;
476
+
477
+ // console.log('firstUpdated ', changedProperties);
478
+ // console.log('firstUpdated endpoint', this.getEndpoint());
479
+ // console.log('firstUpdated rootpath', this.rootPath);
480
+ this.jumpCtrl = this.shadowRoot.getElementById('jumpTo');
481
+ this.jumpCtrl.addEventListener('autocomplete-selected', this.jumpTo.bind(this));
482
+
483
+ const oddSelector = this.querySelector('odd-selector');
484
+
485
+ if (this.odd && oddSelector) {
486
+ oddSelector.selected = this.odd;
487
+
488
+ oddSelector.addEventListener('odd-selected', e => {
489
+ if (confirm('Any unsaved changes will be lost. Continue?')) {
490
+ this.odd = e.detail.odd;
491
+ window.history.pushState({}, '', `?odd=${this.odd}`);
417
492
  }
418
-
419
- this.addEventListener('current-changed', this._changeSelection);
420
- this.addEventListener('odd-copy', e => this._copy(e));
421
- this.addEventListener('odd-paste', e => this._paste(e));
422
- this.addEventListener('element-spec-removed', this.removeElementSpec.bind(this));
423
-
424
- window.addEventListener('beforeunload', () => 'Any unsaved changes will be lost. Continue?');
425
-
426
- this.subscribeTo('pb-login', (ev) => {
427
- this.loggedIn = ev.detail.user != null;
428
- });
429
-
430
- this.focus();
431
-
432
- this.loadContent = this.shadowRoot.getElementById('loadContent');
433
-
434
- // it is unclear to me why root-path is not read from attribute without this explicit call
435
- this.rootPath = this.getAttribute('root-path');
436
-
437
- waitOnce('pb-page-ready', () => {
438
- this.load();
439
- this.inited = true;
440
- });
441
-
442
- this.registerHotkey('save', () => this.save(false));
493
+ oddSelector.selected = this.odd;
494
+ });
443
495
  }
444
496
 
445
- setUseNamespace() {
446
- this.useNamespace = this.shadowRoot.getElementById('useNamespace').checked;
447
- }
497
+ this.addEventListener('current-changed', this._changeSelection);
498
+ this.addEventListener('odd-copy', e => this._copy(e));
499
+ this.addEventListener('odd-paste', e => this._paste(e));
500
+ this.addEventListener('element-spec-removed', this.removeElementSpec.bind(this));
448
501
 
449
- async load() {
450
- if (this.loading) {
451
- return;
452
- }
453
- this.loading = true;
502
+ window.addEventListener('beforeunload', () => 'Any unsaved changes will be lost. Continue?');
454
503
 
455
- if (this.rootPath === '' || this.odd === '') {
456
- return;
457
- }
504
+ this.subscribeTo('pb-login', ev => {
505
+ this.loggedIn = ev.detail.user != null;
506
+ });
458
507
 
459
- // reset
460
- this.elementSpecs = [];
508
+ this.focus();
461
509
 
462
- document.dispatchEvent(new CustomEvent('pb-start-update'));
510
+ this.loadContent = this.shadowRoot.getElementById('loadContent');
463
511
 
512
+ // it is unclear to me why root-path is not read from attribute without this explicit call
513
+ this.rootPath = this.getAttribute('root-path');
464
514
 
465
- // this.$.editSource.setPath(this.rootPath + '/' + this.odd);
466
- const editSrc = this.shadowRoot.getElementById('editSource');
467
- editSrc.setPath(this.rootPath + '/' + this.odd);
468
- // this.shadowRoot.getElementById('editSource').setPath(this.rootPath + '/' + this.odd)
515
+ waitOnce('pb-page-ready', () => {
516
+ this.load();
517
+ this.inited = true;
518
+ });
469
519
 
470
- const params = { odd: this.odd, root: this.rootPath };
520
+ this.registerHotkey('save', () => this.save(false));
521
+ }
471
522
 
472
- // this.$.loadContent.params = params;
473
- this.loadContent.params = params;
474
- this.loadContent.url = `${this.getEndpoint()}/${this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : 'api/odd/' + this.odd}`;
475
- const request = this.loadContent.generateRequest();
523
+ setUseNamespace() {
524
+ this.useNamespace = this.shadowRoot.getElementById('useNamespace').checked;
525
+ }
476
526
 
477
- this._hasChanges = false;
478
- request.completes.then(r => this.handleOdd(r));
527
+ async load() {
528
+ if (this.loading) {
529
+ return;
479
530
  }
531
+ this.loading = true;
480
532
 
481
- handleOdd(req) {
482
- const data = req.response;
483
- this.loggedIn = data.canWrite;
484
- this.source = data.source;
485
- this.title = data.title;
486
- this.titleShort = data.titleShort;
487
- this.description = data.description;
488
- this.cssFile = data.cssFile == null ? '' : data.cssFile;
489
- this.namespace = data.namespace != null ? data.namespace : '';
490
- this.useNamespace = data.namespace != null;
491
-
492
- if (this.cssFile) {
493
- const editCss = this.shadowRoot.getElementById('editCSS');
494
- editCss.setPath(this.rootPath + '/' + this.cssFile);
495
- }
496
-
497
- // update elementSpecs
498
- this.elementSpecs = data.elementSpecs.map(es => this.mapElementSpec(es));
499
-
500
- // init auto-complete list
501
- // const jumpTo = this.shadowRoot.getElementById('jumpTo');
502
- // jumpTo.source = this.elementSpecs.map(this._specMapper);
503
- this._updateAutoComplete();
504
-
505
- this.requestUpdate();
506
-
507
- this.loading = false;
508
- document.dispatchEvent(new CustomEvent('pb-end-update'));
509
-
510
- document.title = this.titleShort || this.title;
533
+ if (this.rootPath === '' || this.odd === '') {
534
+ return;
511
535
  }
512
536
 
513
- _updateAutoComplete() {
514
- const jumpTo = this.shadowRoot.getElementById('jumpTo');
515
- jumpTo.source = this.elementSpecs.map(this._specMapper);
537
+ // reset
538
+ this.elementSpecs = [];
539
+
540
+ document.dispatchEvent(new CustomEvent('pb-start-update'));
541
+
542
+ // this.$.editSource.setPath(this.rootPath + '/' + this.odd);
543
+ const editSrc = this.shadowRoot.getElementById('editSource');
544
+ editSrc.setPath(`${this.rootPath}/${this.odd}`);
545
+ // this.shadowRoot.getElementById('editSource').setPath(this.rootPath + '/' + this.odd)
546
+
547
+ const params = { odd: this.odd, root: this.rootPath };
548
+
549
+ // this.$.loadContent.params = params;
550
+ this.loadContent.params = params;
551
+ this.loadContent.url = `${this.getEndpoint()}/${
552
+ this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : `api/odd/${this.odd}`
553
+ }`;
554
+ const request = this.loadContent.generateRequest();
555
+
556
+ this._hasChanges = false;
557
+ request.completes.then(r => this.handleOdd(r));
558
+ }
559
+
560
+ handleOdd(req) {
561
+ const data = req.response;
562
+ this.loggedIn = data.canWrite;
563
+ this.source = data.source;
564
+ this.title = data.title;
565
+ this.titleShort = data.titleShort;
566
+ this.description = data.description;
567
+ this.cssFile = data.cssFile == null ? '' : data.cssFile;
568
+ this.namespace = data.namespace != null ? data.namespace : '';
569
+ this.useNamespace = data.namespace != null;
570
+
571
+ if (this.cssFile) {
572
+ const editCss = this.shadowRoot.getElementById('editCSS');
573
+ editCss.setPath(`${this.rootPath}/${this.cssFile}`);
516
574
  }
517
575
 
518
- _cssFileChanged(e) {
519
- this.cssFile = e.composedPath()[0].value;
520
- if (this.cssFile) {
521
- const editCss = this.shadowRoot.getElementById('editCSS');
522
- editCss.setPath(this.rootPath + '/' + this.cssFile);
523
- }
524
- }
525
-
526
- /**
527
- * handler for paper-item in navigation list in the drawer
528
- *
529
- * @param e
530
- * @param index
531
- * @private
532
- */
533
- _navlistActiveChanged(e, index) {
534
- // set the paper-item active that got the click
535
- this.selectedNavIndex = index;
536
- this.requestUpdate();
537
- }
538
-
539
- _returnTabs() {
540
- return this.tabs;
541
- }
576
+ // update elementSpecs
577
+ this.elementSpecs = data.elementSpecs.map(es => this.mapElementSpec(es));
542
578
 
543
- _selectTab(e, item) {
544
- const spec = this.elementSpecs.find(theSpec => theSpec.ident === item);
545
- this._updateElementspec(spec);
546
- }
579
+ // init auto-complete list
580
+ // const jumpTo = this.shadowRoot.getElementById('jumpTo');
581
+ // jumpTo.source = this.elementSpecs.map(this._specMapper);
582
+ this._updateAutoComplete();
547
583
 
548
- _openElementSpec(ev, index) {
549
- console.log('_openElementSpec ', ev, index);
584
+ this.requestUpdate();
550
585
 
551
- const spec = this.elementSpecs[index]; //get target elementspec
552
- this._updateElementspec(spec);
586
+ this.loading = false;
587
+ document.dispatchEvent(new CustomEvent('pb-end-update'));
553
588
 
554
- const ident = spec.ident;
589
+ document.title = this.titleShort || this.title;
590
+ }
555
591
 
556
- // do not re-open existing tab, but select it
557
- if (this.tabs.indexOf(ident) >= 0) {
558
- this.tabIndex = this.tabs.indexOf(ident);
559
- this.requestUpdate();
560
- return;
561
- }
592
+ _updateAutoComplete() {
593
+ const jumpTo = this.shadowRoot.getElementById('jumpTo');
594
+ jumpTo.source = this.elementSpecs.map(this._specMapper);
595
+ }
562
596
 
563
- this.tabs.push(ident);
564
- this.tabIndex = this.tabs.length - 1;
565
- this.requestUpdate();
597
+ _cssFileChanged(e) {
598
+ this.cssFile = e.composedPath()[0].value;
599
+ if (this.cssFile) {
600
+ const editCss = this.shadowRoot.getElementById('editCSS');
601
+ editCss.setPath(`${this.rootPath}/${this.cssFile}`);
566
602
  }
567
-
568
- _updateElementspec(elementSpec) {
569
- // const spec = this.elementSpecs.find(theSpec => theSpec.ident === specIdent);
570
-
571
- // reset - delete current element if there's one
572
- const currentElement = this.shadowRoot.getElementById('currentElement');
573
- currentElement.innerHTML = "";
574
-
575
- // create new elementspec
576
- const newElementSpec = new PbOddElementspecEditor();
577
- newElementSpec.addEventListener('element-spec-changed', this.handleElementSpecChanged.bind(this));
578
- newElementSpec.ident = elementSpec.ident;
579
- newElementSpec.models = elementSpec.models;
580
- newElementSpec.mode = elementSpec.mode;
581
- newElementSpec.endpoint = this._endpoint;
582
- newElementSpec.apiVersion = this._apiVersion;
583
-
584
- newElementSpec.hotkeys = this.hotkeys;
585
- currentElement.appendChild(newElementSpec);
603
+ }
604
+
605
+ /**
606
+ * handler for paper-item in navigation list in the drawer
607
+ *
608
+ * @param e
609
+ * @param index
610
+ * @private
611
+ */
612
+ _navlistActiveChanged(e, index) {
613
+ // set the paper-item active that got the click
614
+ this.selectedNavIndex = index;
615
+ this.requestUpdate();
616
+ }
617
+
618
+ _returnTabs() {
619
+ return this.tabs;
620
+ }
621
+
622
+ _selectTab(e, item) {
623
+ const spec = this.elementSpecs.find(theSpec => theSpec.ident === item);
624
+ this._updateElementspec(spec);
625
+ }
626
+
627
+ _openElementSpec(ev, index) {
628
+ console.log('_openElementSpec ', ev, index);
629
+
630
+ const spec = this.elementSpecs[index]; // get target elementspec
631
+ this._updateElementspec(spec);
632
+
633
+ const { ident } = spec;
634
+
635
+ // do not re-open existing tab, but select it
636
+ if (this.tabs.indexOf(ident) >= 0) {
637
+ this.tabIndex = this.tabs.indexOf(ident);
638
+ this.requestUpdate();
639
+ return;
586
640
  }
587
641
 
588
- _closeTabHandler(ev, index) {
589
- console.log('_closeTabHandler ', index);
590
- ev.preventDefault();
591
- ev.stopPropagation();
592
-
593
- this._closeTab(index);
594
- return false;
642
+ this.tabs.push(ident);
643
+ this.tabIndex = this.tabs.length - 1;
644
+ this.requestUpdate();
645
+ }
646
+
647
+ _updateElementspec(elementSpec) {
648
+ // const spec = this.elementSpecs.find(theSpec => theSpec.ident === specIdent);
649
+
650
+ // reset - delete current element if there's one
651
+ const currentElement = this.shadowRoot.getElementById('currentElement');
652
+ currentElement.innerHTML = '';
653
+
654
+ // create new elementspec
655
+ const newElementSpec = new PbOddElementspecEditor();
656
+ newElementSpec.addEventListener(
657
+ 'element-spec-changed',
658
+ this.handleElementSpecChanged.bind(this),
659
+ );
660
+ newElementSpec.ident = elementSpec.ident;
661
+ newElementSpec.models = elementSpec.models;
662
+ newElementSpec.mode = elementSpec.mode;
663
+ newElementSpec.endpoint = this._endpoint;
664
+ newElementSpec.apiVersion = this._apiVersion;
665
+
666
+ newElementSpec.hotkeys = this.hotkeys;
667
+ currentElement.appendChild(newElementSpec);
668
+ }
669
+
670
+ _closeTabHandler(ev, index) {
671
+ console.log('_closeTabHandler ', index);
672
+ ev.preventDefault();
673
+ ev.stopPropagation();
674
+
675
+ this._closeTab(index);
676
+ return false;
677
+ }
678
+
679
+ _closeTab(index) {
680
+ this.tabs.splice(index, 1);
681
+ // last tab closed
682
+ if (this.tabs.length === 0) {
683
+ this.shadowRoot.getElementById('currentElement').innerHTML = '';
684
+ this.tabIndex = 0;
685
+ this.tabs = [];
595
686
  }
687
+ // a tab left of selected tab or current tab closed
688
+ else if (this.tabIndex > 0 && this.tabIndex >= index) {
689
+ // decrease tabIndex by one
690
+ this.tabIndex -= 1;
596
691
 
597
- _closeTab(index) {
598
- this.tabs.splice(index, 1);
599
- // last tab closed
600
- if (this.tabs.length === 0) {
601
- this.shadowRoot.getElementById('currentElement').innerHTML = '';
602
- this.tabIndex = 0;
603
- this.tabs = [];
604
- }
605
- // a tab left of selected tab or current tab closed
606
- else if (this.tabIndex > 0 && this.tabIndex >= index) {
607
- // decrease tabIndex by one
608
- this.tabIndex -= 1;
609
-
610
- const currentTab = this.tabs[this.tabIndex];
611
- this._selectTab(null, currentTab);
612
- }
692
+ const currentTab = this.tabs[this.tabIndex];
693
+ this._selectTab(null, currentTab);
613
694
  }
614
-
615
- attributeChangedCallback(name, oldVal, newVal) {
616
- // console.log('attributeChangedCallback', name, oldVal, newVal);
617
-
618
- super.attributeChangedCallback(name, oldVal, newVal);
619
- if (name == 'odd' && oldVal !== newVal) {
620
- // console.log('<pb-document> Emit update event');
621
- // this.emitTo('pb-odd-editor', this);
622
- if (this.inited) {
623
- this.load();
624
- }
625
- }
695
+ }
696
+
697
+ attributeChangedCallback(name, oldVal, newVal) {
698
+ // console.log('attributeChangedCallback', name, oldVal, newVal);
699
+
700
+ super.attributeChangedCallback(name, oldVal, newVal);
701
+ if (name == 'odd' && oldVal !== newVal) {
702
+ // console.log('<pb-document> Emit update event');
703
+ // this.emitTo('pb-odd-editor', this);
704
+ if (this.inited) {
705
+ this.load();
706
+ }
626
707
  }
627
-
628
- static get replaceCharMap() {
629
- return {
630
- '"': '&quot;',
631
- '&': '&amp;',
632
- '<': '&lt;',
633
- '>': '&gt;'
634
- }
708
+ }
709
+
710
+ static get replaceCharMap() {
711
+ return {
712
+ '"': '&quot;',
713
+ '&': '&amp;',
714
+ '<': '&lt;',
715
+ '>': '&gt;',
635
716
  };
636
-
637
- static get replaceCharRegexp() {
638
- return /"|&|<|>/g
639
- }
640
-
641
- static replaceChars(match) {
642
- return PbOddEditor.replaceCharMap[match];
717
+ }
718
+
719
+ static get replaceCharRegexp() {
720
+ return /"|&|<|>/g;
721
+ }
722
+
723
+ static replaceChars(match) {
724
+ return PbOddEditor.replaceCharMap[match];
725
+ }
726
+
727
+ jumpTo(e) {
728
+ const jumpCtrl = this.shadowRoot.getElementById('jumpTo');
729
+ const id = `#es_${jumpCtrl.text}`;
730
+ const target = this.shadowRoot.querySelector(id);
731
+ if (!target) {
732
+ return;
643
733
  }
644
734
 
645
- jumpTo(e) {
646
- const jumpCtrl = this.shadowRoot.getElementById('jumpTo');
647
- const id = '#es_' + jumpCtrl.text;
648
- const target = this.shadowRoot.querySelector(id);
649
- if (!target) {
650
- return
651
- }
735
+ this.jumpCtrl.clear();
736
+ target.click();
737
+ }
652
738
 
653
- this.jumpCtrl.clear();
654
- target.click();
739
+ _computedTitle() {
740
+ if (!this.odd) {
741
+ return '';
655
742
  }
656
-
657
- _computedTitle() {
658
- if (!this.odd) {
659
- return ''
660
- }
661
- return this.title || this.titleShort || this.odd || 'Loading ...'
743
+ return this.title || this.titleShort || this.odd || 'Loading ...';
744
+ }
745
+
746
+ _copy(e) {
747
+ // console.log('odd-editor._copy ', e);
748
+ this.clipboard = e.detail.model;
749
+ const clone = JSON.parse(JSON.stringify(e.detail.model));
750
+ this.clipboard = clone;
751
+ }
752
+
753
+ _paste(e) {
754
+ console.log('_paste ', e);
755
+ console.log('_paste clipboard', this.clipboard);
756
+
757
+ if (this.clipboard == {} || this.clipboard == undefined) {
758
+ return;
662
759
  }
760
+ const targetElement = e.detail.target;
761
+ targetElement.addModel(this.clipboard);
762
+ targetElement.render();
763
+ }
764
+
765
+ _specMapper(spec) {
766
+ return {
767
+ text: spec.ident,
768
+ value: spec.ident,
769
+ };
770
+ }
663
771
 
664
- _copy(e) {
665
- // console.log('odd-editor._copy ', e);
666
- this.clipboard = e.detail.model;
667
- const clone = JSON.parse(JSON.stringify(e.detail.model));
668
- this.clipboard = clone;
669
- }
772
+ _specObserver(changeRecord) {
773
+ const source = this.elementSpecs.map(this._specMapper);
774
+ this.jumpCtrl.source = source;
775
+ }
670
776
 
671
- _paste(e) {
672
- console.log('_paste ', e);
673
- console.log('_paste clipboard', this.clipboard);
777
+ mapElementSpec(elementSpec) {
778
+ return {
779
+ ...elementSpec,
780
+ models: elementSpec.models.map(m => this.addShowToModel(m)),
781
+ };
782
+ }
674
783
 
675
- if (this.clipboard == {} || this.clipboard == undefined) {
676
- return;
677
- }
678
- const targetElement = e.detail.target;
679
- targetElement.addModel(this.clipboard);
680
- targetElement.render();
784
+ addShowToModel(model) {
785
+ if (model.models) {
786
+ const extendedModels = model.models.map(m => this.addShowToModel(m));
787
+ return { ...model, models: extendedModels, show: false };
681
788
  }
789
+ return { ...model, show: false };
790
+ }
682
791
 
683
- _specMapper(spec) {
684
- return {
685
- text: spec.ident,
686
- value: spec.ident
687
- };
688
- }
792
+ addElementSpec(ev) {
793
+ // const ident = this.$.identNew.value;
794
+ const identNew = this.shadowRoot.getElementById('identNew');
689
795
 
690
- _specObserver(changeRecord) {
691
- const source = this.elementSpecs.map(this._specMapper);
692
- this.jumpCtrl.source = source;
796
+ const ident = identNew.value;
797
+ if (!ident || ident.length === 0) {
798
+ return;
693
799
  }
694
-
695
- mapElementSpec(elementSpec) {
696
- return Object.assign(
697
- {},
698
- elementSpec,
699
- { models: elementSpec.models.map(m => this.addShowToModel(m)) }
700
- );
800
+ const existingSpec = this.elementSpecs.find(spec => spec.ident === ident);
801
+ if (existingSpec) {
802
+ console.log('<pb-odd-editor> element spec to be added already exists: %s', ident);
803
+ const id = `#es_${ident}`;
804
+ const target = this.shadowRoot.querySelector(id);
805
+ if (!target) {
806
+ return;
807
+ }
808
+ target.click();
809
+ return;
701
810
  }
702
811
 
703
- addShowToModel(model) {
704
- if (model.models) {
705
- const extendedModels = model.models.map(m => this.addShowToModel(m));
706
- return Object.assign({}, model, { models: extendedModels, show: false });
707
- }
708
- return Object.assign({}, model, { show: false });
709
- }
710
-
711
- addElementSpec(ev) {
712
- // const ident = this.$.identNew.value;
713
- const identNew = this.shadowRoot.getElementById('identNew');
714
-
715
- const ident = identNew.value;
716
- if (!ident || ident.length === 0) {
717
- return;
718
- }
719
- const existingSpec = this.elementSpecs.find((spec) => spec.ident === ident);
720
- if (existingSpec) {
721
- console.log('<pb-odd-editor> element spec to be added already exists: %s', ident);
722
- const id = `#es_${ident}`;
723
- const target = this.shadowRoot.querySelector(id);
724
- if (!target) {
725
- return
726
- }
727
- target.click();
728
- return;
729
- }
730
-
731
- const oldApiParams = {
732
- action: "find",
733
- odd: this.odd,
734
- root: this.rootPath,
735
- ident
736
- };
737
- const newApiParams = {
738
- root: this.rootPath,
739
- ident
740
- };
741
-
742
- const params = this.lessThanApiVersion('1.0.0') ? oldApiParams : newApiParams;
743
-
744
- this.loadContent.params = params;
745
- this.loadContent.url = `${this.getEndpoint()}/${this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : 'api/odd/' + this.odd}`;
746
- let request = this.loadContent.generateRequest();
747
- request.completes.then(this._handleElementSpecResponse.bind(this));
748
- }
749
-
750
-
751
- _handleElementSpecResponse(req) {
752
- const identNew = this.shadowRoot.getElementById('identNew');
753
-
754
- const data = req.response;
755
- const ident = identNew.value
756
- const mode = (data.status === 'not-found' ? 'add' : 'change');
757
- const models = data.models || [];
758
- const newSpec = {
759
- ident,
760
- mode,
761
- models
762
- };
763
-
764
- this.elementSpecs.unshift(newSpec);
765
- // trigger update of autocomplete list in jumpTo
766
- identNew.value = '';
767
-
768
- //open new tab with newly created element
769
- this.tabs.push(ident);
770
- this.tabIndex = this.tabs.length - 1;
771
-
772
- this.elementSpecs.sort((a, b) => a.ident.localeCompare(b.ident));
773
-
774
- this.requestUpdate().then(() => {
775
- const elem = this.shadowRoot.querySelectorAll('paper-item');
776
- const idx = this.elementSpecs.indexOf(newSpec);
812
+ const oldApiParams = {
813
+ action: 'find',
814
+ odd: this.odd,
815
+ root: this.rootPath,
816
+ ident,
817
+ };
818
+ const newApiParams = {
819
+ root: this.rootPath,
820
+ ident,
821
+ };
777
822
 
778
- this._updateAutoComplete();
823
+ const params = this.lessThanApiVersion('1.0.0') ? oldApiParams : newApiParams;
824
+
825
+ this.loadContent.params = params;
826
+ this.loadContent.url = `${this.getEndpoint()}/${
827
+ this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : `api/odd/${this.odd}`
828
+ }`;
829
+ const request = this.loadContent.generateRequest();
830
+ request.completes.then(this._handleElementSpecResponse.bind(this));
831
+ }
832
+
833
+ _handleElementSpecResponse(req) {
834
+ const identNew = this.shadowRoot.getElementById('identNew');
835
+
836
+ const data = req.response;
837
+ const ident = identNew.value;
838
+ const mode = data.status === 'not-found' ? 'add' : 'change';
839
+ const models = data.models || [];
840
+ const newSpec = {
841
+ ident,
842
+ mode,
843
+ models,
844
+ };
779
845
 
780
- elem[idx].click();
781
- elem[idx].focus();
782
- });
846
+ this.elementSpecs.unshift(newSpec);
847
+ // trigger update of autocomplete list in jumpTo
848
+ identNew.value = '';
849
+
850
+ // open new tab with newly created element
851
+ this.tabs.push(ident);
852
+ this.tabIndex = this.tabs.length - 1;
853
+
854
+ this.elementSpecs.sort((a, b) => a.ident.localeCompare(b.ident));
855
+
856
+ this.requestUpdate().then(() => {
857
+ const elem = this.shadowRoot.querySelectorAll('paper-item');
858
+ const idx = this.elementSpecs.indexOf(newSpec);
859
+
860
+ this._updateAutoComplete();
861
+
862
+ elem[idx].click();
863
+ elem[idx].focus();
864
+ });
865
+ }
866
+
867
+ removeElementSpec(ev) {
868
+ const { ident } = ev.detail.target;
869
+ this.shadowRoot
870
+ .getElementById('dialog')
871
+ .confirm(i18n('browse.delete'), i18n('odd.editor.delete-spec', { ident }))
872
+ .then(
873
+ () => {
874
+ const targetIndex = this.elementSpecs.findIndex(theSpec => theSpec.ident === ident);
875
+ this.elementSpecs.splice(targetIndex, 1);
876
+ this.requestUpdate();
877
+
878
+ const selectedTab = this.shadowRoot.querySelector('vaadin-tab[selected]');
879
+ const tabName = selectedTab.getAttribute('name');
880
+ const idx = this.tabs.indexOf(tabName);
881
+ this._closeTab(idx);
882
+ },
883
+ () => null,
884
+ );
885
+ }
886
+
887
+ serializeOdd() {
888
+ const ns = this.useNamespace ? ` ns="${this.namespace}"` : '';
889
+ const source = this.source ? ` source="${this.source}"` : '';
890
+ const description = this.description ? ` <desc>${this.description}</desc>` : '';
891
+ const title = `${this.indentString}<title>${this.title}${description}</title>\n`;
892
+ const titleShort = this.titleShort
893
+ ? `${this.indentString}<title type="short">${this.titleShort}</title>\n`
894
+ : '';
895
+ const cssFile = this.cssFile
896
+ ? `${this.indentString}<rendition source="${this.cssFile}"/>\n`
897
+ : '';
898
+ const elementSpecs = this.elementSpecs
899
+ .map(e => this.serializeElementSpec(this.indentString, e))
900
+ .join('');
901
+
902
+ return `<schemaSpec xmlns="http://www.tei-c.org/ns/1.0" xmlns:pb="http://teipublisher.com/1.0"${ns}${source}>\n${title}${titleShort}${cssFile}\n${elementSpecs}</schemaSpec>\n`;
903
+ }
904
+
905
+ serializeElementSpec(indent, elementSpec) {
906
+ const mode = elementSpec.mode ? ` mode="${elementSpec.mode}"` : '';
907
+ const indent2 = indent + this.indentString;
908
+ const models = elementSpec.models.map(m => this.serializeModel(indent2, m)).join('');
909
+
910
+ return `${indent}<elementSpec ident="${elementSpec.ident}"${mode}>\n${models}${indent}</elementSpec>\n`;
911
+ }
912
+
913
+ serializeModel(indent, model) {
914
+ if (model.type === 'model' && !model.behaviour) {
915
+ return '';
783
916
  }
784
917
 
785
- removeElementSpec(ev) {
786
- const ident = ev.detail.target.ident;
787
- this.shadowRoot.getElementById('dialog')
788
- .confirm(i18n('browse.delete'), i18n('odd.editor.delete-spec', { ident }))
789
- .then(() => {
790
- const targetIndex = this.elementSpecs.findIndex(theSpec => theSpec.ident === ident);
791
- this.elementSpecs.splice(targetIndex, 1);
792
- this.requestUpdate();
793
-
794
-
795
- const selectedTab = this.shadowRoot.querySelector('vaadin-tab[selected]');
796
- const tabName = selectedTab.getAttribute('name');
797
- const idx = this.tabs.indexOf(tabName);
798
- this._closeTab(idx);
799
- }, () => null);
918
+ const nestedIndent = indent + this.indentString;
919
+
920
+ const attributes = [
921
+ this.serializeAttribute('output', model.output),
922
+ this.serializeAttribute('predicate', model.predicate),
923
+ model.type === 'model' ? this.serializeAttribute('behaviour', model.behaviour) : '',
924
+ this.serializeAttribute('cssClass', model.css),
925
+ this.serializeAttribute('useSourceRendition', model.sourcerend),
926
+ this.serializeAttribute('pb:mode', model.mode),
927
+ ].join('');
928
+
929
+ const desc = model.desc ? `${nestedIndent}<desc>${model.desc}</desc>\n` : '';
930
+
931
+ // innerXML += this.serializeTag('model', nestedIndent);
932
+ const models = model.models.map(m => this.serializeModel(nestedIndent, m)).join('');
933
+ const parameters = model.parameters.map(p => this.serializeParameter(nestedIndent, p)).join('');
934
+ const renditions = model.renditions.map(r => this.serializeRendition(nestedIndent, r)).join('');
935
+ const template = PbOddEditor.serializeTemplate(nestedIndent, model.template);
936
+ const innerXML = `${desc}${models}${parameters}${template}${renditions}`;
937
+ const end = innerXML.length > 0 ? `>\n${innerXML}${indent}</${model.type}` : '/';
938
+
939
+ return `${indent}<${model.type}${attributes}${end}>\n`;
940
+ }
941
+
942
+ serializeParameter(indent, parameter) {
943
+ if (!parameter.name) {
944
+ return '';
800
945
  }
801
-
802
- serializeOdd() {
803
- const ns = this.useNamespace ? ` ns="${this.namespace}"` : '';
804
- const source = this.source ? ` source="${this.source}"` : '';
805
- const description = this.description ? ` <desc>${this.description}</desc>` : '';
806
- const title = `${this.indentString}<title>${this.title}${description}</title>\n`;
807
- const titleShort = this.titleShort ? `${this.indentString}<title type="short">${this.titleShort}</title>\n` : '';
808
- const cssFile = this.cssFile ? `${this.indentString}<rendition source="${this.cssFile}"/>\n` : '';
809
- const elementSpecs = this.elementSpecs
810
- .map(e => this.serializeElementSpec(this.indentString, e)).join('');
811
-
812
- return `<schemaSpec xmlns="http://www.tei-c.org/ns/1.0" xmlns:pb="http://teipublisher.com/1.0"${ns}${source}>\n${title}${titleShort}${cssFile}\n${elementSpecs}</schemaSpec>\n`
946
+ const name = this.serializeAttribute('name', parameter.name);
947
+ const value = this.serializeAttribute('value', parameter.value);
948
+ if (parameter.set) {
949
+ return `${indent}<pb:set-param xmlns=""${name}${value}/>\n`;
813
950
  }
814
-
815
- serializeElementSpec(indent, elementSpec) {
816
- const mode = elementSpec.mode ? ` mode="${elementSpec.mode}"` : '';
817
- const indent2 = indent + this.indentString
818
- const models = elementSpec.models
819
- .map(m => this.serializeModel(indent2, m))
820
- .join('')
821
-
822
- return `${indent}<elementSpec ident="${elementSpec.ident}"${mode}>\n${models}${indent}</elementSpec>\n`;
951
+ return `${indent}<param${name}${value}/>\n`;
952
+ }
953
+
954
+ serializeRendition(indent, rendition) {
955
+ const scope =
956
+ rendition.scope && rendition.scope !== 'null'
957
+ ? this.serializeAttribute('scope', rendition.scope)
958
+ : '';
959
+ const css = PbOddEditor.escape(rendition.css);
960
+ return `${indent}<outputRendition xml:space="preserve" ${scope}>\n${indent}${css}\n${indent}</outputRendition>\n`;
961
+ }
962
+
963
+ static serializeTemplate(indent, template) {
964
+ if (!template) {
965
+ return '';
823
966
  }
967
+ return `${indent}<pb:template xml:space="preserve" xmlns="">${template}</pb:template>\n`;
968
+ }
824
969
 
825
- serializeModel(indent, model) {
826
- if (model.type === 'model' && !model.behaviour) {
827
- return '';
828
- }
829
-
830
- const nestedIndent = indent + this.indentString;
831
-
832
- const attributes = [
833
- this.serializeAttribute('output', model.output),
834
- this.serializeAttribute('predicate', model.predicate),
835
- model.type === 'model' ? this.serializeAttribute('behaviour', model.behaviour) : '',
836
- this.serializeAttribute('cssClass', model.css),
837
- this.serializeAttribute('useSourceRendition', model.sourcerend),
838
- this.serializeAttribute('pb:mode', model.mode)
839
- ].join('');
840
-
841
- const desc = model.desc ? nestedIndent + '<desc>' + model.desc + '</desc>\n' : '';
842
-
843
- // innerXML += this.serializeTag('model', nestedIndent);
844
- const models = model.models.map(m => this.serializeModel(nestedIndent, m)).join('');
845
- const parameters = model.parameters.map(p => this.serializeParameter(nestedIndent, p)).join('');
846
- const renditions = model.renditions.map(r => this.serializeRendition(nestedIndent, r)).join('');
847
- const template = PbOddEditor.serializeTemplate(nestedIndent, model.template);
848
- const innerXML = `${desc}${models}${parameters}${template}${renditions}`;
849
- const end = (innerXML.length > 0) ? `>\n${innerXML}${indent}</${model.type}` : '/';
970
+ serializeAttribute(name, value) {
971
+ return value ? ` ${name}="${PbOddEditor.escape(value)}"` : '';
972
+ }
850
973
 
851
- return `${indent}<${model.type}${attributes}${end}>\n`
974
+ static escape(code) {
975
+ if (!code) {
976
+ return '';
852
977
  }
853
-
854
- serializeParameter(indent, parameter) {
855
- if (!parameter.name) {
856
- return '';
857
- }
858
- const name = this.serializeAttribute('name', parameter.name);
859
- const value = this.serializeAttribute('value', parameter.value);
860
- if (parameter.set) {
861
- return `${indent}<pb:set-param xmlns=""${name}${value}/>\n`
862
- }
863
- return `${indent}<param${name}${value}/>\n`
978
+ if (typeof code === 'string') {
979
+ return code.replace(PbOddEditor.replaceCharRegexp, PbOddEditor.replaceChars);
864
980
  }
865
-
866
- serializeRendition(indent, rendition) {
867
- const scope = rendition.scope && rendition.scope !== 'null' ? this.serializeAttribute('scope', rendition.scope) : '';
868
- const css = PbOddEditor.escape(rendition.css);
869
- return `${indent}<outputRendition xml:space="preserve" ${scope}>\n${indent}${css}\n${indent}</outputRendition>\n`;
981
+ return code;
982
+ }
983
+
984
+ save(download = false) {
985
+ document.dispatchEvent(new CustomEvent('pb-start-update'));
986
+ const data = this.serializeOdd();
987
+
988
+ this.shadowRoot
989
+ .getElementById('dialog')
990
+ .show(i18n('odd.editor.save'), i18n('odd.editor.saving'));
991
+
992
+ const saveOdd = this.shadowRoot.getElementById('saveOdd');
993
+ saveOdd.url = `${this.getEndpoint()}/${
994
+ this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : `api/odd/${this.odd}`
995
+ }`;
996
+ if (this.lessThanApiVersion('1.0.0')) {
997
+ saveOdd.contentType = 'application/x-www-form-urlencoded';
998
+ saveOdd.method = 'POST';
999
+ saveOdd.params = null;
1000
+ saveOdd.body = {
1001
+ action: 'save',
1002
+ root: this.rootPath,
1003
+ 'output-prefix': this.outputPrefix,
1004
+ 'output-root': this.outputRoot,
1005
+ odd: this.odd,
1006
+ data,
1007
+ };
1008
+ } else {
1009
+ saveOdd.contentType = 'application/xml';
1010
+ saveOdd.method = 'PUT';
1011
+ saveOdd.params = {
1012
+ root: this.rootPath,
1013
+ 'output-prefix': this.outputPrefix,
1014
+ 'output-root': this.outputRoot,
1015
+ };
1016
+ saveOdd.body = data;
870
1017
  }
871
1018
 
872
- static serializeTemplate(indent, template) {
873
- if (!template) {
874
- return '';
875
- }
876
- return `${indent}<pb:template xml:space="preserve" xmlns="">${template}</pb:template>\n`;
877
- }
878
-
879
- serializeAttribute(name, value) {
880
- return value ? ` ${name}="${PbOddEditor.escape(value)}"` : ''
881
- }
882
-
883
- static escape(code) {
884
- if (!code) {
885
- return '';
886
- }
887
- if (typeof code === 'string') {
888
- return code.replace(PbOddEditor.replaceCharRegexp, PbOddEditor.replaceChars);
889
- }
890
- return code;
891
- }
892
-
893
- save(download=false) {
894
- document.dispatchEvent(new CustomEvent('pb-start-update'));
895
- const data = this.serializeOdd();
896
-
897
- this.shadowRoot.getElementById('dialog').show(i18n("odd.editor.save"), i18n('odd.editor.saving'));
898
-
899
- const saveOdd = this.shadowRoot.getElementById('saveOdd');
900
- saveOdd.url = `${this.getEndpoint()}/${this.lessThanApiVersion('1.0.0') ? 'modules/editor.xql' : 'api/odd/' + this.odd}`;
901
- if (this.lessThanApiVersion('1.0.0')) {
902
- saveOdd.contentType = 'application/x-www-form-urlencoded';
903
- saveOdd.method = "POST";
904
- saveOdd.params = null;
905
- saveOdd.body = {
906
- action: "save",
907
- root: this.rootPath,
908
- "output-prefix": this.outputPrefix,
909
- "output-root": this.outputRoot,
910
- odd: this.odd,
911
- data
912
- };
913
- } else {
914
- saveOdd.contentType = 'application/xml';
915
- saveOdd.method = "PUT";
916
- saveOdd.params = {
917
- root: this.rootPath,
918
- "output-prefix": this.outputPrefix,
919
- "output-root": this.outputRoot,};
920
- saveOdd.body = data;
921
- }
922
-
923
- const request = saveOdd.generateRequest();
924
- request.completes
925
- .then((req) => {
926
- this.handleSaveComplete(req, download);
927
- })
928
- .catch(this.handleSaveError.bind(this));
929
- }
930
-
931
- //to be deprecated: only used for old api
932
- static _renderReport(report) {
933
- if (report.error) {
934
- return `
1019
+ const request = saveOdd.generateRequest();
1020
+ request.completes
1021
+ .then(req => {
1022
+ this.handleSaveComplete(req, download);
1023
+ })
1024
+ .catch(this.handleSaveError.bind(this));
1025
+ }
1026
+
1027
+ // to be deprecated: only used for old api
1028
+ static _renderReport(report) {
1029
+ if (report.error) {
1030
+ return `
935
1031
  <div class="list-group-item-danger">
936
1032
  <h4 class="list-group-item-heading">${report.file}</h4>
937
1033
  <h5 class="list-group-item-heading">Compilation error on line ${report.line}:</h5>
@@ -939,138 +1035,140 @@ export class PbOddEditor extends pbHotkeys(pbMixin(LitElement)) {
939
1035
  <pre class="list-group-item-text">${report.message}</pre>
940
1036
  </div>
941
1037
  `;
942
- }
943
- return `
1038
+ }
1039
+ return `
944
1040
  <div class="list-group-item-success">
945
1041
  <p class="list-group-item-text">Generated ${report.file}</p>
946
1042
  </div>
947
1043
  `;
1044
+ }
1045
+
1046
+ handleSaveComplete(req, download = false) {
1047
+ const data = req.response;
1048
+ if (data.status === 'denied') {
1049
+ this.shadowRoot
1050
+ .getElementById('dialog')
1051
+ .set(i18n('odd.editor.denied'), i18n('odd.editor.denied-message', { odd: this.odd }));
1052
+ document.dispatchEvent(new CustomEvent('pb-end-update'));
1053
+ return;
948
1054
  }
949
1055
 
950
- handleSaveComplete(req, download=false) {
951
- const data = req.response;
952
- if (data.status === 'denied') {
953
- this.shadowRoot.getElementById('dialog').set(i18n("odd.editor.denied"), i18n("odd.editor.denied-message", { odd: this.odd }));
954
- document.dispatchEvent(new CustomEvent('pb-end-update'));
955
- return;
956
- }
957
-
958
- let msg;
959
-
960
- if (this.lessThanApiVersion('1.0.0')) {
961
- const report = data.report.map(PbOddEditor._renderReport);
962
- msg = `<div class="list-group">${report.join('')}</div>`;
963
- } else {
964
- const report = data.report;
965
- msg = `<div class="list-group">${report}</div>`;
966
- }
1056
+ let msg;
967
1057
 
968
- this.shadowRoot.getElementById('dialog').set(i18n("odd.editor.saved"), msg);
969
-
970
- this._hasChanges = false;
971
- document.dispatchEvent(new CustomEvent('pb-end-update'));
972
-
973
- if (download) {
974
- const blob = new Blob([data.source], { type: 'application/xml'});
975
- fileSave(blob, {
976
- fileName: this.odd,
977
- extensions: ['.odd'],
978
- })
979
- .then(
980
- () => console.log(`<pb-odd-editor> ${this.odd} exported`),
981
- () => console.log('<pb-odd-editor> export aborted')
982
- );
983
- }
1058
+ if (this.lessThanApiVersion('1.0.0')) {
1059
+ const report = data.report.map(PbOddEditor._renderReport);
1060
+ msg = `<div class="list-group">${report.join('')}</div>`;
1061
+ } else {
1062
+ const { report } = data;
1063
+ msg = `<div class="list-group">${report}</div>`;
984
1064
  }
985
1065
 
986
- handleSaveError(rejected) {
987
- this.shadowRoot.getElementById('dialog').set("Error", rejected.error);
988
- // this.$.dialog.set("Error", rejected.error);
989
- document.dispatchEvent(new CustomEvent('pb-end-update'));
990
- }
1066
+ this.shadowRoot.getElementById('dialog').set(i18n('odd.editor.saved'), msg);
991
1067
 
992
- _reload() {
993
- this.shadowRoot.getElementById('dialog')
994
- .confirm(i18n('odd.editor.reload'), i18n('odd.editor.reload-confirm'))
995
- .then(() => {
996
- this.load();
997
- this.tabs = [];
998
- this.tabIndex = 0;
999
- this.shadowRoot.getElementById('currentElement').innerHTML = '';
1000
- }, () => null);
1001
- }
1068
+ this._hasChanges = false;
1069
+ document.dispatchEvent(new CustomEvent('pb-end-update'));
1002
1070
 
1003
- _setCurrentSelection(e) {
1004
- if (this.currentSelection != undefined) {
1005
- this.currentSelection.removeAttribute('currentselection');
1006
- }
1007
- this.currentSelection = e.target;
1008
- this.currentSelection.setAttribute('currentselection', 'true');
1071
+ if (download) {
1072
+ const blob = new Blob([data.source], { type: 'application/xml' });
1073
+ fileSave(blob, {
1074
+ fileName: this.odd,
1075
+ extensions: ['.odd'],
1076
+ }).then(
1077
+ () => console.log(`<pb-odd-editor> ${this.odd} exported`),
1078
+ () => console.log('<pb-odd-editor> export aborted'),
1079
+ );
1009
1080
  }
1010
-
1011
-
1012
- _changeSelection(ev) {
1013
- ev.preventDefault();
1014
- ev.stopPropagation();
1015
-
1016
- if (ev.detail.target === this) return;
1017
-
1018
- if (this.currentSelection &&
1019
- this.currentSelection.tagName !== undefined) {
1020
- this.currentSelection.removeAttribute('currentselection');
1021
- }
1022
-
1023
- let newSelection;
1024
- if (ev.detail.target) {
1025
- newSelection = ev.detail.target;
1026
- } else {
1027
- newSelection = ev.target;
1028
- }
1029
- newSelection.setAttribute('currentselection', 'true');
1030
- this.currentSelection = newSelection;
1081
+ }
1082
+
1083
+ handleSaveError(rejected) {
1084
+ this.shadowRoot.getElementById('dialog').set('Error', rejected.error);
1085
+ // this.$.dialog.set("Error", rejected.error);
1086
+ document.dispatchEvent(new CustomEvent('pb-end-update'));
1087
+ }
1088
+
1089
+ _reload() {
1090
+ this.shadowRoot
1091
+ .getElementById('dialog')
1092
+ .confirm(i18n('odd.editor.reload'), i18n('odd.editor.reload-confirm'))
1093
+ .then(
1094
+ () => {
1095
+ this.load();
1096
+ this.tabs = [];
1097
+ this.tabIndex = 0;
1098
+ this.shadowRoot.getElementById('currentElement').innerHTML = '';
1099
+ },
1100
+ () => null,
1101
+ );
1102
+ }
1103
+
1104
+ _setCurrentSelection(e) {
1105
+ if (this.currentSelection != undefined) {
1106
+ this.currentSelection.removeAttribute('currentselection');
1031
1107
  }
1108
+ this.currentSelection = e.target;
1109
+ this.currentSelection.setAttribute('currentselection', 'true');
1110
+ }
1032
1111
 
1033
- _selectElementspec(e) {
1034
- if (this.currentElementSpec &&
1035
- this.currentElementSpec.tagName === 'PB-ODD-ELEMENTSPEC-EDITOR') {
1036
- this.currentElementSpec.removeAttribute('currentselection');
1037
- }
1038
- const newSelection = e.target;
1039
- newSelection.setAttribute('currentselection', 'true');
1040
- this.currentElementSpec = newSelection;
1041
- }
1112
+ _changeSelection(ev) {
1113
+ ev.preventDefault();
1114
+ ev.stopPropagation();
1042
1115
 
1043
- nsDisabled() {
1044
- return !this.useNamespace;
1045
- }
1116
+ if (ev.detail.target === this) return;
1046
1117
 
1047
- _handleLoadError(e) {
1048
- console.log('loading error occurred: ', e);
1049
- const msg = this.shadowRoot.getElementById('errorMsg');
1050
- msg.style.background = 'red';
1051
- const url = this.shadowRoot.getElementById('loadContent').url;
1052
- console.log('url ', url);
1053
- msg.show('Error: ', 'ODD file could not be loaded from ' + url);
1118
+ if (this.currentSelection && this.currentSelection.tagName !== undefined) {
1119
+ this.currentSelection.removeAttribute('currentselection');
1054
1120
  }
1055
1121
 
1056
-
1057
- handleElementSpecChanged(e) {
1058
- // console.log('handleElementSpecChanged ',e);
1059
- this._hasChanges = true;
1060
- const elementSpec = this.elementSpecs.find(es => es.ident === e.detail.ident);
1061
- const index = this.elementSpecs.indexOf(elementSpec);
1062
- const newSpec = Object.assign({}, elementSpec, { models: e.detail.models });
1063
- const allSpecs = Array.from(this.elementSpecs);
1064
- allSpecs.splice(index, 1, newSpec)
1065
- this.elementSpecs = allSpecs;
1066
- // console.log('updated elementspecs ', this.elementSpecs);
1067
-
1122
+ let newSelection;
1123
+ if (ev.detail.target) {
1124
+ newSelection = ev.detail.target;
1125
+ } else {
1126
+ newSelection = ev.target;
1068
1127
  }
1069
-
1070
- _inputTitle(ev) {
1071
- this.title = ev.composedPath()[0].value;
1128
+ newSelection.setAttribute('currentselection', 'true');
1129
+ this.currentSelection = newSelection;
1130
+ }
1131
+
1132
+ _selectElementspec(e) {
1133
+ if (
1134
+ this.currentElementSpec &&
1135
+ this.currentElementSpec.tagName === 'PB-ODD-ELEMENTSPEC-EDITOR'
1136
+ ) {
1137
+ this.currentElementSpec.removeAttribute('currentselection');
1072
1138
  }
1073
-
1139
+ const newSelection = e.target;
1140
+ newSelection.setAttribute('currentselection', 'true');
1141
+ this.currentElementSpec = newSelection;
1142
+ }
1143
+
1144
+ nsDisabled() {
1145
+ return !this.useNamespace;
1146
+ }
1147
+
1148
+ _handleLoadError(e) {
1149
+ console.log('loading error occurred: ', e);
1150
+ const msg = this.shadowRoot.getElementById('errorMsg');
1151
+ msg.style.background = 'red';
1152
+ const { url } = this.shadowRoot.getElementById('loadContent');
1153
+ console.log('url ', url);
1154
+ msg.show('Error: ', `ODD file could not be loaded from ${url}`);
1155
+ }
1156
+
1157
+ handleElementSpecChanged(e) {
1158
+ // console.log('handleElementSpecChanged ',e);
1159
+ this._hasChanges = true;
1160
+ const elementSpec = this.elementSpecs.find(es => es.ident === e.detail.ident);
1161
+ const index = this.elementSpecs.indexOf(elementSpec);
1162
+ const newSpec = { ...elementSpec, models: e.detail.models };
1163
+ const allSpecs = Array.from(this.elementSpecs);
1164
+ allSpecs.splice(index, 1, newSpec);
1165
+ this.elementSpecs = allSpecs;
1166
+ // console.log('updated elementspecs ', this.elementSpecs);
1167
+ }
1168
+
1169
+ _inputTitle(ev) {
1170
+ this.title = ev.composedPath()[0].value;
1171
+ }
1074
1172
  }
1075
1173
 
1076
1174
  customElements.define('pb-odd-editor', PbOddEditor);