neo.mjs 6.3.10 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/ServiceWorker.mjs +2 -2
- package/examples/ConfigurationViewport.mjs +21 -9
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/container/dialog/MainContainerController.mjs +20 -16
- package/examples/dialog/DemoDialog.mjs +24 -3
- package/examples/form/field/select/MainContainer.mjs +28 -6
- package/package.json +1 -1
- package/resources/scss/src/component/Base.scss +26 -0
- package/resources/scss/src/form/field/Picker.scss +0 -3
- package/resources/scss/src/menu/List.scss +4 -8
- package/resources/scss/theme-dark/menu/List.scss +2 -1
- package/resources/scss/theme-light/menu/List.scss +1 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/button/Base.mjs +41 -6
- package/src/component/Base.mjs +236 -44
- package/src/container/Dialog.mjs +3 -3
- package/src/core/Base.mjs +20 -0
- package/src/form/Container.mjs +2 -0
- package/src/form/field/Picker.mjs +30 -47
- package/src/form/field/Time.mjs +8 -8
- package/src/form/field/trigger/Base.mjs +1 -1
- package/src/form/field/trigger/CopyToClipboard.mjs +5 -1
- package/src/grid/View.mjs +5 -2
- package/src/grid/header/Button.mjs +10 -10
- package/src/list/Base.mjs +17 -14
- package/src/list/plugin/Animate.mjs +3 -3
- package/src/main/DomAccess.mjs +272 -28
- package/src/menu/List.mjs +35 -102
- package/src/table/Container.mjs +2 -2
- package/src/table/View.mjs +1 -0
- package/src/table/header/Button.mjs +21 -23
- package/src/tree/Accordion.mjs +1 -1
- package/src/util/Array.mjs +4 -18
- package/src/util/Css.mjs +6 -8
- package/src/util/HashHistory.mjs +10 -3
- package/src/util/Rectangle.mjs +444 -7
- package/test/siesta/siesta-node.js +2 -1
- package/test/siesta/siesta.js +1 -0
- package/test/siesta/tests/Rectangle.mjs +409 -0
package/src/main/DomAccess.mjs
CHANGED
@@ -1,6 +1,24 @@
|
|
1
1
|
import Base from '../core/Base.mjs';
|
2
2
|
import DeltaUpdates from './mixin/DeltaUpdates.mjs';
|
3
3
|
import Observable from '../core/Observable.mjs';
|
4
|
+
import Rectangle from '../util/Rectangle.mjs';
|
5
|
+
|
6
|
+
const
|
7
|
+
lengthRE = /^\d+\w+$/,
|
8
|
+
fontSizeProps = [
|
9
|
+
'font-size',
|
10
|
+
'font-size-adjust',
|
11
|
+
'font-style',
|
12
|
+
'font-weight',
|
13
|
+
'font-family',
|
14
|
+
'font-kerning',
|
15
|
+
'font-stretch',
|
16
|
+
'line-height',
|
17
|
+
'text-transform',
|
18
|
+
'text-decoration',
|
19
|
+
'letter-spacing',
|
20
|
+
'word-break'
|
21
|
+
];
|
4
22
|
|
5
23
|
/**
|
6
24
|
* @class Neo.main.DomAccess
|
@@ -44,12 +62,14 @@ class DomAccess extends Base {
|
|
44
62
|
remote: {
|
45
63
|
app: [
|
46
64
|
'addScript',
|
65
|
+
'align',
|
47
66
|
'applyBodyCls',
|
48
67
|
'blur',
|
49
68
|
'execCommand',
|
50
69
|
'focus',
|
51
70
|
'getAttributes',
|
52
71
|
'getBoundingClientRect',
|
72
|
+
'measure',
|
53
73
|
'scrollBy',
|
54
74
|
'scrollIntoView',
|
55
75
|
'scrollTo',
|
@@ -82,10 +102,13 @@ class DomAccess extends Base {
|
|
82
102
|
construct(config) {
|
83
103
|
super.construct(config);
|
84
104
|
|
85
|
-
|
86
|
-
|
105
|
+
const
|
106
|
+
me = this,
|
107
|
+
syncAligns = me.syncAligns.bind(me);
|
87
108
|
|
88
109
|
if (Neo.config.renderCountDeltas) {
|
110
|
+
let node;
|
111
|
+
|
89
112
|
setInterval(() => {
|
90
113
|
node = document.getElementById('neo-delta-updates');
|
91
114
|
|
@@ -94,8 +117,58 @@ class DomAccess extends Base {
|
|
94
117
|
}
|
95
118
|
|
96
119
|
me.countDeltasPer250ms = 0;
|
97
|
-
}, 250)
|
120
|
+
}, 250)
|
98
121
|
}
|
122
|
+
|
123
|
+
// Set up our aligning callback which is called when things change which may
|
124
|
+
// mean that alignments need to be updated.
|
125
|
+
me.syncAligns = () => requestAnimationFrame(syncAligns);
|
126
|
+
}
|
127
|
+
|
128
|
+
/**
|
129
|
+
* @param {Object} alignSpec
|
130
|
+
*/
|
131
|
+
addAligned(alignSpec) {
|
132
|
+
const
|
133
|
+
me = this,
|
134
|
+
{ id } = alignSpec,
|
135
|
+
aligns = me._aligns || (me._aligns = new Map()),
|
136
|
+
resizeObserver = me._alignResizeObserver || (me._alignResizeObserver = new ResizeObserver(me.syncAligns)),
|
137
|
+
{ constrainToElement } = alignSpec;
|
138
|
+
|
139
|
+
// Set up listeners which monitor for changes
|
140
|
+
if (!aligns.has(id)) {
|
141
|
+
// Realign when target's layout-controlling element changes size
|
142
|
+
resizeObserver.observe(alignSpec.offsetParent);
|
143
|
+
|
144
|
+
// Realign when align to target changes size
|
145
|
+
resizeObserver.observe(alignSpec.targetElement);
|
146
|
+
|
147
|
+
// Realign when constraining element changes size
|
148
|
+
if (constrainToElement) {
|
149
|
+
resizeObserver.observe(constrainToElement);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
if (!me.hasDocumentScrollListener) {
|
154
|
+
document.addEventListener('scroll', me.syncAligns, {
|
155
|
+
capture: true,
|
156
|
+
passive: true
|
157
|
+
});
|
158
|
+
|
159
|
+
me.hasDocumentScrollListener = true;
|
160
|
+
}
|
161
|
+
|
162
|
+
if (!me.documentMutationObserver) {
|
163
|
+
me.documentMutationObserver = new MutationObserver(me.onDocumentMutation.bind(me));
|
164
|
+
|
165
|
+
me.documentMutationObserver.observe(document.body, {
|
166
|
+
childList: true,
|
167
|
+
subtree : true
|
168
|
+
})
|
169
|
+
}
|
170
|
+
|
171
|
+
aligns.set(id, alignSpec)
|
99
172
|
}
|
100
173
|
|
101
174
|
/**
|
@@ -116,6 +189,58 @@ class DomAccess extends Base {
|
|
116
189
|
document.head.appendChild(script);
|
117
190
|
}
|
118
191
|
|
192
|
+
/**
|
193
|
+
* @param {Object} data
|
194
|
+
* @returns {Promise<void>}
|
195
|
+
*/
|
196
|
+
async align(data) {
|
197
|
+
const
|
198
|
+
me = this,
|
199
|
+
{ constrainTo } = data,
|
200
|
+
subject = data.subject = me.getElement(data.id),
|
201
|
+
{ style } = subject,
|
202
|
+
align = {...data},
|
203
|
+
lastAlign = me._aligns?.get(data.id);
|
204
|
+
|
205
|
+
if (lastAlign) {
|
206
|
+
subject.classList.remove(`neo-aligned-${lastAlign.result.position}`);
|
207
|
+
}
|
208
|
+
|
209
|
+
// Release any constrainTo or matchSize sizing which may have been imposed
|
210
|
+
// by a previous align call.
|
211
|
+
me.resetDimensions(align);
|
212
|
+
|
213
|
+
// The Rectangle's align spec target and constrainTo must be Rectangles
|
214
|
+
align.target = me.getBoundingClientRect({ id : data.targetElement = me.getElementOrBody(data.target) });
|
215
|
+
data.offsetParent = data.targetElement.offsetParent
|
216
|
+
if (constrainTo) {
|
217
|
+
align.constrainTo = me.getBoundingClientRect({ id : data.constrainToElement = me.getElementOrBody(constrainTo) });
|
218
|
+
}
|
219
|
+
|
220
|
+
// Get an aligned clone of myRect aligned according to the align object
|
221
|
+
const
|
222
|
+
myRect = me.getBoundingClientRect(data),
|
223
|
+
result = data.result = myRect.alignTo(align);
|
224
|
+
|
225
|
+
Object.assign(style, {
|
226
|
+
top : 0,
|
227
|
+
left : 0,
|
228
|
+
transform : `translate(${result.x}px,${result.y}px)`
|
229
|
+
});
|
230
|
+
if (result.width !== myRect.width) {
|
231
|
+
style.width = `${result.width}px`;
|
232
|
+
}
|
233
|
+
if (result.height !== myRect.height) {
|
234
|
+
style.height = `${result.height}px`;
|
235
|
+
}
|
236
|
+
|
237
|
+
// Place box shadow at correct edge
|
238
|
+
subject.classList.add(`neo-aligned-${result.position}`);
|
239
|
+
|
240
|
+
// Register an alignment to be kept in sync
|
241
|
+
me.addAligned(data);
|
242
|
+
}
|
243
|
+
|
119
244
|
/**
|
120
245
|
* @param {Object} data
|
121
246
|
* @param {String[]} data.cls
|
@@ -170,7 +295,7 @@ class DomAccess extends Base {
|
|
170
295
|
* @param {Object} data
|
171
296
|
* @param {Array|String} data.id either an id or an array of ids
|
172
297
|
* @param {Array|String} data.attributes either an attribute or an array of attributes
|
173
|
-
* @returns {Array|Object} In case id is an array, an array of
|
298
|
+
* @returns {Array|Object} In case id is an array, an array of attribute objects is returned, otherwise an object
|
174
299
|
*/
|
175
300
|
getAttributes(data) {
|
176
301
|
let returnData;
|
@@ -220,54 +345,73 @@ class DomAccess extends Base {
|
|
220
345
|
});
|
221
346
|
} else {
|
222
347
|
let node = this.getElementOrBody(data.id),
|
223
|
-
rect = {};
|
348
|
+
rect = {}, style, minWidth, minHeight;
|
224
349
|
|
225
350
|
returnData = {};
|
226
351
|
|
227
352
|
if (node) {
|
228
|
-
rect
|
353
|
+
rect = node.getBoundingClientRect();
|
354
|
+
style = node.ownerDocument.defaultView.getComputedStyle(node);
|
355
|
+
minWidth = style.getPropertyValue('min-width'),
|
356
|
+
minHeight = style.getPropertyValue('min-height');
|
229
357
|
|
230
358
|
// DomRect does not support spreading => {...DomRect} => {}
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
359
|
+
returnData = Rectangle.clone(rect);
|
360
|
+
|
361
|
+
// Measure minWidth/minHeight in other units like em/rem etc
|
362
|
+
// Note that 0px is what the DOM reports if no minWidth is specified
|
363
|
+
// so we do not report a minimum in these cases.
|
364
|
+
if (lengthRE.test(minWidth) && minWidth !== '0px') {
|
365
|
+
returnData.minWidth = this.measure({ value : minWidth, id : node});
|
366
|
+
}
|
367
|
+
if (lengthRE.test(minHeight) && minHeight !== '0px') {
|
368
|
+
returnData.minHeight = this.measure({ value : minHeight, id : node });
|
369
|
+
}
|
241
370
|
}
|
242
371
|
}
|
243
372
|
|
244
373
|
return returnData;
|
245
374
|
}
|
246
375
|
|
376
|
+
onDocumentMutation(mutations) {
|
377
|
+
const me = this;
|
378
|
+
|
379
|
+
// If the mutations are purely align subjects being added or removed, take no action.
|
380
|
+
if (!mutations.every(({ type, addedNodes, removedNodes }) => {
|
381
|
+
if (type === 'childList') {
|
382
|
+
const nodes = [...Array.from(addedNodes), ...Array.from(removedNodes)];
|
383
|
+
|
384
|
+
return nodes.every(a => me.isAlignSubject(a))
|
385
|
+
}
|
386
|
+
})) {
|
387
|
+
me.syncAligns();
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
247
391
|
/**
|
248
|
-
* @param {String} nodeId
|
392
|
+
* @param {String|HTMLElement} nodeId
|
249
393
|
* @returns {HTMLElement}
|
250
394
|
* @protected
|
251
395
|
*/
|
252
396
|
getElement(nodeId) {
|
253
|
-
|
254
|
-
return document.getElementById(nodeId);
|
255
|
-
}
|
256
|
-
|
257
|
-
return document.querySelector(`[data-neo-id='${nodeId}']`);
|
397
|
+
return nodeId.nodeType ? nodeId : Neo.config.useDomIds ? document.getElementById(nodeId) : document.querySelector(`[data-neo-id='${nodeId}']`);
|
258
398
|
}
|
259
399
|
|
260
400
|
/**
|
261
|
-
* @param {String} [nodeId='document.body']
|
401
|
+
* @param {String|HTMLElement} [nodeId='document.body']
|
262
402
|
* @returns {HTMLElement}
|
263
403
|
* @protected
|
264
404
|
*/
|
265
405
|
getElementOrBody(nodeId='document.body') {
|
266
|
-
|
267
|
-
|
268
|
-
}
|
406
|
+
return nodeId.nodeType ? nodeId : (nodeId === 'body' || nodeId === 'document.body') ? document.body : this.getElement(nodeId);
|
407
|
+
}
|
269
408
|
|
270
|
-
|
409
|
+
/**
|
410
|
+
* @param {HTMLElement} el
|
411
|
+
* @returns {Boolean}
|
412
|
+
*/
|
413
|
+
isAlignSubject(el) {
|
414
|
+
return [...this._aligns?.values()].some(align => align.subject === el);
|
271
415
|
}
|
272
416
|
|
273
417
|
/**
|
@@ -313,7 +457,53 @@ class DomAccess extends Base {
|
|
313
457
|
});
|
314
458
|
|
315
459
|
document.head.appendChild(link);
|
316
|
-
})
|
460
|
+
})
|
461
|
+
}
|
462
|
+
|
463
|
+
/**
|
464
|
+
* @param {Object} data
|
465
|
+
* @param {String} data.id
|
466
|
+
* @param {Number|String} data.value
|
467
|
+
* @returns {Number|String}
|
468
|
+
*/
|
469
|
+
measure({ value, id }) {
|
470
|
+
const node = id.nodeType === 1 ? id : this.getElement(id);
|
471
|
+
|
472
|
+
if (value.endsWith('%')) {
|
473
|
+
const fraction = parseFloat(value) / 100;
|
474
|
+
|
475
|
+
return (node.offsetParent?.getBoundingClientRect().height || 0) * fraction;
|
476
|
+
}
|
477
|
+
// If it's any other CSS unit than px, it needs to be measured using the DOM
|
478
|
+
else if (isNaN(value) && !value.endsWith('px')) {
|
479
|
+
const elStyle = node.ownerDocument.defaultView.getComputedStyle(node);
|
480
|
+
|
481
|
+
let d = this._measuringDiv;
|
482
|
+
|
483
|
+
if (!d) {
|
484
|
+
d = this._measuringDiv = document.createElement('div');
|
485
|
+
d.style = 'position:fixed;top:-10000px;left:-10000px';
|
486
|
+
}
|
487
|
+
// In case a DOM update cleared it out
|
488
|
+
document.body.appendChild(d);
|
489
|
+
|
490
|
+
// Set all the font-size, font-weight etc style properties so that
|
491
|
+
// em/ex/rem etc units will match
|
492
|
+
fontSizeProps.forEach(prop => {
|
493
|
+
d.style[prop] = elStyle[prop];
|
494
|
+
});
|
495
|
+
d.className = node.className;
|
496
|
+
d.style.width = value;
|
497
|
+
|
498
|
+
// Read back the resulting computed pixel width
|
499
|
+
value = elStyle.width;
|
500
|
+
|
501
|
+
}
|
502
|
+
// If it's a number, or ends with px, use the numeric value.
|
503
|
+
else {
|
504
|
+
value = parseFloat(value);
|
505
|
+
}
|
506
|
+
return value;
|
317
507
|
}
|
318
508
|
|
319
509
|
/**
|
@@ -419,6 +609,24 @@ class DomAccess extends Base {
|
|
419
609
|
}
|
420
610
|
}
|
421
611
|
|
612
|
+
/**
|
613
|
+
* Resets any DOM sizing configs to the last externally configured value.
|
614
|
+
*
|
615
|
+
* This is used during aligning to release any constraints applied by a previous alignment.
|
616
|
+
* @protected
|
617
|
+
*/
|
618
|
+
async resetDimensions(align) {
|
619
|
+
const { style } = this.getElement(align.id);
|
620
|
+
|
621
|
+
style.flex = align.configuredFlex;
|
622
|
+
style.width = align.configuredWidth;
|
623
|
+
style.height = align.configuredHeight;
|
624
|
+
style.minWidth = align.configuredMinWidth;
|
625
|
+
style.minHeight = align.configuredMinHeight;
|
626
|
+
style.maxWidth = align.configuredMaxWidth;
|
627
|
+
style.maxHeight = align.configuredMaxHeight;
|
628
|
+
}
|
629
|
+
|
422
630
|
/**
|
423
631
|
* @param {Object} data
|
424
632
|
* @param {String} data.direction left, top
|
@@ -555,6 +763,42 @@ class DomAccess extends Base {
|
|
555
763
|
return {id: data.id};
|
556
764
|
}
|
557
765
|
|
766
|
+
/**
|
767
|
+
*
|
768
|
+
*/
|
769
|
+
syncAligns() {
|
770
|
+
const
|
771
|
+
me = this,
|
772
|
+
{ _aligns } = me;
|
773
|
+
|
774
|
+
// Keep all registered aligns aligned on any detected change
|
775
|
+
_aligns?.forEach(align => {
|
776
|
+
// Align subject and target still in the DOM - correct its alignment
|
777
|
+
if (document.contains(align.subject) && document.contains(align.targetElement)) {
|
778
|
+
me.align(align);
|
779
|
+
}
|
780
|
+
// Align subject or target no longer in the DOM - remove it.
|
781
|
+
else {
|
782
|
+
const
|
783
|
+
{ _alignResizeObserver } = me,
|
784
|
+
{ constrainToElement } = align;
|
785
|
+
|
786
|
+
// Stop observing the align elements
|
787
|
+
_alignResizeObserver.unobserve(align.subject);
|
788
|
+
_alignResizeObserver.unobserve(align.offsetParent);
|
789
|
+
_alignResizeObserver.unobserve(align.targetElement);
|
790
|
+
if (constrainToElement) {
|
791
|
+
_alignResizeObserver.unobserve(constrainToElement);
|
792
|
+
}
|
793
|
+
|
794
|
+
// Clear the last aligned class.
|
795
|
+
align.subject.classList.remove(`neo-aligned-${align.result?.position}`);
|
796
|
+
|
797
|
+
_aligns.delete(align.id);
|
798
|
+
}
|
799
|
+
})
|
800
|
+
}
|
801
|
+
|
558
802
|
/**
|
559
803
|
* @param {Object} data
|
560
804
|
* @param {String} [data.behavior='smooth'] // auto or smooth
|
package/src/menu/List.mjs
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import BaseList from '../list/Base.mjs';
|
2
2
|
import ListModel from '../selection/menu/ListModel.mjs';
|
3
|
-
import NeoArray from '../util/Array.mjs';
|
4
3
|
import Store from './Store.mjs';
|
5
4
|
|
6
5
|
/**
|
@@ -28,11 +27,6 @@ class List extends BaseList {
|
|
28
27
|
* @member {String[]} baseCls=['neo-menu-list','neo-list']
|
29
28
|
*/
|
30
29
|
baseCls: ['neo-menu-list', 'neo-list'],
|
31
|
-
/**
|
32
|
-
* True will add 'neo-floating' to the instance cls list.
|
33
|
-
* @member {Boolean} floating_=false
|
34
|
-
*/
|
35
|
-
floating_: false,
|
36
30
|
/**
|
37
31
|
* setTimeout() id after a focus-leave event.
|
38
32
|
* @member {Number|null} focusTimeoutId=null
|
@@ -115,19 +109,6 @@ class List extends BaseList {
|
|
115
109
|
*/
|
116
110
|
parentComponent = null
|
117
111
|
|
118
|
-
/**
|
119
|
-
* Triggered after the floating config got changed
|
120
|
-
* @param {Object[]} value
|
121
|
-
* @param {Object[]} oldValue
|
122
|
-
* @protected
|
123
|
-
*/
|
124
|
-
afterSetFloating(value, oldValue) {
|
125
|
-
let cls = this.cls;
|
126
|
-
|
127
|
-
NeoArray[value ? 'add' : 'remove'](cls, 'neo-floating');
|
128
|
-
this.cls = cls
|
129
|
-
}
|
130
|
-
|
131
112
|
/**
|
132
113
|
* Triggered after the items config got changed
|
133
114
|
* @param {Object[]} value
|
@@ -168,40 +149,17 @@ class List extends BaseList {
|
|
168
149
|
}
|
169
150
|
|
170
151
|
/**
|
171
|
-
* Triggered after the
|
172
|
-
* @param {
|
173
|
-
* @param {
|
152
|
+
* Triggered after the theme config got changed
|
153
|
+
* @param {String|null} value
|
154
|
+
* @param {String|null} oldValue
|
174
155
|
* @protected
|
175
156
|
*/
|
176
|
-
|
177
|
-
super.
|
157
|
+
afterSetTheme(value, oldValue) {
|
158
|
+
super.afterSetTheme(value, oldValue);
|
178
159
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
if (parentId) {
|
184
|
-
if (value) {
|
185
|
-
Neo.main.addon.ScrollSync.register({
|
186
|
-
sourceId: parentId,
|
187
|
-
targetId: id
|
188
|
-
});
|
189
|
-
|
190
|
-
!me.parentMenu && me.getDomRect([id, parentId]).then(rects => {
|
191
|
-
let style = me.style || {};
|
192
|
-
|
193
|
-
style.left = `${rects[1].right - rects[0].width}px`;
|
194
|
-
style.top = `${rects[1].bottom + 1}px`;
|
195
|
-
|
196
|
-
me.style = style
|
197
|
-
})
|
198
|
-
} else if (oldValue !== undefined) {
|
199
|
-
Neo.main.addon.ScrollSync.unregister({
|
200
|
-
sourceId: parentId,
|
201
|
-
targetId: id
|
202
|
-
})
|
203
|
-
}
|
204
|
-
}
|
160
|
+
Object.values(this.subMenuMap || {}).forEach(menu => {
|
161
|
+
menu.theme = value
|
162
|
+
})
|
205
163
|
}
|
206
164
|
|
207
165
|
/**
|
@@ -243,9 +201,7 @@ class List extends BaseList {
|
|
243
201
|
destroy(...args) {
|
244
202
|
let me = this,
|
245
203
|
activeSubMenu = me.activeSubMenu,
|
246
|
-
subMenuMap = me.subMenuMap;
|
247
|
-
|
248
|
-
me.store.destroy();
|
204
|
+
subMenuMap = me.subMenuMap || {};
|
249
205
|
|
250
206
|
activeSubMenu?.unmount();
|
251
207
|
|
@@ -335,16 +291,6 @@ class List extends BaseList {
|
|
335
291
|
}
|
336
292
|
}
|
337
293
|
|
338
|
-
/**
|
339
|
-
* @param {Object} node
|
340
|
-
* @param {Object} data
|
341
|
-
*/
|
342
|
-
onItemClick(node, data) {
|
343
|
-
super.onItemClick(node, data);
|
344
|
-
|
345
|
-
this.onKeyDownEnter(node.id)
|
346
|
-
}
|
347
|
-
|
348
294
|
/**
|
349
295
|
* @param {String} nodeId
|
350
296
|
*/
|
@@ -401,48 +347,35 @@ class List extends BaseList {
|
|
401
347
|
* @param {Object} record
|
402
348
|
*/
|
403
349
|
showSubMenu(nodeId, record) {
|
404
|
-
|
350
|
+
const
|
351
|
+
me = this,
|
405
352
|
store = me.store,
|
406
353
|
recordId = record[store.keyProperty],
|
407
|
-
subMenuMap = me.subMenuMap || {},
|
354
|
+
subMenuMap = me.subMenuMap || (me.subMenuMap = {}),
|
408
355
|
subMenuMapId = me.getMenuMapId(recordId),
|
409
|
-
subMenu = subMenuMap[subMenuMapId]
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
parentComponent: me.parentComponent,
|
433
|
-
parentId : Neo.apps[me.appName].mainView.id,
|
434
|
-
parentIndex : store.indexOf(record),
|
435
|
-
parentMenu : me,
|
436
|
-
style,
|
437
|
-
zIndex : me.zIndex + 1
|
438
|
-
})
|
439
|
-
}
|
440
|
-
|
441
|
-
me.activeSubMenu = subMenu;
|
442
|
-
me.subMenuMap = subMenuMap;
|
443
|
-
|
444
|
-
subMenu.render(true)
|
445
|
-
});
|
356
|
+
subMenu = subMenuMap[subMenuMapId] || (subMenuMap[subMenuMapId] = Neo.create({
|
357
|
+
align : {
|
358
|
+
target : nodeId,
|
359
|
+
edgeAlign : 'l0-r0',
|
360
|
+
axisLock : true,
|
361
|
+
targetMargin : me.subMenuGap
|
362
|
+
},
|
363
|
+
module : List,
|
364
|
+
appName : me.appName,
|
365
|
+
displayField : me.displayField,
|
366
|
+
floating : true,
|
367
|
+
items : record.items,
|
368
|
+
isRoot : false,
|
369
|
+
parentComponent: me.parentComponent,
|
370
|
+
parentId : Neo.apps[me.appName].mainView.id,
|
371
|
+
parentIndex : store.indexOf(record),
|
372
|
+
parentMenu : me,
|
373
|
+
theme : me.theme,
|
374
|
+
zIndex : me.zIndex + 1
|
375
|
+
}));
|
376
|
+
|
377
|
+
me.activeSubMenu = subMenu;
|
378
|
+
subMenu.render(true)
|
446
379
|
}
|
447
380
|
|
448
381
|
/**
|
package/src/table/Container.mjs
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import BaseContainer from '../container/Base.mjs';
|
2
2
|
import ClassSystemUtil from '../util/ClassSystem.mjs';
|
3
|
-
import
|
3
|
+
import CssUtil from '../util/Css.mjs';
|
4
4
|
import NeoArray from '../util/Array.mjs';
|
5
5
|
import RowModel from '../selection/table/RowModel.mjs';
|
6
6
|
import Store from '../data/Store.mjs';
|
@@ -207,7 +207,7 @@ class Container extends BaseContainer {
|
|
207
207
|
cssRules.push('#' + id + '::-webkit-scrollbar-track:horizontal {margin-right: ' + me.dockRightMargin + 'px;}');
|
208
208
|
}
|
209
209
|
if (cssRules.length > 0) {
|
210
|
-
|
210
|
+
CssUtil.insertRules(me.appName, cssRules);
|
211
211
|
}
|
212
212
|
|
213
213
|
me.scrollbarsCssApplied = true;
|