neo.mjs 3.0.1 → 3.0.5

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.
@@ -32,13 +32,15 @@ class List extends BaseList {
32
32
  * @returns {Object|Object[]|String} Either a config object to assign to the item, a vdom cn array or a html string
33
33
  */
34
34
  createItemContent(record, index) {
35
+ let id = this.getItemId(record.id);
36
+
35
37
  return [
36
- {cls: ['neo-list-item-content'], cn: [
37
- {tag: 'img', src: `../../../resources/examples/${record.image}`},
38
- {cls: ['neo-list-item-text'], cn: [
39
- {html: record.firstname},
40
- {cls: ['neo-lastname'], html: record.lastname},
41
- {cls: ['neo-is-online'], removeDom: !record.isOnline}
38
+ {cls: ['neo-list-item-content'], id: `${id}__content`, cn: [
39
+ {tag: 'img', id: `${id}__image`, src: `${Neo.config.resourcesPath}examples/${record.image}`},
40
+ {cls: ['neo-list-item-text'], id: `${id}__content_wrapper`, cn: [
41
+ {html: record.firstname, id: `${id}__firstname`},
42
+ {cls: ['neo-lastname'], id: `${id}__lastname`, html: record.lastname},
43
+ {cls: ['neo-is-online'], id: `${id}__isonline`, removeDom: !record.isOnline}
42
44
  ]}
43
45
  ]}
44
46
  ];
@@ -1,8 +1,10 @@
1
- import CheckBox from '../../../src/form/field/CheckBox.mjs';
2
- import List from './List.mjs';
3
- import MainStore from './MainStore.mjs';
4
- import Toolbar from '../../../src/container/Toolbar.mjs';
5
- import Viewport from '../../../src/container/Viewport.mjs';
1
+ import CheckBox from '../../../src/form/field/CheckBox.mjs';
2
+ import List from './List.mjs';
3
+ import MainStore from './MainStore.mjs';
4
+ import NumberField from '../../../src/form/field/Number.mjs';
5
+ import TextField from '../../../src/form/field/Text.mjs';
6
+ import Toolbar from '../../../src/container/Toolbar.mjs';
7
+ import Viewport from '../../../src/container/Viewport.mjs';
6
8
 
7
9
  /**
8
10
  * @class Neo.examples.list.animate.MainContainer
@@ -12,7 +14,8 @@ class MainContainer extends Viewport {
12
14
  static getConfig() {return {
13
15
  className: 'Neo.examples.list.animate.MainContainer',
14
16
  autoMount: true,
15
- layout : {ntype: 'vbox', align: 'stretch'}
17
+ layout : {ntype: 'vbox', align: 'stretch'},
18
+ sortBy : 'firstname'
16
19
  }}
17
20
 
18
21
  /**
@@ -36,11 +39,16 @@ class MainContainer extends Viewport {
36
39
  ntype: 'label',
37
40
  text : 'Sort by'
38
41
  }, {
39
- handler: me.changeSorting.bind(me, 'firstname'),
40
- text : 'Firstname'
42
+ field : 'firstname',
43
+ handler : me.changeSorting.bind(me, 'firstname'),
44
+ iconCls : 'fas fa-arrow-circle-up',
45
+ iconPosition: 'right',
46
+ text : 'Firstname'
41
47
  }, {
42
- handler: me.changeSorting.bind(me, 'lastname'),
43
- text : 'Lastname'
48
+ field : 'lastname',
49
+ handler : me.changeSorting.bind(me, 'lastname'),
50
+ iconPosition: 'right',
51
+ text : 'Lastname'
44
52
  }, {
45
53
  module : CheckBox,
46
54
  labelText : 'Is online',
@@ -48,6 +56,27 @@ class MainContainer extends Viewport {
48
56
  listeners : {change: me.changeIsOnlineFilter.bind(me)},
49
57
  style : {marginLeft: '50px'}
50
58
  }]
59
+ }, {
60
+ module : TextField,
61
+ flex : 'none',
62
+ labelText : 'Search',
63
+ labelWidth: 60,
64
+ listeners : {change: me.changeNameFilter.bind(me)},
65
+ style : {marginLeft: '10px'},
66
+ width : 262
67
+ }, {
68
+ module : NumberField,
69
+ clearToOriginalValue: true,
70
+ flex : 'none',
71
+ labelText : 'Transition Duration',
72
+ labelWidth : 150,
73
+ listeners : {change: me.changeTransitionDuration.bind(me)},
74
+ maxValue : 5000,
75
+ minValue : 100,
76
+ stepSize : 100,
77
+ style : {marginLeft: '10px'},
78
+ value : 500,
79
+ width : 262
51
80
  }, {
52
81
  module: List,
53
82
  store : MainStore
@@ -64,13 +93,48 @@ class MainContainer extends Viewport {
64
93
  }
65
94
 
66
95
  /**
67
- * @param {String} field
68
96
  * @param {Object} data
69
97
  */
70
- changeSorting(field, data) {
98
+ changeNameFilter(data) {
71
99
  let store = this.down({module: List}).store;
72
100
 
73
- store.sorters[0].property = field;
101
+ store.getFilter('name').value = data.value;
102
+ }
103
+
104
+ /**
105
+ * @param {String} property
106
+ * @param {Object} data
107
+ */
108
+ changeSorting(property, data) {
109
+ let me = this,
110
+ buttonFirstName = me.down({field: 'firstname'}),
111
+ buttonLastName = me.down({field: 'lastname'}),
112
+ direction = 'ASC',
113
+ store = me.down({module: List}).store,
114
+ sorter = store.sorters[0],
115
+ button;
116
+
117
+ button = property === 'firstname' ? buttonFirstName : buttonLastName;
118
+
119
+ if (property === me.sortBy) {
120
+ direction = sorter.direction === 'ASC' ? 'DESC' : 'ASC';
121
+ }
122
+
123
+ button.iconCls = `fas fa-arrow-circle-${direction === 'ASC' ? 'up' : 'down'}`;
124
+
125
+ button = button === buttonFirstName ? buttonLastName : buttonFirstName;
126
+ button.iconCls = null;
127
+
128
+ sorter.set({direction, property});
129
+
130
+ me.sortBy = property;
131
+ }
132
+
133
+ /**
134
+ * @param {Object} data
135
+ */
136
+ changeTransitionDuration(data) {
137
+ this.down({module: List}).getPlugin('animate').transitionDuration = data.value;
74
138
  }
75
139
  }
76
140
 
@@ -17,6 +17,23 @@ class MainStore extends Store {
17
17
  disabled : true,
18
18
  property : 'isOnline',
19
19
  value : true
20
+ }, {
21
+ property : 'name',
22
+ value : null,
23
+
24
+ filterBy: opts => {
25
+ let record = opts.item,
26
+ value = opts.value?.toLowerCase();
27
+
28
+ if (value) {
29
+ return !(
30
+ record.firstname.toLowerCase().includes(value) ||
31
+ record.lastname .toLowerCase().includes(value)
32
+ );
33
+ }
34
+
35
+ return false;
36
+ }
20
37
  }],
21
38
 
22
39
  sorters: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "3.0.1",
3
+ "version": "3.0.5",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,11 +36,11 @@
36
36
  "@fortawesome/fontawesome-free": "^5.15.4",
37
37
  "@material/mwc-button": "^0.25.3",
38
38
  "@material/mwc-textfield": "^0.25.3",
39
- "autoprefixer": "^10.4.1",
39
+ "autoprefixer": "^10.4.2",
40
40
  "chalk": "^4.1.2",
41
41
  "clean-webpack-plugin": "^4.0.0",
42
42
  "commander": "^8.3.0",
43
- "cssnano": "^5.0.14",
43
+ "cssnano": "^5.0.15",
44
44
  "envinfo": "^7.8.1",
45
45
  "fs-extra": "^10.0.0",
46
46
  "highlightjs-line-numbers.js": "^2.8.0",
@@ -48,7 +48,7 @@
48
48
  "neo-jsdoc": "^1.0.1",
49
49
  "neo-jsdoc-x": "^1.0.4",
50
50
  "postcss": "^8.4.5",
51
- "sass": "^1.45.2",
51
+ "sass": "^1.47.0",
52
52
  "webpack": "^5.65.0",
53
53
  "webpack-cli": "^4.9.1",
54
54
  "webpack-dev-server": "4.7.2",
@@ -17,7 +17,6 @@
17
17
  border : 1px solid #1c60a0;
18
18
  border-radius : 6px;
19
19
  opacity : .9;
20
- transition : transform .5s ease-in-out;
21
20
  }
22
21
 
23
22
  .neo-list-item-content {
@@ -469,11 +469,13 @@ class Base extends CoreBase {
469
469
  }
470
470
 
471
471
  /**
472
+ *
473
+ * @param {Object[]} items=this._items
474
+ * @param {Boolean} silent=false
472
475
  * @protected
473
476
  */
474
- doSort() {
477
+ doSort(items=this._items, silent=false) {
475
478
  let me = this,
476
- items = me._items,
477
479
  previousItems = [...items],
478
480
  sorters = me.sorters,
479
481
  sortDirections = me.sortDirections,
@@ -558,7 +560,7 @@ class Base extends CoreBase {
558
560
 
559
561
  me[isSorted] = countSorters > 0;
560
562
 
561
- if (me[updatingIndex] === 0) {
563
+ if (!silent && me[updatingIndex] === 0) {
562
564
  me.fire('sort', {
563
565
  items: me._items,
564
566
  previousItems,
@@ -607,6 +609,8 @@ class Base extends CoreBase {
607
609
  i = 0,
608
610
  countItems = items.length,
609
611
  filteredItems = [],
612
+ needsSorting = false,
613
+ oldItems = [...me._items],
610
614
  config, isIncluded, item, j, tmpItems;
611
615
 
612
616
  for (; i < countAllFilters; i++) {
@@ -616,6 +620,10 @@ class Base extends CoreBase {
616
620
  }
617
621
 
618
622
  if (countFilters === 0 && me.allItems) {
623
+ if (me.sorters.length > 0) {
624
+ needsSorting = true;
625
+ }
626
+
619
627
  me.clear();
620
628
 
621
629
  me.items = [...me.allItems._items];
@@ -682,7 +690,16 @@ class Base extends CoreBase {
682
690
 
683
691
  me[isFiltered] = countFilters !== 0;
684
692
 
685
- me.fire('filter', me);
693
+ if (needsSorting) {
694
+ me.doSort(me.items, true);
695
+ }
696
+
697
+ me.fire('filter', {
698
+ isFiltered: me[isFiltered],
699
+ items : me.items,
700
+ oldItems,
701
+ scope : me
702
+ });
686
703
  }
687
704
 
688
705
  /**
@@ -40,7 +40,7 @@ class Filter extends Base {
40
40
  */
41
41
  disabled_: false,
42
42
  /**
43
- * Provide a custom filtering function, has a higher priority than property, operator & value
43
+ * Provide a custom filtering function which has a higher priority than property, operator & value
44
44
  * @member {Function|null} filterBy_=null
45
45
  */
46
46
  filterBy_: null,
@@ -173,7 +173,12 @@ class Filter extends Base {
173
173
  }
174
174
 
175
175
  if (me._filterBy) {
176
- return me.filterBy.call(me.scope || me, item, filteredItems, allItems);
176
+ return me.filterBy.call(me.scope || me, {
177
+ allItems,
178
+ filteredItems,
179
+ item,
180
+ value: me._value
181
+ });
177
182
  }
178
183
 
179
184
  if (me.includeEmptyValues && (me._value === null || Neo.isEmpty(me._value))) {
@@ -107,6 +107,10 @@ class Observable extends Base {
107
107
  for (i = 0; i < len; i++) {
108
108
  eventConfig = events[i];
109
109
 
110
+ if (!Neo.isFunction(eventConfig.fn)) {
111
+ eventConfig.fn = eventConfig.scope[eventConfig.fn];
112
+ }
113
+
110
114
  eventConfig.fn.apply(eventConfig.scope || me, eventConfig.data ? args.concat(eventConfig.data) : args);
111
115
  }
112
116
  }
package/src/list/Base.mjs CHANGED
@@ -132,7 +132,7 @@ class Base extends Component {
132
132
  plugins.push({
133
133
  module : module.default,
134
134
  appName: me.appName,
135
- flag : 'animate',
135
+ id : 'animate',
136
136
  ...me.pluginAnimateConfig
137
137
  });
138
138
 
@@ -191,9 +191,9 @@ class Base extends Component {
191
191
  let me = this;
192
192
 
193
193
  value?.on({
194
- filter : me.onStoreFilter,
195
- load : me.onStoreLoad,
196
- recordChange: me.onStoreRecordChange,
194
+ filter : 'onStoreFilter',
195
+ load : 'onStoreLoad',
196
+ recordChange: 'onStoreRecordChange',
197
197
  scope : me
198
198
  });
199
199
 
@@ -1,4 +1,5 @@
1
- import Base from '../../plugin/Base.mjs';
1
+ import Base from '../../plugin/Base.mjs';
2
+ import CssUtil from '../../util/Css.mjs';
2
3
 
3
4
  /**
4
5
  * @class Neo.list.plugin.Animate
@@ -39,7 +40,17 @@ class Animate extends Base {
39
40
  * Read only
40
41
  * @member {Number|null} rows=null
41
42
  */
42
- rows: null
43
+ rows: null,
44
+ /**
45
+ * Time in ms. Please ensure to match the CSS based value, in case you change the default.
46
+ * @member {Number} transitionDuration_=500
47
+ */
48
+ transitionDuration_: 500,
49
+ /**
50
+ * The id of the setTimeout() call which gets triggered after a transition is done.
51
+ * @member {Number|null} transitionTimeoutId=null
52
+ */
53
+ transitionTimeoutId: null
43
54
  }}
44
55
 
45
56
  /**
@@ -48,14 +59,16 @@ class Animate extends Base {
48
59
  construct(config) {
49
60
  super.construct(config);
50
61
 
51
- let me = this;
62
+ let me = this,
63
+ owner = me.owner;
52
64
 
53
65
  me.adjustCreateItem();
54
66
 
55
- me.owner.store.on({
56
- filter: me.onFilter,
57
- sort : me.onSort,
58
- scope : me
67
+ owner.onStoreFilter = me.onStoreFilter.bind(me);
68
+
69
+ owner.store.on({
70
+ sort : me.onStoreSort,
71
+ scope: me
59
72
  });
60
73
  }
61
74
 
@@ -70,6 +83,25 @@ class Animate extends Base {
70
83
  owner.createItem = me.createItem.bind(owner, me);
71
84
  }
72
85
 
86
+ /**
87
+ * Triggered after the transitionDuration config got changed.
88
+ *
89
+ * We do not want to apply the style to each list item itself,
90
+ * so we are using Neo.util.Css
91
+ * @param {Boolean} value
92
+ * @param {Boolean} oldValue
93
+ * @protected
94
+ */
95
+ afterSetTransitionDuration(value, oldValue) {
96
+ Neo.isNumber(oldValue) && CssUtil.deleteRules(`#${this.owner.id} .neo-list-item`);
97
+
98
+ CssUtil.insertRules([
99
+ `#${this.owner.id} .neo-list-item {`,
100
+ `transition: opacity ${value}ms ease-in-out, transform ${value}ms ease-in-out`,
101
+ '}'
102
+ ].join(''));
103
+ }
104
+
73
105
  /**
74
106
  * @param {Neo.list.plugin.Animate} me
75
107
  * @param {Object} record
@@ -77,27 +109,19 @@ class Animate extends Base {
77
109
  * @returns {Object}
78
110
  */
79
111
  createItem(me, record, index) {
80
- let item = me.ownerCreateItem(record, index),
81
- itemHeight = me.itemHeight,
82
- itemWidth = me.itemWidth,
83
- margin = me.itemMargin,
84
- style = item.style || {},
85
- column, row, x, y;
112
+ let item = me.ownerCreateItem(record, index),
113
+ position = me.getItemPosition(record, index),
114
+ style = item.style || {};
86
115
 
87
116
  if (!me.ownerRect) {
88
117
  return null;
89
118
  }
90
119
 
91
- column = index % me.columns;
92
- row = Math.floor(index / me.columns);
93
- x = column * (margin + itemWidth) + margin;
94
- y = row * (margin + itemHeight) + margin;
95
-
96
120
  Object.assign(style, {
97
- height : `${itemHeight}px`,
121
+ height : `${me.itemHeight}px`,
98
122
  position : 'absolute',
99
- transform: `translate(${x}px, ${y}px)`,
100
- width : `${itemWidth}px`
123
+ transform: `translate(${position.x}px, ${position.y}px)`,
124
+ width : `${me.itemWidth}px`
101
125
  });
102
126
 
103
127
  item.style = style;
@@ -106,10 +130,38 @@ class Animate extends Base {
106
130
  }
107
131
 
108
132
  /**
109
- * @param {Object} data
133
+ *
134
+ * @param {Object} record
135
+ * @param {Number} index
136
+ * @returns {{x: Number, y: Number}}
110
137
  */
111
- onFilter(data) {
112
- console.log('onFilter', data);
138
+ getItemPosition(record, index) {
139
+ let me = this,
140
+ column = index % me.columns,
141
+ margin = me.itemMargin,
142
+ row = Math.floor(index / me.columns),
143
+ x = column * (margin + me.itemWidth) + margin,
144
+ y = row * (margin + me.itemHeight) + margin;
145
+
146
+ return {x, y};
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param {Object} obj
152
+ * @param {String[]} map
153
+ * @param {Boolean} intercept
154
+ * @returns {Number}
155
+ */
156
+ getItemIndex(obj, map, intercept) {
157
+ if (!intercept) {
158
+ return obj.index;
159
+ }
160
+
161
+ let owner = this.owner,
162
+ key = owner.store.keyProperty;
163
+
164
+ return map.indexOf(owner.getItemId(obj.record[key]));
113
165
  }
114
166
 
115
167
  /**
@@ -127,13 +179,126 @@ class Animate extends Base {
127
179
  });
128
180
  }
129
181
 
182
+ /**
183
+ * @param {Object} data
184
+ * @param {Boolean} data.isFiltered
185
+ * @param {Object[]} data.items
186
+ * @param {Object[]} data.oldItems
187
+ * @param {Neo.data.Store} data.scope
188
+ */
189
+ onStoreFilter(data) {
190
+ let me = this,
191
+ owner = me.owner,
192
+ key = owner.store.keyProperty,
193
+ hasAddedItems = false,
194
+ addedItems = [],
195
+ movedItems = [],
196
+ removedItems = [],
197
+ transitionTimeoutId = me.transitionTimeoutId,
198
+ intercept = !!transitionTimeoutId,
199
+ vdom = owner.vdom,
200
+ index, item, map, position;
201
+
202
+ if (transitionTimeoutId) {
203
+ clearTimeout(transitionTimeoutId);
204
+ me.transitionTimeoutId = null;
205
+ }
206
+
207
+ map = intercept ? vdom.cn.map(e => e.id) : [];
208
+
209
+ data.items.forEach((record, index) => {
210
+ item = {index, record};
211
+
212
+ if (!data.oldItems.includes(record)) {
213
+ // flag items which are still inside the DOM (running remove OP)
214
+ if (intercept && map.includes(owner.getItemId(record[key]))) {
215
+ item.reAdded = true;
216
+ }
217
+
218
+ addedItems.push(item);
219
+ } else {
220
+ movedItems.push(item);
221
+ }
222
+ });
223
+
224
+ data.oldItems.forEach((record, index) => {
225
+ if (!data.items.includes(record)) {
226
+ removedItems.push({index, record});
227
+ }
228
+ });
229
+
230
+ addedItems.forEach(obj => {
231
+ if (!obj.reAdded) {
232
+ index = me.getItemIndex(obj, map, intercept);
233
+
234
+ if (index > -1) {
235
+ hasAddedItems = true;
236
+
237
+ vdom.cn.splice(index, 0, me.createItem(me, obj.record, obj.index));
238
+
239
+ obj.item = vdom.cn[index];
240
+ obj.item.style.opacity = 0;
241
+ }
242
+ }
243
+ });
244
+
245
+ if (hasAddedItems) {
246
+ owner.vdom = vdom;
247
+ }
248
+
249
+ // ensure to get into the next animation frame
250
+ setTimeout(() => {
251
+ // get the latest version of the vdom, since this is a delayed callback
252
+ vdom = owner.vdom;
253
+
254
+ // new items are already added into the vdom, while old items are not yet removed
255
+ // => we need a map to ensure getting the correct index
256
+ map = vdom.cn.map(e => e.id);
257
+
258
+ addedItems.forEach(obj => {
259
+ index = me.getItemIndex(obj, map, intercept);
260
+
261
+ if (index > -1) {
262
+ // we can change the opacity for re-added items too => the vdom engine will ignore this
263
+ vdom.cn[index].style.opacity = 1;
264
+ }
265
+ });
266
+
267
+ movedItems.forEach(obj => {
268
+ index = me.getItemIndex(obj, map, true); // honor removed items, even without interceptions
269
+
270
+ if (index > -1) {
271
+ position = me.getItemPosition(obj.record, obj.index);
272
+
273
+ Object.assign(vdom.cn[index].style, {
274
+ opacity : 1,
275
+ transform: `translate(${position.x}px, ${position.y}px)`
276
+ });
277
+ }
278
+ });
279
+
280
+ removedItems.forEach(obj => {
281
+ index = me.getItemIndex(obj, map, intercept);
282
+
283
+ if (index > -1) {
284
+ obj.item = vdom.cn[index];
285
+ obj.item.style.opacity = 0;
286
+ }
287
+ });
288
+
289
+ owner.vdom = vdom;
290
+
291
+ me.triggerTransitionCallback();
292
+ }, 50);
293
+ }
294
+
130
295
  /**
131
296
  * @param {Object} data
132
297
  * @param {Object[]} data.items
133
298
  * @param {Object[]} data.previousItems
134
299
  * @param {Neo.data.Store} data.scope
135
300
  */
136
- onSort(data) {
301
+ onStoreSort(data) {
137
302
  let me = this,
138
303
  hasChange = false,
139
304
  keyProperty = data.scope.keyProperty,
@@ -158,15 +323,28 @@ class Animate extends Base {
158
323
  if (hasChange) {
159
324
  owner.vdom.cn = newVdomCn;
160
325
 
161
- owner.promiseVdomUpdate().then(() => {
162
- // we need to ensure to get this call into the next animation frame
163
- setTimeout(() => {
164
- owner.createItems();
165
- }, 50);
166
- });
326
+ owner.vdom = vdom;
327
+
328
+ // we need to ensure to get this call into the next animation frame
329
+ setTimeout(() => {
330
+ owner.createItems();
331
+ }, 50);
167
332
  }
168
333
  }
169
334
  }
335
+
336
+ /**
337
+ *
338
+ */
339
+ triggerTransitionCallback() {
340
+ let me = this;
341
+
342
+ me.transitionTimeoutId = setTimeout(() => {
343
+ me.transitionTimeoutId = null;
344
+
345
+ me.owner.createItems();
346
+ }, me.transitionDuration);
347
+ }
170
348
  }
171
349
 
172
350
  Neo.applyClassConfig(Animate);
@@ -8,6 +8,12 @@ import Base from '../../core/Base.mjs';
8
8
  * @singleton
9
9
  */
10
10
  class Stylesheet extends Base {
11
+ /**
12
+ * @member {String} dynamicStyleSheetId='neo-dynamic-stylesheet'
13
+ * @protected
14
+ */
15
+ dynamicStyleSheetId = 'neo-dynamic-stylesheet';
16
+
11
17
  static getConfig() {return {
12
18
  /**
13
19
  * @member {String} className='Neo.main.addon.Stylesheet'
@@ -23,6 +29,7 @@ class Stylesheet extends Base {
23
29
  app: [
24
30
  'addThemeFiles',
25
31
  'createStyleSheet',
32
+ 'deleteCssRules',
26
33
  'insertCssRules',
27
34
  'swapStyleSheet'
28
35
  ]
@@ -137,6 +144,32 @@ class Stylesheet extends Base {
137
144
  document.head.appendChild(link);
138
145
  }
139
146
 
147
+ /**
148
+ * @param {Object} data
149
+ * @param {Array} data.rules
150
+ * @protected
151
+ */
152
+ deleteCssRules(data) {
153
+ let styleEl = document.getElementById(this.dynamicStyleSheetId),
154
+ styleSheet = styleEl.sheet,
155
+ cssRules = styleSheet.cssRules,
156
+ i = 0,
157
+ len = data.rules.length,
158
+ j, rulesLen;
159
+
160
+ for (; i < len; i++) {
161
+ j = 0;
162
+ rulesLen = cssRules.length;
163
+
164
+ for (; j < rulesLen; j++) {
165
+ if (cssRules[j].selectorText === data.rules[i]) {
166
+ styleSheet.deleteRule(j);
167
+ break;
168
+ }
169
+ }
170
+ }
171
+ }
172
+
140
173
  /**
141
174
  * @param {String} token
142
175
  * @returns {Boolean}
@@ -162,7 +195,7 @@ class Stylesheet extends Base {
162
195
  * @protected
163
196
  */
164
197
  insertCssRules(data) {
165
- let styleEl = document.getElementById('neoDynamicStyleSheet'),
198
+ let styleEl = document.getElementById(this.dynamicStyleSheetId),
166
199
  i = 0,
167
200
  len = data.rules.length,
168
201
  styleSheet;
@@ -170,7 +203,7 @@ class Stylesheet extends Base {
170
203
  if (!styleEl) {
171
204
  styleEl = document.createElement('style');
172
205
 
173
- styleEl.id = 'neoDynamicStyleSheet';
206
+ styleEl.id = this.dynamicStyleSheetId;
174
207
  document.head.appendChild(styleEl);
175
208
  }
176
209
 
@@ -33,7 +33,11 @@ class Base extends CoreBase {
33
33
 
34
34
  let me = this;
35
35
 
36
- me.owner.on('mounted', me.onOwnerMounted, me);
36
+ if (me.owner.mounted) {
37
+ me.onOwnerMounted();
38
+ } else {
39
+ me.owner.on('mounted', me.onOwnerMounted, me);
40
+ }
37
41
  }
38
42
 
39
43
  /**
package/src/util/Css.mjs CHANGED
@@ -14,15 +14,29 @@ class Css extends Base {
14
14
  }}
15
15
 
16
16
  /**
17
- * @param {Array} rules
17
+ * Pass the selectorText of the rules which you want to remove
18
+ * @param {String[]|String} rules
19
+ */
20
+ static deleteRules(rules) {
21
+ if (!Array.isArray(rules)) {
22
+ rules = [rules];
23
+ }
24
+
25
+ Neo.main.addon.Stylesheet.deleteCssRules({
26
+ rules: rules
27
+ });
28
+ }
29
+
30
+ /**
31
+ * @param {String[]|String} rules
18
32
  */
19
33
  static insertRules(rules) {
34
+ if (!Array.isArray(rules)) {
35
+ rules = [rules];
36
+ }
37
+
20
38
  Neo.main.addon.Stylesheet.insertCssRules({
21
39
  rules: rules
22
- }).then(function(data) {
23
- // console.log('inserted CSS rules', data);
24
- }).catch(function(err) {
25
- console.log('App: Got error attempting to insert CSS rules', err, rules);
26
40
  });
27
41
  }
28
42
  }