datafolder 1.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 (182) hide show
  1. package/README.md +169 -0
  2. package/index.js +3 -0
  3. package/package.json +27 -0
  4. package/sample.js +37 -0
  5. package/scripts/airbnb.js +73 -0
  6. package/scripts/airbnb2.js +74 -0
  7. package/scripts/airbnb2_queries.js +231 -0
  8. package/scripts/airbnb_queries.js +264 -0
  9. package/scripts/downloadFile.js +42 -0
  10. package/scripts/express.js +46 -0
  11. package/scripts/fastify.js +79 -0
  12. package/scripts/flights.js +75 -0
  13. package/scripts/flights2.js +81 -0
  14. package/scripts/flights2_queries.js +453 -0
  15. package/scripts/flights_queries.js +403 -0
  16. package/src/QyAcl.js +252 -0
  17. package/src/QyAclSaver.js +14 -0
  18. package/src/QyAclSaver_Worker.js +29 -0
  19. package/src/QyAclWriter.js +19 -0
  20. package/src/QyBatch.js +501 -0
  21. package/src/QyBinWriter.js +140 -0
  22. package/src/QyCD.js +61 -0
  23. package/src/QyCache.js +212 -0
  24. package/src/QyCompressor.js +60 -0
  25. package/src/QyCompressor_Worker.js +13 -0
  26. package/src/QyDB.js +122 -0
  27. package/src/QyDefaultOptions.js +59 -0
  28. package/src/QyDir.js +192 -0
  29. package/src/QyFetch.js +38 -0
  30. package/src/QyFile.js +124 -0
  31. package/src/QyFileContentUtils.js +175 -0
  32. package/src/QyFileLogger.js +58 -0
  33. package/src/QyIndex.js +237 -0
  34. package/src/QyIndexPropTree.js +92 -0
  35. package/src/QyIntersectNode.js +48 -0
  36. package/src/QyItem.js +105 -0
  37. package/src/QyJsonSaver.js +20 -0
  38. package/src/QyKVData.js +289 -0
  39. package/src/QyKVDataCleaner.js +17 -0
  40. package/src/QyKVDataCleaner_Worker.js +94 -0
  41. package/src/QyKVDataLoader.js +65 -0
  42. package/src/QyKVDataSaver.js +17 -0
  43. package/src/QyKVDataSaver_Worker.js +81 -0
  44. package/src/QyLogFileSaver.js +14 -0
  45. package/src/QyLogFileSaver_Worker.js +26 -0
  46. package/src/QyLogger.js +76 -0
  47. package/src/QyMessageWorker.js +41 -0
  48. package/src/QyMessager.js +84 -0
  49. package/src/QyMessager_Run.js +13 -0
  50. package/src/QyMod.js +15 -0
  51. package/src/QyOpRunner.js +73 -0
  52. package/src/QyQueue.js +60 -0
  53. package/src/QySaver.js +83 -0
  54. package/src/QySnapshotCompactor.js +17 -0
  55. package/src/QySnapshotCompactor_Worker.js +151 -0
  56. package/src/QySnapshotSaver.js +17 -0
  57. package/src/QySnapshotSaver_Worker.js +164 -0
  58. package/src/QySnapshots.js +354 -0
  59. package/src/QyStructure.js +50 -0
  60. package/src/QyTrigger.js +133 -0
  61. package/src/QyUnionNode.js +105 -0
  62. package/src/QyUtils.js +250 -0
  63. package/src/QyWorker.js +33 -0
  64. package/src/hackernews.js +93 -0
  65. package/src/rpc/evalCode.js +9 -0
  66. package/src/rpc/getFileContent.js +16 -0
  67. package/src/rpc/getSubItems.js +32 -0
  68. package/src/rpc/queryFiles.js +33 -0
  69. package/src/rpc/reloadRpc.js +1 -0
  70. package/src/simulate.js +114 -0
  71. package/src/simulate2.js +110 -0
  72. package/src/soc_pokec.js +43 -0
  73. package/static/bootstrap-5.3.8-dist/css/bootstrap.min.css +6 -0
  74. package/static/bootstrap-5.3.8-dist/js/bootstrap.bundle.js +6312 -0
  75. package/static/datafolderui/QyStyledElement.js +30 -0
  76. package/static/datafolderui/QyUIFolderTree.js +203 -0
  77. package/static/datafolderui/QyUIUtils.js +42 -0
  78. package/static/datafolderui/display-tree.js +108 -0
  79. package/static/datafolderui/explore-tree.js +122 -0
  80. package/static/datafolderui/folder-tree.js +5 -0
  81. package/static/datafolderui/hscrpt.js +25 -0
  82. package/static/datafolderui/index.css +6 -0
  83. package/static/datafolderui/index.html +20 -0
  84. package/static/datafolderui/json-view.js +74 -0
  85. package/static/datafolderui/kv-input.js +66 -0
  86. package/static/datafolderui/list-input.js +52 -0
  87. package/static/datafolderui/main-page.js +98 -0
  88. package/static/datafolderui/num-input.js +27 -0
  89. package/static/datafolderui/query-editor.js +229 -0
  90. package/static/datafolderui/querySelectorShadowRoot.js +24 -0
  91. package/static/datafolderui/resizable-input.js +67 -0
  92. package/static/favicon.ico +0 -0
  93. package/static/icons-1.13.1/font/bootstrap-icons.min.css +5 -0
  94. package/static/icons-1.13.1/font/fonts/bootstrap-icons.woff +0 -0
  95. package/static/icons-1.13.1/font/fonts/bootstrap-icons.woff2 +0 -0
  96. package/static/json-view/dist/jsonview.js +433 -0
  97. package/static/tree.js/tree.css +106 -0
  98. package/static/tree.js/tree.js +374 -0
  99. package/static/w2ui/dist/w2ui.min.css +2 -0
  100. package/static/w2ui/src/less/icons/icons.json +1 -0
  101. package/static/w2ui/src/less/icons/preview.html +33 -0
  102. package/static/w2ui/src/less/icons/readme.md +15 -0
  103. package/static/w2ui/src/less/icons/svg/box.svg +3 -0
  104. package/static/w2ui/src/less/icons/svg/check.svg +3 -0
  105. package/static/w2ui/src/less/icons/svg/colors.svg +3 -0
  106. package/static/w2ui/src/less/icons/svg/columns.svg +5 -0
  107. package/static/w2ui/src/less/icons/svg/cross.svg +4 -0
  108. package/static/w2ui/src/less/icons/svg/drop.svg +6 -0
  109. package/static/w2ui/src/less/icons/svg/empty.svg +3 -0
  110. package/static/w2ui/src/less/icons/svg/eye-dropper.svg +4 -0
  111. package/static/w2ui/src/less/icons/svg/info.svg +8 -0
  112. package/static/w2ui/src/less/icons/svg/paste.svg +4 -0
  113. package/static/w2ui/src/less/icons/svg/pencil.svg +5 -0
  114. package/static/w2ui/src/less/icons/svg/plus.svg +3 -0
  115. package/static/w2ui/src/less/icons/svg/reload.svg +5 -0
  116. package/static/w2ui/src/less/icons/svg/search.svg +3 -0
  117. package/static/w2ui/src/less/icons/svg/settings.svg +8 -0
  118. package/static/w2ui/src/less/icons/w2ui-font.css +36 -0
  119. package/static/w2ui/src/less/icons/w2ui-font.woff +0 -0
  120. package/static/w2ui/src/less/src/buttons.less +184 -0
  121. package/static/w2ui/src/less/src/common.less +541 -0
  122. package/static/w2ui/src/less/src/fields.less +302 -0
  123. package/static/w2ui/src/less/src/form.less +319 -0
  124. package/static/w2ui/src/less/src/grid.less +1057 -0
  125. package/static/w2ui/src/less/src/icons.less +37 -0
  126. package/static/w2ui/src/less/src/layout.less +86 -0
  127. package/static/w2ui/src/less/src/mixins.less +87 -0
  128. package/static/w2ui/src/less/src/popup.less +277 -0
  129. package/static/w2ui/src/less/src/sidebar.less +343 -0
  130. package/static/w2ui/src/less/src/tabs.less +145 -0
  131. package/static/w2ui/src/less/src/toolbar.less +219 -0
  132. package/static/w2ui/src/less/src/tooltip.less +948 -0
  133. package/static/w2ui/src/less/w2ui.less +196 -0
  134. package/static/w2ui/src/locale/az-az.json +114 -0
  135. package/static/w2ui/src/locale/ba-ba.json +114 -0
  136. package/static/w2ui/src/locale/bg-bg.json +114 -0
  137. package/static/w2ui/src/locale/ca-es.json +114 -0
  138. package/static/w2ui/src/locale/da-dk.json +114 -0
  139. package/static/w2ui/src/locale/de-de.json +114 -0
  140. package/static/w2ui/src/locale/en-gb.json +17 -0
  141. package/static/w2ui/src/locale/en-us.json +17 -0
  142. package/static/w2ui/src/locale/es-ar.json +115 -0
  143. package/static/w2ui/src/locale/es-cr.json +119 -0
  144. package/static/w2ui/src/locale/es-es.json +114 -0
  145. package/static/w2ui/src/locale/es-mx.json +114 -0
  146. package/static/w2ui/src/locale/fr-fr.json +114 -0
  147. package/static/w2ui/src/locale/gl-es.json +114 -0
  148. package/static/w2ui/src/locale/hr-hr.json +114 -0
  149. package/static/w2ui/src/locale/hu-hu.json +114 -0
  150. package/static/w2ui/src/locale/id-id.json +114 -0
  151. package/static/w2ui/src/locale/it-it.json +114 -0
  152. package/static/w2ui/src/locale/ja-jp.json +114 -0
  153. package/static/w2ui/src/locale/kk-kz.json +116 -0
  154. package/static/w2ui/src/locale/ko-kr.json +114 -0
  155. package/static/w2ui/src/locale/lt-lt.json +114 -0
  156. package/static/w2ui/src/locale/nl-nl.json +114 -0
  157. package/static/w2ui/src/locale/no-no.json +114 -0
  158. package/static/w2ui/src/locale/pl-pl.json +114 -0
  159. package/static/w2ui/src/locale/pt-br.json +114 -0
  160. package/static/w2ui/src/locale/ru-ru.json +116 -0
  161. package/static/w2ui/src/locale/sk-sk.json +114 -0
  162. package/static/w2ui/src/locale/sl-si.json +116 -0
  163. package/static/w2ui/src/locale/sr-rs.json +114 -0
  164. package/static/w2ui/src/locale/tr-tr.json +114 -0
  165. package/static/w2ui/src/locale/uk-ua.json +114 -0
  166. package/static/w2ui/src/locale/zh-cn.json +114 -0
  167. package/static/w2ui/src/locale/zh-tw.json +114 -0
  168. package/static/w2ui/src/query.js +583 -0
  169. package/static/w2ui/src/readme.md +11 -0
  170. package/static/w2ui/src/w2base.js +311 -0
  171. package/static/w2ui/src/w2compat.js +207 -0
  172. package/static/w2ui/src/w2field.js +1854 -0
  173. package/static/w2ui/src/w2form.js +2411 -0
  174. package/static/w2ui/src/w2grid.js +8916 -0
  175. package/static/w2ui/src/w2layout.js +1194 -0
  176. package/static/w2ui/src/w2locale.js +129 -0
  177. package/static/w2ui/src/w2popup.js +909 -0
  178. package/static/w2ui/src/w2sidebar.js +1769 -0
  179. package/static/w2ui/src/w2tabs.js +669 -0
  180. package/static/w2ui/src/w2toolbar.js +1180 -0
  181. package/static/w2ui/src/w2tooltip.js +3134 -0
  182. package/static/w2ui/src/w2utils.js +2457 -0
