neo.mjs 5.6.12 → 5.7.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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.6.12'
23
+ * @member {String} version='5.7.0'
24
24
  */
25
- version: '5.6.12'
25
+ version: '5.7.0'
26
26
  }
27
27
 
28
28
  /**
@@ -3,6 +3,6 @@
3
3
  "basePath" : "../../",
4
4
  "environment" : "development",
5
5
  "mainPath" : "./Main.mjs",
6
- "mainThreadAddons": ["AmCharts", "DragDrop", "MapboxGL", "Stylesheet"],
6
+ "mainThreadAddons": ["AmCharts", "DragDrop", "MapboxGL", "ScrollSync", "Stylesheet"],
7
7
  "themes" : ["neo-theme-dark", "neo-theme-light"]
8
8
  }
@@ -21,6 +21,10 @@ class FormPageContainer extends FormContainer {
21
21
  * @member {Object} layout={ntype:'vbox'}
22
22
  */
23
23
  layout: {ntype: 'vbox'},
24
+ /**
25
+ * @member {Object} style={overflow:'auto'}
26
+ */
27
+ style: {overflow: 'auto'},
24
28
  /**
25
29
  * @member {Object} _vdom
26
30
  */
@@ -18,7 +18,8 @@ class Page2 extends FormPageContainer {
18
18
  items: [{
19
19
  module : DateField,
20
20
  labelText: 'Birthday',
21
- name : 'birthday'
21
+ name : 'birthday',
22
+ style : {marginBottom: '800px', marginTop: '800px'}
22
23
  }]
23
24
  }
24
25
  }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.6.12'
23
+ * @member {String} version='5.7.0'
24
24
  */