@@ -0,0 +1,1194 @@
1
+ /**
2
+ * Part of w2ui 2.0 library
3
+ * - Dependencies: mQuery, w2utils, w2base, w2tabs, w2toolbar
4
+ *
5
+ * == 2.0 changes
6
+ * - CSP - fixed inline events
7
+ * - remove jQuery dependency
8
+ * - layout.confirm - refactored
9
+ * - layout.message - refactored
10
+ * - panel.removed
11
+ * - assignTabs
12
+ */
13
+
14
+ import { w2base } from './w2base.js'
15
+ import { w2ui, w2utils } from './w2utils.js'
16
+ import { query } from './query.js'
17
+ import { w2tabs } from './w2tabs.js'
18
+ import { w2toolbar } from './w2toolbar.js'
19
+
20
+ let w2panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']
21
+
22
+ class w2layout extends w2base {
23
+ constructor(options) {
24
+ super(options.name)
25
+ this.box = null // DOM Element that holds the element
26
+ this.name = null // unique name for w2ui
27
+ this.panels = []
28
+ this.last = {}
29
+ this.padding = 1 // panel padding
30
+ this.resizer = 4 // resizer width or height
31
+ this.style = ''
32
+ this.onShow = null
33
+ this.onHide = null
34
+ this.onResizing = null
35
+ this.onResizerClick = null
36
+ this.onRender = null
37
+ this.onRefresh = null
38
+ this.onChange = null
39
+ this.onResize = null
40
+ this.onDestroy = null
41
+ this.panel_template = {
42
+ type: null, // left, right, top, bottom
43
+ title: '',
44
+ size: 100, // width or height depending on panel name
45
+ minSize: 20,
46
+ maxSize: false,
47
+ hidden: false,
48
+ resizable: false,
49
+ overflow: 'auto',
50
+ style: '',
51
+ html: '', // can be String or Object with .render(box) method
52
+ tabs: null,
53
+ toolbar: null,
54
+ width: null, // read only
55
+ height: null, // read only
56
+ show: {
57
+ toolbar: false,
58
+ tabs: false
59
+ },
60
+ removed: null, // function to call when content is overwritten
61
+ onRefresh: null,
62
+ onShow: null,
63
+ onHide: null
64
+ }
65
+ // mix in options
66
+ Object.assign(this, options)
67
+ if (!Array.isArray(this.panels)) this.panels = []
68
+ // add defined panels
69
+ this.panels.forEach((panel, ind) => {
70
+ this.panels[ind] = w2utils.extend({}, this.panel_template, panel)
71
+ if (w2utils.isPlainObject(panel.tabs) || Array.isArray(panel.tabs)) initTabs(this, panel.type)
72
+ if (w2utils.isPlainObject(panel.toolbar) || Array.isArray(panel.toolbar)) initToolbar(this, panel.type)
73
+ })
74
+ // add all other panels
75
+ w2panels.forEach(tab => {
76
+ if (this.get(tab) != null) return
77
+ this.panels.push(w2utils.extend({}, this.panel_template, { type: tab, hidden: (tab !== 'main'), size: 50 }))
78
+ })
79
+
80
+ // render if box specified
81
+ if (typeof this.box == 'string') this.box = query(this.box).get(0)
82
+ if (this.box) this.render(this.box)
83
+
84
+ function initTabs(object, panel, tabs) {
85
+ let pan = object.get(panel)
86
+ if (pan != null && tabs == null) tabs = pan.tabs
87
+ if (pan == null || tabs == null) return false
88
+ // instantiate tabs
89
+ if (Array.isArray(tabs)) tabs = { tabs: tabs }
90
+ let name = object.name + '_' + panel + '_tabs'
91
+ if (w2ui[name]) w2ui[name].destroy() // destroy if existed
92
+ pan.tabs = new w2tabs(w2utils.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' }))
93
+ pan.show.tabs = true
94
+ return true
95
+ }
96
+
97
+ function initToolbar(object, panel, toolbar) {
98
+ let pan = object.get(panel)
99
+ if (pan != null && toolbar == null) toolbar = pan.toolbar
100
+ if (pan == null || toolbar == null) return false
101
+ // instantiate toolbar
102
+ if (Array.isArray(toolbar)) toolbar = { items: toolbar }
103
+ let name = object.name + '_' + panel + '_toolbar'
104
+ if (w2ui[name]) w2ui[name].destroy() // destroy if existed
105
+ pan.toolbar = new w2toolbar(w2utils.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' }))
106
+ pan.show.toolbar = true
107
+ return true
108
+ }
109
+ }
110
+
111
+ html(panel, data, transition) {
112
+ let p = this.get(panel)
113
+ let promise = {
114
+ panel: panel,
115
+ html: p.html,
116
+ error: false,
117
+ cancelled: false,
118
+ removed(cb) {
119
+ if (typeof cb == 'function') {
120
+ p.removed = cb
121
+ }
122
+ }
123
+ }
124
+ if (typeof p.removed == 'function') {
125
+ p.removed({ panel: panel, html: p.html, html_new: data, transition: transition || 'none' })
126
+ p.removed = null // this is one time call back only
127
+ }
128
+ // if it is CSS panel
129
+ if (panel == 'css') {
130
+ query(this.box).find('#layout_'+ this.name +'_panel_css').html('<style>'+ data +'</style>')
131
+ promise.status = true
132
+ return promise
133
+ }
134
+ if (p == null) {
135
+ console.log('ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css')
136
+ promise.error = true
137
+ return promise
138
+ }
139
+ if (data == null) {
140
+ return promise
141
+ }
142
+ // event before
143
+ let edata = this.trigger('change', { target: panel, panel: p, html_new: data, transition: transition })
144
+ if (edata.isCancelled === true) {
145
+ promise.cancelled = true
146
+ return promise
147
+ }
148
+ let pname = '#layout_'+ this.name + '_panel_'+ p.type
149
+ let current = query(this.box).find(pname + '> [data-role="panel-content"]')
150
+ let panelTop = 0
151
+ if (current.length > 0) {
152
+ query(this.box).find(pname).get(0).scrollTop = 0
153
+ panelTop = query(current).css('top')
154
+ }
155
+ // clean up previous content
156
+ if (typeof p.html.unmount == 'function') p.html.unmount()
157
+ current.addClass('w2ui-panel-content')
158
+ current.removeAttr('style') // styles could have added manually, but all necessary will be added by resizeBoxes
159
+ this.resizeBoxes(panel)
160
+
161
+ if (p.html === '') {
162
+ p.html = data
163
+ this.refresh(panel)
164
+ } else {
165
+ p.html = data
166
+ if (!p.hidden) {
167
+ if (transition != null && transition !== '') {
168
+ // apply transition
169
+ query(this.box).addClass('animating')
170
+ let div1 = query(this.box).find(pname + '> [data-role="panel-content"]')
171
+ div1.after('<div class="w2ui-panel-content new-panel" data-role="panel-content" style="'+ div1[0].style.cssText +'"></div>')
172
+ let div2 = query(this.box).find(pname + '> [data-role="panel-content"].new-panel')
173
+ div1.css('top', panelTop)
174
+ div2.css('top', panelTop)
175
+ if (typeof data == 'object') {
176
+ data.box = div2[0] // do not do .render(box);
177
+ data.render()
178
+ } else {
179
+ div2.hide().html(data)
180
+ }
181
+ w2utils.transition(div1[0], div2[0], transition, () => {
182
+ div1.remove()
183
+ div2.removeClass('new-panel')
184
+ div2.css('overflow', p.overflow)
185
+ // make sure only one content left
186
+ query(query(this.box).find(pname + '> [data-role="panel-content"]').get(1)).remove()
187
+ query(this.box).removeClass('animating')
188
+ this.refresh(panel)
189
+ })
190
+ } else {
191
+ this.refresh(panel)
192
+ }
193
+ }
194
+ }
195
+ // event after
196
+ edata.finish()
197
+ return promise
198
+ }
199
+
200
+ message(panel, options) {
201
+ let p = this.get(panel)
202
+ let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type)
203
+ let oldOverflow = box.css('overflow')
204
+ box.css('overflow', 'hidden')
205
+ let prom = w2utils.message({
206
+ owner: this,
207
+ box : box.get(0),
208
+ after: '.w2ui-panel-title',
209
+ param: panel
210
+ }, options)
211
+ if (prom) {
212
+ prom.self.on('close:after', () => {
213
+ box.css('overflow', oldOverflow)
214
+ })
215
+ }
216
+ return prom
217
+ }
218
+
219
+ confirm(panel, options) {
220
+ let p = this.get(panel)
221
+ let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type)
222
+ let oldOverflow = box.css('overflow')
223
+ box.css('overflow', 'hidden')
224
+ let prom = w2utils.confirm({
225
+ owner : this,
226
+ box : box.get(0),
227
+ after : '.w2ui-panel-title',
228
+ param : panel
229
+ }, options)
230
+ if (prom) {
231
+ prom.self.on('close:after', () => {
232
+ box.css('overflow', oldOverflow)
233
+ })
234
+ }
235
+ return prom
236
+ }
237
+
238
+ load(panel, url, transition) {
239
+ return new Promise((resolve, reject) => {
240
+ if ((panel == 'css' || this.get(panel) != null) && url != null) {
241
+ fetch(url)
242
+ .then(resp => resp.text())
243
+ .then(text => {
244
+ this.resize()
245
+ resolve(this.html(panel, text, transition))
246
+ })
247
+ } else {
248
+ reject()
249
+ }
250
+ })
251
+ }
252
+
253
+ sizeTo(panel, size, instant) {
254
+ let pan = this.get(panel)
255
+ if (pan == null) return false
256
+ // resize
257
+ query(this.box).find(':scope > div > .w2ui-panel')
258
+ .css('transition', (instant !== true ? '.2s' : '0s'))
259
+ setTimeout(() => { this.set(panel, { size: size }) }, 1)
260
+ // clean
261
+ setTimeout(() => {
262
+ query(this.box).find(':scope > div > .w2ui-panel').css('transition', '0s')
263
+ this.resize()
264
+ }, 300)
265
+ return true
266
+ }
267
+
268
+ show(panel, immediate) {
269
+ // event before
270
+ let edata = this.trigger('show', { target: panel, thisect: this.get(panel), immediate: immediate })
271
+ if (edata.isCancelled === true) return
272
+
273
+ let p = this.get(panel)
274
+ if (p == null) return false
275
+ p.hidden = false
276
+ if (immediate === true) {
277
+ query(this.box).find('#layout_'+ this.name +'_panel_'+panel)
278
+ .css({ 'opacity': '1' })
279
+ edata.finish()
280
+ this.resize()
281
+ } else {
282
+ // resize
283
+ query(this.box).addClass('animating')
284
+ query(this.box).find('#layout_'+ this.name +'_panel_'+panel)
285
+ .css({ 'opacity': '0' })
286
+ query(this.box).find(':scope > div > .w2ui-panel')
287
+ .css('transition', '.2s')
288
+ setTimeout(() => { this.resize() }, 1)
289
+ // show
290
+ setTimeout(() => {
291
+ query(this.box).find('#layout_'+ this.name +'_panel_'+ panel).css({ 'opacity': '1' })
292
+ }, 250)
293
+ // clean
294
+ setTimeout(() => {
295
+ query(this.box).find(':scope > div > .w2ui-panel')
296
+ .css('transition', '0s')
297
+ query(this.box).removeClass('animating')
298
+ edata.finish()
299
+ this.resize()
300
+ }, 300)
301
+ }
302
+ return true
303
+ }
304
+
305
+ hide(panel, immediate) {
306
+ // event before
307
+ let edata = this.trigger('hide', { target: panel, object: this.get(panel), immediate: immediate })
308
+ if (edata.isCancelled === true) return
309
+
310
+ let p = this.get(panel)
311
+ if (p == null) return false
312
+ p.hidden = true
313
+ if (immediate === true) {
314
+ query(this.box).find('#layout_'+ this.name +'_panel_'+panel)
315
+ .css({ 'opacity': '0' })
316
+ edata.finish()
317
+ this.resize()
318
+ } else {
319
+ // hide
320
+ query(this.box).addClass('animating')
321
+ query(this.box).find(':scope > div > .w2ui-panel')
322
+ .css('transition', '.2s')
323
+ query(this.box).find('#layout_'+ this.name +'_panel_'+panel)
324
+ .css({ 'opacity': '0' })
325
+ setTimeout(() => { this.resize() }, 1)
326
+ // clean
327
+ setTimeout(() => {
328
+ query(this.box).find(':scope > div > .w2ui-panel')
329
+ .css('transition', '0s')
330
+ query(this.box).removeClass('animating')
331
+ edata.finish()
332
+ this.resize()
333
+ }, 300)
334
+ }
335
+ return true
336
+ }
337
+
338
+ toggle(panel, immediate) {
339
+ let p = this.get(panel)
340
+ if (p == null) return false
341
+ if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate)
342
+ }
343
+
344
+ set(panel, options) {
345
+ let ind = this.get(panel, true)
346
+ if (ind == null) return false
347
+ w2utils.extend(this.panels[ind], options)
348
+ // refresh only when content changed
349
+ if (options.html != null || options.resizable != null) {
350
+ this.refresh(panel)
351
+ }
352
+ // show/hide resizer
353
+ this.resize() // resize is needed when panel size is changed
354
+ return true
355
+ }
356
+
357
+ get(panel, returnIndex) {
358
+ for (let p = 0; p < this.panels.length; p++) {
359
+ if (this.panels[p].type == panel) {
360
+ if (returnIndex === true) return p; else return this.panels[p]
361
+ }
362
+ }
363
+ return null
364
+ }
365
+
366
+ el(panel) {
367
+ let el = query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> [data-role="panel-content"]')
368
+ if (el.length != 1) return null
369
+ return el[0]
370
+ }
371
+
372
+ hideToolbar(panel) {
373
+ let pan = this.get(panel)
374
+ if (!pan) return
375
+ pan.show.toolbar = false
376
+ query(this.box).find(`#layout_${this.name}_panel_${panel} > [data-role="panel-toolbar"]`).hide()
377
+ this.resize()
378
+ }
379
+
380
+ showToolbar(panel) {
381
+ let pan = this.get(panel)
382
+ if (!pan) return
383
+ pan.show.toolbar = true
384
+ query(this.box).find(`#layout_${this.name}_panel_${panel} > [data-role="panel-toolbar"]`).show()
385
+ this.resize()
386
+ }
387
+
388
+ toggleToolbar(panel) {
389
+ let pan = this.get(panel)
390
+ if (!pan) return
391
+ if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel)
392
+ }
393
+
394
+ assignToolbar(panel, toolbar) {
395
+ if (typeof toolbar == 'string' && w2ui[toolbar] != null) toolbar = w2ui[toolbar]
396
+ let pan = this.get(panel)
397
+ pan.toolbar = toolbar
398
+ let tmp = query(this.box).find(panel +'> [data-role="panel-toolbar"]')
399
+ if (pan.toolbar != null) {
400
+ if (tmp.attr('name') != pan.toolbar.name) {
401
+ pan.toolbar.render(tmp.get(0))
402
+ } else if (pan.toolbar != null) {
403
+ pan.toolbar.refresh()
404
+ }
405
+ toolbar.owner = this
406
+ this.showToolbar(panel)
407
+ this.refresh(panel)
408
+ } else {
409
+ tmp.html('')
410
+ this.hideToolbar(panel)
411
+ }
412
+ }
413
+
414
+ hideTabs(panel) {
415
+ let pan = this.get(panel)
416
+ if (!pan) return
417
+ pan.show.tabs = false
418
+ query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> [data-role="panel-tabs"]').hide()
419
+ this.resize()
420
+ }
421
+
422
+ showTabs(panel) {
423
+ let pan = this.get(panel)
424
+ if (!pan) return
425
+ pan.show.tabs = true
426
+ query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> [data-role="panel-tabs"]').show()
427
+ this.resize()
428
+ }
429
+
430
+ toggleTabs(panel) {
431
+ let pan = this.get(panel)
432
+ if (!pan) return
433
+ if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel)
434
+ }
435
+
436
+ assignTabs(panel, tabs) {
437
+ if (typeof tabs == 'string' && w2ui[tabs] != null) tabs = w2ui[tabs]
438
+ let pan = this.get(panel)
439
+ pan.tabs = tabs
440
+ let tmp = query(this.box).find(panel +'> [data-role="panel-tabs"]')
441
+ if (pan.tabs != null) {
442
+ if (tmp.attr('name') != pan.tabs.name) {
443
+ pan.tabs.render(tmp.get(0))
444
+ } else if (pan.tabs != null) {
445
+ pan.tabs.refresh()
446
+ }
447
+ tabs.owner = this
448
+ this.showTabs(panel)
449
+ this.refresh(panel)
450
+ } else {
451
+ tmp.html('')
452
+ this.hideTabs(panel)
453
+ }
454
+ }
455
+
456
+ render(box) {
457
+ let time = Date.now()
458
+ let self = this
459
+ if (typeof box == 'string') box = query(box).get(0)
460
+ // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection
461
+ // event before
462
+ let edata = this.trigger('render', { target: this.name, box: box ?? this.box })
463
+ if (edata.isCancelled === true) return
464
+ // default action
465
+ if (box != null) {
466
+ this.unmount() // clean previous control
467
+ this.box = box
468
+ }
469
+ if (!this.box) return false
470
+ // render layout
471
+ query(this.box)
472
+ .attr('name', this.name)
473
+ .addClass('w2ui-layout')
474
+ .html('<div></div>')
475
+ if (query(this.box).length > 0) {
476
+ query(this.box)[0].style.cssText += this.style
477
+ }
478
+ // create all panels
479
+ for (let p1 = 0; p1 < w2panels.length; p1++) {
480
+ let html = '<div id="layout_'+ this.name + '_panel_'+ w2panels[p1] +'" class="w2ui-panel">'+
481
+ ' <div class="w2ui-panel-title"></div>'+
482
+ ' <div class="w2ui-panel-tabs" data-role="panel-tabs"></div>'+
483
+ ' <div class="w2ui-panel-toolbar" data-role="panel-toolbar"></div>'+
484
+ ' <div class="w2ui-panel-content" data-role="panel-content"></div>'+
485
+ '</div>'+
486
+ '<div id="layout_'+ this.name + '_resizer_'+ w2panels[p1] +'" class="w2ui-resizer"></div>'
487
+ query(this.box).find(':scope > div').append(html)
488
+ }
489
+ query(this.box).find(':scope > div')
490
+ .append('<div id="layout_'+ this.name + '_panel_css" style="position: absolute; top: 10000px;"></div>')
491
+ this.refresh() // if refresh is not called here, the layout will not be available right after initialization
492
+ // observe div resize
493
+ this.last.observeResize = new ResizeObserver(() => { this.resize() })
494
+ this.last.observeResize.observe(this.box)
495
+ // process event
496
+ edata.finish()
497
+ // re-init events
498
+ setTimeout(() => { // needed this timeout to allow browser to render first if there are tabs or toolbar
499
+ self.last.events = { resizeStart, mouseMove, mouseUp }
500
+ this.resize()
501
+ }, 0)
502
+ return Date.now() - time
503
+
504
+ function resizeStart(type, evnt) {
505
+ if (!self.box) return
506
+ if (!evnt) evnt = window.event
507
+ query(document)
508
+ .off('mousemove', self.last.events.mouseMove)
509
+ .on('mousemove', self.last.events.mouseMove)
510
+ query(document)
511
+ .off('mouseup', self.last.events.mouseUp)
512
+ .on('mouseup', self.last.events.mouseUp)
513
+ self.last.resize = {
514
+ type : type,
515
+ x : evnt.screenX,
516
+ y : evnt.screenY,
517
+ diff_x : 0,
518
+ diff_y : 0,
519
+ value : 0
520
+ }
521
+ // lock all panels
522
+ w2panels.forEach(panel => {
523
+ let $tmp = query(self.el(panel)).find('.w2ui-lock')
524
+ if ($tmp.length > 0) {
525
+ $tmp.data('locked', 'yes')
526
+ } else {
527
+ self.lock(panel, { opacity: 0 })
528
+ }
529
+ })
530
+ let el = query(self.box).find('#layout_'+ self.name +'_resizer_'+ type).get(0)
531
+ if (type == 'left' || type == 'right') {
532
+ self.last.resize.value = parseInt(el.style.left)
533
+ }
534
+ if (type == 'top' || type == 'preview' || type == 'bottom') {
535
+ self.last.resize.value = parseInt(el.style.top)
536
+ }
537
+ }
538
+
539
+ function mouseUp(evnt) {
540
+ if (!self.box) return
541
+ if (!evnt) evnt = window.event
542
+ query(document).off('mousemove', self.last.events.mouseMove)
543
+ query(document).off('mouseup', self.last.events.mouseUp)
544
+ if (self.last.resize == null) return
545
+ // unlock all panels
546
+ w2panels.forEach(panel => {
547
+ let $tmp = query(self.el(panel)).find('.w2ui-lock')
548
+ if ($tmp.data('locked') == 'yes') {
549
+ $tmp.removeData('locked')
550
+ } else {
551
+ self.unlock(panel)
552
+ }
553
+ })
554
+ // set new size
555
+ if (self.last.diff_x !== 0 || self.last.resize.diff_y !== 0) { // only recalculate if changed
556
+ let ptop = self.get('top')
557
+ let pbottom = self.get('bottom')
558
+ let panel = self.get(self.last.resize.type)
559
+ let width = w2utils.getSize(query(self.box), 'width')
560
+ let height = w2utils.getSize(query(self.box), 'height')
561
+ let str = String(panel.size)
562
+ let ns, nd
563
+ switch (self.last.resize.type) {
564
+ case 'top':
565
+ ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_y
566
+ nd = 0
567
+ break
568
+ case 'bottom':
569
+ ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y
570
+ nd = 0
571
+ break
572
+ case 'preview':
573
+ ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y
574
+ nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) +
575
+ (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0)
576
+ break
577
+ case 'left':
578
+ ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_x
579
+ nd = 0
580
+ break
581
+ case 'right':
582
+ ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_x
583
+ nd = 0
584
+ break
585
+ }
586
+ // set size
587
+ if (str.substr(str.length-1) == '%') {
588
+ panel.size = Math.floor(ns * 100 / (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%'
589
+ } else {
590
+ if (String(panel.size).substr(0, 1) == '-') {
591
+ panel.size = parseInt(panel.size) - panel.sizeCalculated + ns
592
+ } else {
593
+ panel.size = ns
594
+ }
595
+ }
596
+ self.resize()
597
+ }
598
+ query(self.box)
599
+ .find('#layout_'+ self.name + '_resizer_'+ self.last.resize.type)
600
+ .removeClass('active')
601
+ delete self.last.resize
602
+ }
603
+
604
+ function mouseMove(evnt) {
605
+ if (!self.box) return
606
+ if (!evnt) evnt = window.event
607
+ if (self.last.resize == null) return
608
+ let panel = self.get(self.last.resize.type)
609
+ // event before
610
+ let tmp = self.last.resize
611
+ let edata = self.trigger('resizing', { target: self.name, object: panel, originalEvent: evnt,
612
+ panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 })
613
+ if (edata.isCancelled === true) return
614
+
615
+ let p = query(self.box).find('#layout_'+ self.name + '_resizer_'+ tmp.type)
616
+ let resize_x = (evnt.screenX - tmp.x)
617
+ let resize_y = (evnt.screenY - tmp.y)
618
+ let mainPanel = self.get('main')
619
+
620
+ if (!p.hasClass('active')) p.addClass('active')
621
+
622
+ switch (tmp.type) {
623
+ case 'left':
624
+ if (panel.minSize - resize_x > panel.width) {
625
+ resize_x = panel.minSize - panel.width
626
+ }
627
+ if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) {
628
+ resize_x = panel.maxSize - panel.width
629
+ }
630
+ if (mainPanel.minSize + resize_x > mainPanel.width) {
631
+ resize_x = mainPanel.width - mainPanel.minSize
632
+ }
633
+ break
634
+
635
+ case 'right':
636
+ if (panel.minSize + resize_x > panel.width) {
637
+ resize_x = panel.width - panel.minSize
638
+ }
639
+ if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) {
640
+ resize_x = panel.width - panel.maxSize
641
+ }
642
+ if (mainPanel.minSize - resize_x > mainPanel.width) {
643
+ resize_x = mainPanel.minSize - mainPanel.width
644
+ }
645
+ break
646
+
647
+ case 'top':
648
+ if (panel.minSize - resize_y > panel.height) {
649
+ resize_y = panel.minSize - panel.height
650
+ }
651
+ if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) {
652
+ resize_y = panel.maxSize - panel.height
653
+ }
654
+ if (mainPanel.minSize + resize_y > mainPanel.height) {
655
+ resize_y = mainPanel.height - mainPanel.minSize
656
+ }
657
+ break
658
+
659
+ case 'preview':
660
+ case 'bottom':
661
+ if (panel.minSize + resize_y > panel.height) {
662
+ resize_y = panel.height - panel.minSize
663
+ }
664
+ if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) {
665
+ resize_y = panel.height - panel.maxSize
666
+ }
667
+ if (mainPanel.minSize - resize_y > mainPanel.height) {
668
+ resize_y = mainPanel.minSize - mainPanel.height
669
+ }
670
+ break
671
+ }
672
+ tmp.diff_x = resize_x
673
+ tmp.diff_y = resize_y
674
+
675
+ switch (tmp.type) {
676
+ case 'top':
677
+ case 'preview':
678
+ case 'bottom':
679
+ tmp.diff_x = 0
680
+ if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'
681
+ break
682
+
683
+ case 'left':
684
+ case 'right':
685
+ tmp.diff_y = 0
686
+ if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'
687
+ break
688
+ }
689
+ // event after
690
+ edata.finish()
691
+ }
692
+ }
693
+
694
+ unmount() {
695
+ super.unmount()
696
+ this.panels.forEach(panel => {
697
+ panel.tabs?.unmount?.()
698
+ panel.toolbar?.unmount?.()
699
+ })
700
+ this.last.observeResize?.disconnect()
701
+ }
702
+
703
+ destroy() {
704
+ // event before
705
+ let edata = this.trigger('destroy', { target: this.name })
706
+ if (edata.isCancelled === true) return
707
+ if (w2ui[this.name] == null) return false
708
+ // clean up
709
+ this.panels.forEach(panel => {
710
+ panel.tabs?.destroy?.()
711
+ panel.toolbar?.destroy?.()
712
+ })
713
+ if (query(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) {
714
+ this.unmount()
715
+ }
716
+ delete w2ui[this.name]
717
+ // event after
718
+ edata.finish()
719
+ if (this.last.events && this.last.events.resize) {
720
+ query(window).off('resize', this.last.events.resize)
721
+ }
722
+ return true
723
+ }
724
+
725
+ refresh(panel) {
726
+ let self = this
727
+ // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection
728
+ if (panel == null) panel = null
729
+ let time = Date.now()
730
+ // event before
731
+ let edata = self.trigger('refresh', { target: (panel != null ? panel : self.name), object: self.get(panel) })
732
+ if (edata.isCancelled === true) return
733
+ // self.unlock(panel);
734
+ if (typeof panel == 'string') {
735
+ let p = self.get(panel)
736
+ if (p == null) return
737
+ let pname = '#layout_'+ self.name + '_panel_'+ p.type
738
+ let rname = '#layout_'+ self.name +'_resizer_'+ p.type
739
+ // apply properties to the panel
740
+ query(self.box).find(pname).css({ display: p.hidden ? 'none' : 'block' })
741
+ if (p.resizable) {
742
+ query(self.box).find(rname).show()
743
+ } else {
744
+ query(self.box).find(rname).hide()
745
+ }
746
+ // insert content
747
+ if (typeof p.html == 'object' && typeof p.html.render === 'function') {
748
+ p.html.box = query(self.box).find(pname +'> [data-role="panel-content"]')[0]
749
+ setTimeout(() => {
750
+ // need to remove unnecessary classes
751
+ if (query(self.box).find(pname +'> [data-role="panel-content"]').length > 0) {
752
+ query(self.box).find(pname +'> [data-role="panel-content"]')
753
+ .removeClass()
754
+ .removeAttr('name')
755
+ .addClass('w2ui-panel-content')
756
+ .css('overflow', p.overflow)[0].style.cssText += ';' + p.style
757
+ }
758
+ if (p.html && typeof p.html.render == 'function') {
759
+ p.html.render() // do not do .render(box);
760
+ }
761
+ }, 1)
762
+ } else {
763
+ // need to remove unnecessary classes
764
+ if (query(self.box).find(pname +'> [data-role="panel-content"]').length > 0) {
765
+ query(self.box).find(pname +'> [data-role="panel-content"]')
766
+ .removeClass()
767
+ .removeAttr('name')
768
+ .addClass('w2ui-panel-content')
769
+ .html(p.html)
770
+ .css('overflow', p.overflow)[0].style.cssText += ';' + p.style
771
+ }
772
+ }
773
+ // if there are tabs and/or toolbar - render it
774
+ let tmp = query(self.box).find(pname +'> [data-role="panel-tabs"]')
775
+ if (p.show.tabs) {
776
+ if (tmp.attr('name') != p.tabs.name && p.tabs != null) {
777
+ p.tabs.render(tmp.get(0))
778
+ } else {
779
+ p.tabs.refresh()
780
+ }
781
+ tmp.addClass('w2ui-panel-tabs')
782
+ } else {
783
+ tmp.html('').removeAttr('name').removeClass('w2ui-tabs').hide()
784
+ }
785
+ tmp = query(self.box).find(pname +'> [data-role="panel-toolbar"]')
786
+ if (p.show.toolbar) {
787
+ if (tmp.attr('name') != p.toolbar.name && p.toolbar != null) {
788
+ p.toolbar.render(tmp.get(0))
789
+ } else {
790
+ p.toolbar.refresh()
791
+ }
792
+ tmp.addClass('w2ui-panel-toolbar')
793
+ } else {
794
+ tmp.html('').removeAttr('name').removeClass('w2ui-toolbar').hide()
795
+ }
796
+ // show title
797
+ tmp = query(self.box).find(pname +'> .w2ui-panel-title')
798
+ if (p.title) {
799
+ tmp.html(p.title).show()
800
+ } else {
801
+ tmp.html('').hide()
802
+ }
803
+ } else {
804
+ if (query(self.box).find('#layout_'+ self.name +'_panel_main').length === 0) {
805
+ self.render()
806
+ return
807
+ }
808
+ self.resize()
809
+ // refresh all of them
810
+ for (let p1 = 0; p1 < this.panels.length; p1++) { self.refresh(this.panels[p1].type) }
811
+ }
812
+ edata.finish()
813
+ return Date.now() - time
814
+ }
815
+
816
+ resize() {
817
+ // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection
818
+ if (!this.box) return false
819
+ let time = Date.now()
820
+ // event before
821
+ let tmp = this.last.resize
822
+ let edata = this.trigger('resize', { target: this.name,
823
+ panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 })
824
+ if (edata.isCancelled === true) return
825
+ if (this.padding < 0) this.padding = 0
826
+
827
+ // layout itself
828
+ // width includes border and padding, we need to exclude that so panels
829
+ // are sized correctly
830
+ let width = w2utils.getSize(query(this.box), 'width')
831
+ let height = w2utils.getSize(query(this.box), 'height')
832
+ let self = this
833
+ // panels
834
+ let pmain = this.get('main')
835
+ let pprev = this.get('preview')
836
+ let pleft = this.get('left')
837
+ let pright = this.get('right')
838
+ let ptop = this.get('top')
839
+ let pbottom = this.get('bottom')
840
+ let sprev = (pprev != null && pprev.hidden !== true ? true : false)
841
+ let sleft = (pleft != null && pleft.hidden !== true ? true : false)
842
+ let sright = (pright != null && pright.hidden !== true ? true : false)
843
+ let stop = (ptop != null && ptop.hidden !== true ? true : false)
844
+ let sbottom = (pbottom != null && pbottom.hidden !== true ? true : false)
845
+ let l, t, w, h
846
+ // calculate %
847
+ for (let p = 0; p < w2panels.length; p++) {
848
+ if (w2panels[p] === 'main') continue
849
+ tmp = this.get(w2panels[p])
850
+ if (!tmp) continue
851
+ let str = String(tmp.size || 0)
852
+ if (str.substr(str.length-1) == '%') {
853
+ let tmph = height
854
+ if (tmp.type == 'preview') {
855
+ tmph = tmph -
856
+ (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) -
857
+ (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0)
858
+ }
859
+ tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100)
860
+ } else {
861
+ tmp.sizeCalculated = parseInt(tmp.size)
862
+ }
863
+ tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize))
864
+ }
865
+ // negative size
866
+ if (parseInt(pright.size) < 0) {
867
+ if (sleft && parseInt(pleft.size) < 0) {
868
+ console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.')
869
+ } else {
870
+ pright.sizeCalculated = width - (sleft ? pleft.sizeCalculated : 0) + parseInt(pright.size)
871
+ }
872
+ }
873
+ if (parseInt(pleft.size) < 0) {
874
+ if (sright && parseInt(pright.size) < 0) {
875
+ console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.')
876
+ } else {
877
+ pleft.sizeCalculated = width - (sright ? pright.sizeCalculated : 0) + parseInt(pleft.size)
878
+ }
879
+ }
880
+ if (parseInt(pprev.size) < 0) {
881
+ pprev.sizeCalculated = height + parseInt(pprev.size)
882
+ if (pprev.sizeCalculated > height) pprev.sizeCalculated = height
883
+ }
884
+ // top if any
885
+ if (ptop != null && ptop.hidden !== true) {
886
+ l = 0
887
+ t = 0
888
+ w = width
889
+ h = ptop.sizeCalculated
890
+ query(this.box).find('#layout_'+ this.name +'_panel_top')
891
+ .css({
892
+ 'display': 'block',
893
+ 'left': l + 'px',
894
+ 'top': t + 'px',
895
+ 'width': w + 'px',
896
+ 'height': h + 'px'
897
+ })
898
+ ptop.width = w
899
+ ptop.height = h
900
+ // resizer
901
+ if (ptop.resizable) {
902
+ t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0)
903
+ h = (this.resizer > this.padding ? this.resizer : this.padding)
904
+ query(this.box).find('#layout_'+ this.name +'_resizer_top')
905
+ .css({
906
+ 'display': 'block',
907
+ 'left': l + 'px',
908
+ 'top': t + 'px',
909
+ 'width': w + 'px',
910
+ 'height': h + 'px',
911
+ 'cursor': 'ns-resize'
912
+ })
913
+ .off('mousedown')
914
+ .on('mousedown', function(event) {
915
+ event.preventDefault()
916
+ // event before
917
+ let edata = self.trigger('resizerClick', { target: 'top', originalEvent: event })
918
+ if (edata.isCancelled === true) return
919
+ // default action
920
+ w2ui[self.name].last.events.resizeStart('top', event)
921
+ // event after
922
+ edata.finish()
923
+ return false
924
+ })
925
+ }
926
+ } else {
927
+ query(this.box).find('#layout_'+ this.name +'_panel_top').hide()
928
+ query(this.box).find('#layout_'+ this.name +'_resizer_top').hide()
929
+ }
930
+ // left if any
931
+ if (pleft != null && pleft.hidden !== true) {
932
+ l = 0
933
+ t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0)
934
+ w = pleft.sizeCalculated
935
+ h = height - (stop ? ptop.sizeCalculated + this.padding : 0) -
936
+ (sbottom ? pbottom.sizeCalculated + this.padding : 0)
937
+ query(this.box).find('#layout_'+ this.name +'_panel_left')
938
+ .css({
939
+ 'display': 'block',
940
+ 'left': l + 'px',
941
+ 'top': t + 'px',
942
+ 'width': w + 'px',
943
+ 'height': h + 'px'
944
+ })
945
+ pleft.width = w
946
+ pleft.height = h
947
+ // resizer
948
+ if (pleft.resizable) {
949
+ l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0)
950
+ w = (this.resizer > this.padding ? this.resizer : this.padding)
951
+ query(this.box).find('#layout_'+ this.name +'_resizer_left')
952
+ .css({
953
+ 'display': 'block',
954
+ 'left': l + 'px',
955
+ 'top': t + 'px',
956
+ 'width': w + 'px',
957
+ 'height': h + 'px',
958
+ 'cursor': 'ew-resize'
959
+ })
960
+ .off('mousedown')
961
+ .on('mousedown', function(event) {
962
+ event.preventDefault()
963
+ // event before
964
+ let edata = self.trigger('resizerClick', { target: 'left', originalEvent: event })
965
+ if (edata.isCancelled === true) return
966
+ // default action
967
+ w2ui[self.name].last.events.resizeStart('left', event)
968
+ // event after
969
+ edata.finish()
970
+ return false
971
+ })
972
+ }
973
+ } else {
974
+ query(this.box).find('#layout_'+ this.name +'_panel_left').hide()
975
+ query(this.box).find('#layout_'+ this.name +'_resizer_left').hide()
976
+ }
977
+ // right if any
978
+ if (pright != null && pright.hidden !== true) {
979
+ l = width - pright.sizeCalculated
980
+ t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0)
981
+ w = pright.sizeCalculated
982
+ h = height - (stop ? ptop.sizeCalculated + this.padding : 0) -
983
+ (sbottom ? pbottom.sizeCalculated + this.padding : 0)
984
+ query(this.box).find('#layout_'+ this.name +'_panel_right')
985
+ .css({
986
+ 'display': 'block',
987
+ 'left': l + 'px',
988
+ 'top': t + 'px',
989
+ 'width': w + 'px',
990
+ 'height': h + 'px'
991
+ })
992
+ pright.width = w
993
+ pright.height = h
994
+ // resizer
995
+ if (pright.resizable) {
996
+ l = l - this.padding
997
+ w = (this.resizer > this.padding ? this.resizer : this.padding)
998
+ query(this.box).find('#layout_'+ this.name +'_resizer_right')
999
+ .css({
1000
+ 'display': 'block',
1001
+ 'left': l + 'px',
1002
+ 'top': t + 'px',
1003
+ 'width': w + 'px',
1004
+ 'height': h + 'px',
1005
+ 'cursor': 'ew-resize'
1006
+ })
1007
+ .off('mousedown')
1008
+ .on('mousedown', function(event) {
1009
+ event.preventDefault()
1010
+ // event before
1011
+ let edata = self.trigger('resizerClick', { target: 'right', originalEvent: event })
1012
+ if (edata.isCancelled === true) return
1013
+ // default action
1014
+ w2ui[self.name].last.events.resizeStart('right', event)
1015
+ // event after
1016
+ edata.finish()
1017
+ return false
1018
+ })
1019
+ }
1020
+ } else {
1021
+ query(this.box).find('#layout_'+ this.name +'_panel_right').hide()
1022
+ query(this.box).find('#layout_'+ this.name +'_resizer_right').hide()
1023
+ }
1024
+ // bottom if any
1025
+ if (pbottom != null && pbottom.hidden !== true) {
1026
+ l = 0
1027
+ t = height - pbottom.sizeCalculated
1028
+ w = width
1029
+ h = pbottom.sizeCalculated
1030
+ query(this.box).find('#layout_'+ this.name +'_panel_bottom')
1031
+ .css({
1032
+ 'display': 'block',
1033
+ 'left': l + 'px',
1034
+ 'top': t + 'px',
1035
+ 'width': w + 'px',
1036
+ 'height': h + 'px'
1037
+ })
1038
+ pbottom.width = w
1039
+ pbottom.height = h
1040
+ // resizer
1041
+ if (pbottom.resizable) {
1042
+ t = t - (this.padding === 0 ? 0 : this.padding)
1043
+ h = (this.resizer > this.padding ? this.resizer : this.padding)
1044
+ query(this.box).find('#layout_'+ this.name +'_resizer_bottom')
1045
+ .css({
1046
+ 'display': 'block',
1047
+ 'left': l + 'px',
1048
+ 'top': t + 'px',
1049
+ 'width': w + 'px',
1050
+ 'height': h + 'px',
1051
+ 'cursor': 'ns-resize'
1052
+ })
1053
+ .off('mousedown')
1054
+ .on('mousedown', function(event) {
1055
+ event.preventDefault()
1056
+ // event before
1057
+ let edata = self.trigger('resizerClick', { target: 'bottom', originalEvent: event })
1058
+ if (edata.isCancelled === true) return
1059
+ // default action
1060
+ w2ui[self.name].last.events.resizeStart('bottom', event)
1061
+ // event after
1062
+ edata.finish()
1063
+ return false
1064
+ })
1065
+ }
1066
+ } else {
1067
+ query(this.box).find('#layout_'+ this.name +'_panel_bottom').hide()
1068
+ query(this.box).find('#layout_'+ this.name +'_resizer_bottom').hide()
1069
+ }
1070
+ // main - always there
1071
+ l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0)
1072
+ t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0)
1073
+ w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) -
1074
+ (sright ? pright.sizeCalculated + this.padding: 0)
1075
+ h = height - (stop ? ptop.sizeCalculated + this.padding : 0) -
1076
+ (sbottom ? pbottom.sizeCalculated + this.padding : 0) -
1077
+ (sprev ? pprev.sizeCalculated + this.padding : 0)
1078
+ query(this.box)
1079
+ .find('#layout_'+ this.name +'_panel_main')
1080
+ .css({
1081
+ 'display': 'block',
1082
+ 'left': l + 'px',
1083
+ 'top': t + 'px',
1084
+ 'width': w + 'px',
1085
+ 'height': h + 'px'
1086
+ })
1087
+ pmain.width = w
1088
+ pmain.height = h
1089
+
1090
+ // preview if any
1091
+ if (pprev != null && pprev.hidden !== true) {
1092
+ l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0)
1093
+ t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated
1094
+ w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) -
1095
+ (sright ? pright.sizeCalculated + this.padding : 0)
1096
+ h = pprev.sizeCalculated
1097
+ query(this.box).find('#layout_'+ this.name +'_panel_preview')
1098
+ .css({
1099
+ 'display': 'block',
1100
+ 'left': l + 'px',
1101
+ 'top': t + 'px',
1102
+ 'width': w + 'px',
1103
+ 'height': h + 'px'
1104
+ })
1105
+ pprev.width = w
1106
+ pprev.height = h
1107
+ // resizer
1108
+ if (pprev.resizable) {
1109
+ t = t - (this.padding === 0 ? 0 : this.padding)
1110
+ h = (this.resizer > this.padding ? this.resizer : this.padding)
1111
+ query(this.box).find('#layout_'+ this.name +'_resizer_preview')
1112
+ .css({
1113
+ 'display': 'block',
1114
+ 'left': l + 'px',
1115
+ 'top': t + 'px',
1116
+ 'width': w + 'px',
1117
+ 'height': h + 'px',
1118
+ 'cursor': 'ns-resize'
1119
+ })
1120
+ .off('mousedown')
1121
+ .on('mousedown', function(event) {
1122
+ event.preventDefault()
1123
+ // event before
1124
+ let edata = self.trigger('resizerClick', { target: 'preview', originalEvent: event })
1125
+ if (edata.isCancelled === true) return
1126
+ // default action
1127
+ w2ui[self.name].last.events.resizeStart('preview', event)
1128
+ // event after
1129
+ edata.finish()
1130
+ return false
1131
+ })
1132
+ }
1133
+ } else {
1134
+ query(this.box).find('#layout_'+ this.name +'_panel_preview').hide()
1135
+ query(this.box).find('#layout_'+ this.name +'_resizer_preview').hide()
1136
+ }
1137
+
1138
+ // resizes boxes for header, tabs, toolbar inside the panel
1139
+ this.resizeBoxes()
1140
+
1141
+ edata.finish()
1142
+ return Date.now() - time
1143
+ }
1144
+
1145
+ resizeBoxes(panel) {
1146
+ let panels = w2panels
1147
+ if (!panel && typeof panel == 'string') panels = [panel]
1148
+ // display tabs and toolbar if needed
1149
+ panels.forEach((pname, ind) => {
1150
+ let pan = this.get(w2panels[ind])
1151
+ let tmp2 = `#layout_${this.name}_panel_${pname} > `
1152
+ let topHeight = 0
1153
+ if (pan) {
1154
+ if (pan.title) {
1155
+ let el = query(this.box).find(tmp2 + '.w2ui-panel-title').css({ top: topHeight + 'px', display: 'block' })
1156
+ topHeight += w2utils.getSize(el, 'height')
1157
+ }
1158
+ if (pan.show.tabs) {
1159
+ let el = query(this.box).find(tmp2 + '[data-role="panel-tabs"]').css({ top: topHeight + 'px', display: 'block' })
1160
+ topHeight += w2utils.getSize(el, 'height')
1161
+ }
1162
+ if (pan.show.toolbar) {
1163
+ let el = query(this.box).find(tmp2 + '[data-role="panel-toolbar"]').css({ top: topHeight + 'px', display: 'block' })
1164
+ topHeight += w2utils.getSize(el, 'height')
1165
+ }
1166
+ }
1167
+ query(this.box).find(tmp2 + '[data-role="panel-content"]')
1168
+ .css({
1169
+ display: 'block',
1170
+ top: topHeight + 'px'
1171
+ })
1172
+ })
1173
+ }
1174
+
1175
+ lock(panel, msg, showSpinner) {
1176
+ if (w2panels.indexOf(panel) == -1) {
1177
+ console.log('ERROR: First parameter needs to be the a valid panel name.')
1178
+ return
1179
+ }
1180
+ let args = Array.from(arguments)
1181
+ args[0] = '#layout_'+ this.name + '_panel_' + panel
1182
+ w2utils.lock(...args)
1183
+ }
1184
+
1185
+ unlock(panel, speed) {
1186
+ if (w2panels.indexOf(panel) == -1) {
1187
+ console.log('ERROR: First parameter needs to be the a valid panel name.')
1188
+ return
1189
+ }
1190
+ let nm = '#layout_'+ this.name + '_panel_' + panel
1191
+ w2utils.unlock(nm, speed)
1192
+ }
1193
+ }
1194
+ export { w2layout }