25
- version: '5.6.12'
25
+ version: '5.7.0'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.6.12",
3
+ "version": "5.7.0",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -236,12 +236,12 @@ const DefaultConfig = {
236
236
  useVdomWorker: true,
237
237
  /**
238
238
  * buildScripts/injectPackageVersion.mjs will update this value
239
- * @default '5.6.12'
239
+ * @default '5.7.0'
240
240
  * @memberOf! module:Neo
241
241
  * @name config.version
242
242
  * @type String
243
243
  */
244
- version: '5.6.12'
244
+ version: '5.7.0'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
package/src/Main.mjs CHANGED
@@ -431,14 +431,22 @@ class Main extends core.Base {
431
431
  }
432
432
 
433
433
  /**
434
- * Open a new popup window
434
+ * Open a new popup window and return if successfull
435
435
  * @param {Object} data
436
436
  * @param {String} data.url
437
437
  * @param {String} data.windowFeatures
438
438
  * @param {String} data.windowName
439
- */
439
+ * @return {Boolean}
440
+ */
440
441
  windowOpen(data) {
441
- this.openWindows[data.windowName] = window.open(data.url, data.windowName, data.windowFeatures);
442
+ let openedWindow = window.open(data.url, data.windowName, data.windowFeatures),
443
+ success = !!openedWindow;
444
+
445
+ if (success) {
446
+ this.openWindows[data.windowName] = openedWindow;
447
+ }
448
+
449
+ return success;
442
450
  }
443
451
 
444
452
  /**
@@ -1,6 +1,10 @@
1
- import Base from '../../core/Base.mjs';
1
+ import Base from '../../core/Base.mjs';
2
+ import DomEvents from '../DomEvents.mjs'
2
3
 
3
4
  /**
5
+ * This addon keeps the position of overlays in sync with an anchor element,
6
+ * when scrolling inside any parent node.
7
+ * A prominent use case is Neo.form.field.Picker.
4
8
  * @class Neo.main.addon.ScrollSync
5
9
  * @extends Neo.core.Base
6
10
  * @singleton
@@ -31,70 +35,112 @@ class ScrollSync extends Base {
31
35
  }
32
36
 
33
37
  /**
34
- * @member {Object} items=[]
38
+ * @member {Object} sourceMap={}
35
39
  * @protected
36
40
  */
37
- items = []
41
+ sourceMap = {}
38
42
 
39
43
  /**
40
- * @param {Object} data
41
- * @param {String} data.sourceId
42
- * @param {String} data.targetId
44
+ * @param {Object} config
43
45
  */
44
- register(data) {
45
- let me = this,
46
- items = me.items,
47
- sourceId = data.sourceId,
48
- targetId = data.targetId;
49
-
50
- // ensure that there are no duplicate entries
51
- me.removeItem(sourceId, targetId);
52
-
53
- items.push({
54
- source: {id: sourceId},
55
- target: {id: targetId}
56
- })
46
+ construct(config = {}) {
47
+ super.construct(config);
57
48
 
58
- console.log('register', data, items)
49
+ document.addEventListener('scroll', this.onDocumentScroll.bind(this), true)
59
50
  }
60
51
 
61
52
  /**
62
- * @param {String} sourceId
63
- * @param {String} targetId
64
- * @returns {Boolean}
53
+ * @param {Event} event
54
+ */
55
+ onDocumentScroll(event) {
56
+ let me = this,
57
+ scrollNode = event.target,
58
+ sourceRect, targetNode;
59
+
60
+ me.sourceMap[scrollNode.id]?.forEach(item => {
61
+ sourceRect = document.getElementById(item.sourceId).getBoundingClientRect();
62
+ targetNode = document.getElementById(item.targetId)
63
+
64
+ targetNode.style.left = `${sourceRect.x + item.deltaX}px`;
65
+ targetNode.style.top = `${sourceRect.y + item.deltaY}px`
66
+ })
67
+ }
68
+
69
+ /**
70
+ * @param {Object} data
71
+ * @param {String} data.sourceId
72
+ * @param {String} data.targetId
73
+ * @returns Promise<Boolean>
65
74
  */
66
- removeItem(sourceId, targetId) {
67
- let items = this.items,
68
- i = 0,
69
- len = items.length,
70
- item;
71
-
72
- for (; i < len; i++) {
73
- item = items[i];
74
-
75
- if (item.source.id === sourceId && item.target.id === targetId) {
76
- items.splice(i, 1);
77
- return true
75
+ async register(data) {
76
+ // short delay to ensure the target node got mounted
77
+ await Neo.timeout(50)
78
+
79
+ let sourceId = data.sourceId,
80
+ sourceMap = this.sourceMap,
81
+ sourceNode = document.getElementById(sourceId),
82
+ sourceRect = sourceNode.getBoundingClientRect(),
83
+ parentNode = sourceNode.parentNode,
84
+ targetId = data.targetId,
85
+ targetRect = document.getElementById(targetId).getBoundingClientRect(),
86
+ deltaX = targetRect.x - sourceRect.x,
87
+ deltaY = targetRect.y - sourceRect.y,
88
+ overflowX, overflowY, parentId;
89
+
90
+ while (parentNode && parentNode.id) {
91
+ parentId = parentNode.id;
92
+
93
+ ({overflowX, overflowY} = getComputedStyle(parentNode))
94
+
95
+ if (overflowX === 'auto' || overflowX === 'scroll' || overflowY === 'auto' || overflowY === 'scroll') {
96
+ if (!sourceMap[parentId]) {
97
+ sourceMap[parentId] = []
98
+ }
99
+
100
+ sourceMap[parentId].push({deltaX, deltaY, sourceId, targetId})
78
101
  }
102
+
103
+ parentNode = parentNode.parentNode
79
104
  }
80
105
 
81
- return false
106
+ return true
82
107
  }
83
108
 
84
109
  /**
85
110
  * @param {Object} data
86
111
  * @param {String} data.sourceId
87
112
  * @param {String} data.targetId
113
+ * @returns {Boolean}
88
114
  */
89
115
  unregister(data) {
90
- this.removeItem(data.sourceId, data.targetId)
91
- }
92
- }
116
+ let sourceId = data.sourceId,
117
+ sourceMap = this.sourceMap,
118
+ sourceNode = document.getElementById(sourceId),
119
+ parentNode = sourceNode.parentNode,
120
+ parentId;
93
121
 
94
- Neo.applyClassConfig(ScrollSync);
122
+ while (parentNode && parentNode.id) {
123
+ parentId = parentNode.id;
95
124
 
96
- let instance = Neo.create(ScrollSync);
125
+ if (sourceMap[parentId]) {
126
+ [...sourceMap[parentId]].forEach((item, index) => {
127
+ if (item.sourceId === sourceId && item.targetId === data.targetId) {
128
+ sourceMap[parentId].splice(index, 1)
129
+ }
130
+ })
131
+
132
+ if (sourceMap[parentId].length < 1) {
133
+ delete sourceMap[parentId]
134
+ }
135
+ }
136
+
137
+ parentNode = parentNode.parentNode
138
+ }
139
+
140
+ return true
141
+ }
142
+ }
97
143
 
98
- Neo.applyToGlobalNs(instance);
144
+ let instance = Neo.applyClassConfig(ScrollSync);
99
145
 
100
146
  export default instance;