neo.mjs 4.6.1 → 4.6.3

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 (29) hide show
  1. package/README.md +0 -8
  2. package/docs/app/view/MainContainerController.mjs +12 -11
  3. package/docs/app/view/classdetails/SourceViewComponent.mjs +12 -12
  4. package/examples/form/field/text/MainContainer.mjs +6 -0
  5. package/examples/toast/MainContainer.mjs +136 -0
  6. package/examples/toast/MainContainerController.mjs +95 -0
  7. package/examples/toast/app.mjs +7 -0
  8. package/examples/toast/index.html +27 -0
  9. package/examples/toast/neo-config.json +7 -0
  10. package/examples/toast/resources/highlight/CHANGES.md +1739 -0
  11. package/examples/toast/resources/highlight/LICENSE +24 -0
  12. package/examples/toast/resources/highlight/README.md +186 -0
  13. package/examples/toast/resources/highlight/highlight.pack.js +2 -0
  14. package/examples/toast/resources/highlightjs-custom-dark-theme.css +120 -0
  15. package/examples/toast/resources/highlightjs-custom-github-theme.css +136 -0
  16. package/package.json +1 -1
  17. package/resources/scss/src/dialog/Toast.scss +132 -106
  18. package/resources/scss/src/form/field/Text.scss +130 -24
  19. package/resources/scss/theme-dark/dialog/Toast.scss +13 -0
  20. package/resources/scss/theme-dark/form/field/Text.scss +54 -34
  21. package/resources/scss/theme-light/dialog/Toast.scss +25 -0
  22. package/resources/scss/theme-light/form/field/Text.scss +54 -34
  23. package/src/collection/Base.mjs +0 -1
  24. package/src/component/Base.mjs +1 -17
  25. package/src/dialog/Toast.mjs +140 -68
  26. package/src/form/field/CheckBox.mjs +3 -3
  27. package/src/form/field/Text.mjs +51 -21
  28. package/src/main/addon/HighlightJS.mjs +28 -15
  29. package/src/manager/Toast.mjs +1 -1
@@ -1,41 +1,61 @@
1
1
  $neoMap: map-merge($neoMap, (
2
- 'textfield-border-color' : #ddd,
3
- 'textfield-border-color-active' : #1c60a0,
4
- 'textfield-border-color-hovered' : #ddd,
5
- 'textfield-border-color-invalid' : brown,
6
- 'textfield-border-radius' : 3px,
7
- 'textfield-border-width' : 1px,
8
- 'textfield-input-background-color' : #fff,
9
- 'textfield-input-color' : #000,
10
- 'textfield-input-font' : 400 13px/17px Arial,
11
- 'textfield-input-height' : 25px,
12
- 'textfield-input-padding' : 3px 6px 2px,
13
- 'textfield-input-placeholder-color' : #333,
14
- 'textfield-input-placeholder-opacity': 0.6,
15
- 'textfield-label-color' : #666,
16
- 'textfield-label-top-margin' : 0 0 3px,
17
- 'textfield-outline-active' : none,
18
- 'textfield-outline-hovered' : none
2
+ 'textfield-border-color' : #ddd,
3
+ 'textfield-border-color-active' : #1c60a0,
4
+ 'textfield-border-color-disabled' : #ddd,
5
+ 'textfield-border-color-hovered' : #ddd,
6
+ 'textfield-border-color-invalid' : brown,
7
+ 'textfield-border-color-readonly' : #ddd,
8
+ 'textfield-border-radius' : 3px,
9
+ 'textfield-border-width' : 1px,
10
+ 'textfield-input-background-color' : #fff,
11
+ 'textfield-input-background-color-disabled': #fff,
12
+ 'textfield-input-background-color-readonly': #fbfbfb,
13
+ 'textfield-input-color' : #000,
14
+ 'textfield-input-color-disabled' : #000,
15
+ 'textfield-input-color-readonly' : #000,
16
+ 'textfield-input-font' : 400 13px/17px Arial,
17
+ 'textfield-input-height' : 25px,
18
+ 'textfield-input-padding' : 3px 6px 2px,
19
+ 'textfield-input-placeholder-color' : #333,
20
+ 'textfield-input-placeholder-opacity' : 0.6,
21
+ 'textfield-label-color' : #666,
22
+ 'textfield-label-color-disabled' : #666,
23
+ 'textfield-label-color-readonly' : #666,
24
+ 'textfield-label-top-margin' : 0 0 3px,
25
+ 'textfield-opacity-disabled' : #{neo(neo-disabled-opacity)},
26
+ 'textfield-opacity-readonly' : 1,
27
+ 'textfield-outline-active' : none,
28
+ 'textfield-outline-hovered' : none
19
29
  ));
20
30
 
21
31
  @if $useCssVars == true {
22
32
  :root .neo-theme-light { // .neo-textfield
23
- --textfield-border-color : #{neo(textfield-border-color)};
24
- --textfield-border-color-active : #{neo(textfield-border-color-active)};
25
- --textfield-border-color-hovered : #{neo(textfield-border-color-hovered)};
26
- --textfield-border-color-invalid : #{neo(textfield-border-color-invalid)};
27
- --textfield-border-radius : #{neo(textfield-border-radius)};
28
- --textfield-border-width : #{neo(textfield-border-width)};
29
- --textfield-input-background-color : #{neo(textfield-input-background-color)};
30
- --textfield-input-color : #{neo(textfield-input-color)};
31
- --textfield-input-font : #{neo(textfield-input-font)};
32
- --textfield-input-height : #{neo(textfield-input-height)};
33
- --textfield-input-padding : #{neo(textfield-input-padding)};
34
- --textfield-input-placeholder-color : #{neo(textfield-input-placeholder-color)};
35
- --textfield-input-placeholder-opacity: #{neo(textfield-input-placeholder-opacity)};
36
- --textfield-label-color : #{neo(textfield-label-color)};
37
- --textfield-label-top-margin : #{neo(textfield-label-top-margin)};
38
- --textfield-outline-active : #{neo(textfield-outline-active)};
39
- --textfield-outline-hovered : #{neo(textfield-outline-hovered)};
33
+ --textfield-border-color : #{neo(textfield-border-color)};
34
+ --textfield-border-color-active : #{neo(textfield-border-color-active)};
35
+ --textfield-border-color-disabled : #{neo(textfield-border-color-disabled)};
36
+ --textfield-border-color-hovered : #{neo(textfield-border-color-hovered)};
37
+ --textfield-border-color-invalid : #{neo(textfield-border-color-invalid)};
38
+ --textfield-border-color-readonly : #{neo(textfield-border-color-readonly)};
39
+ --textfield-border-radius : #{neo(textfield-border-radius)};
40
+ --textfield-border-width : #{neo(textfield-border-width)};
41
+ --textfield-input-background-color : #{neo(textfield-input-background-color)};
42
+ --textfield-input-background-color-disabled: #{neo(textfield-input-background-color-disabled)};
43
+ --textfield-input-background-color-readonly: #{neo(textfield-input-background-color-readonly)};
44
+ --textfield-input-color : #{neo(textfield-input-color)};
45
+ --textfield-input-color-disabled : #{neo(textfield-input-color-disabled)};
46
+ --textfield-input-color-readonly : #{neo(textfield-input-color-readonly)};
47
+ --textfield-input-font : #{neo(textfield-input-font)};
48
+ --textfield-input-height : #{neo(textfield-input-height)};
49
+ --textfield-input-padding : #{neo(textfield-input-padding)};
50
+ --textfield-input-placeholder-color : #{neo(textfield-input-placeholder-color)};
51
+ --textfield-input-placeholder-opacity : #{neo(textfield-input-placeholder-opacity)};
52
+ --textfield-label-color : #{neo(textfield-label-color)};
53
+ --textfield-label-color-disabled : #{neo(textfield-label-color-disabled)};
54
+ --textfield-label-color-readonly : #{neo(textfield-label-color-readonly)};
55
+ --textfield-label-top-margin : #{neo(textfield-label-top-margin)};
56
+ --textfield-opacity-disabled : #{neo(textfield-opacity-disabled)};
57
+ --textfield-opacity-readonly : #{neo(textfield-opacity-readonly)};
58
+ --textfield-outline-active : #{neo(textfield-outline-active)};
59
+ --textfield-outline-hovered : #{neo(textfield-outline-hovered)};
40
60
  }
41
61
  }
@@ -668,7 +668,6 @@ class Base extends CoreBase {
668
668
  me.clearSilent();
669
669
 
670
670
  me.items = [...me.allItems._items];
671
- me.map.set(...me.allItems.map);
672
671
  } else {
673
672
  if (!me.allItems) {
674
673
  config = {...me.originalConfig};
@@ -16,13 +16,6 @@ import VNodeUtil from '../util/VNode.mjs';
16
16
  * @extends Neo.core.Base
17
17
  */
18
18
  class Base extends CoreBase {
19
- /**
20
- * Internal flag to prevent multiple CSS merges
21
- * @member {Boolean} baseClsApplied=false
22
- * @protected
23
- */
24
- baseClsApplied = false
25
-
26
19
  static getStaticConfig() {return {
27
20
  /**
28
21
  * Valid values for hideMode
@@ -866,16 +859,7 @@ class Base extends CoreBase {
866
859
  * @protected
867
860
  */
868
861
  beforeSetCls(value, oldValue) {
869
- value = value || [];
870
-
871
- let me = this;
872
-
873
- if (!me.baseClsApplied) {
874
- value = NeoArray.union(value, me.baseCls);
875
- me.baseClsApplied = true;
876
- }
877
-
878
- return value;
862
+ return NeoArray.union(value || [], this.baseCls);;
879
863
  }
880
864
 
881
865
  /**
@@ -1,9 +1,10 @@
1
- import Base from './Base.mjs';
1
+ import Base from '../component/Base.mjs';
2
2
  import ToastManager from '../manager/Toast.mjs';
3
+ import NeoArray from "../util/Array.mjs";
3
4
 
4
5
  /**
5
6
  * @class Neo.dialog.Toast
6
- * @extends Neo.dialog.Base
7
+ * @extends Neo.component.Base
7
8
  *
8
9
  * @example
9
10
  Neo.toast({
@@ -20,33 +21,12 @@ import ToastManager from '../manager/Toast.mjs';
20
21
  })
21
22
  */
22
23
  class Toast extends Base {
23
- /**
24
- * If true makes the toast sticky and show a close icon
25
- * @member {Boolean} closable=false
26
- */
27
- closable = false
28
- /**
29
- * Change to use your own fade out animation
30
- * @member {String} fadeOutCls='neo-toast-fade-out'
31
- */
32
- fadeOutCls = 'neo-toast-fade-out'
33
- /**
34
- * If set, it shows this icon in front of the text
35
- * e.g. 'fa fa-cog'
36
- * @member {String|null} iconCls=null
37
- */
38
- iconCls = null
39
24
  /**
40
25
  * Used by the ToastManager
41
26
  * @member {Boolean} running=false
42
27
  * @private
43
28
  */
44
29
  running = false
45
- /**
46
- * Change the complete styling with custom cls
47
- * @member {String} toastCls='neo-toast-'
48
- */
49
- toastCls = 'neo-toast-'
50
30
  /**
51
31
  * Used by the ToastManager
52
32
  * @member {String|null} toastManagerId=null
@@ -54,6 +34,22 @@ class Toast extends Base {
54
34
  */
55
35
  toastManagerId = null
56
36
 
37
+ static getStaticConfig() {return {
38
+ /**
39
+ * Valid values for positions
40
+ * @member {String[]} positions = ['tl', 'tc', 'tr', 'bl', 'bc', 'br']
41
+ * @protected
42
+ * @static
43
+ */
44
+ positions: ['tl', 'tc', 'tr', 'bl', 'bc', 'br'],
45
+ /**
46
+ * True automatically applies the core/Observable.mjs mixin
47
+ * @member {String[]} slideDirections = ['down', 'up', 'left', 'right']
48
+ * @static
49
+ */
50
+ slideDirections: ['down', 'up', 'left', 'right']
51
+ }}
52
+
57
53
  static getConfig() {return {
58
54
  /**
59
55
  * @member {String} className='Neo.dialog.Toast'
@@ -65,18 +61,31 @@ class Toast extends Base {
65
61
  * @protected
66
62
  */
67
63
  ntype: 'toast',
64
+
65
+ /**
66
+ * @member {Boolean} autoMount=true
67
+ */
68
+ autoMount: true,
69
+ /**
70
+ * @member {Boolean} autoRender=true
71
+ */
72
+ autoRender: true,
68
73
  /**
69
- * The Toast should not be moved
70
- * @member {Boolean} draggable=false
74
+ * @member {String[]} baseCls=['neo-toast']
75
+ * @protected
71
76
  */
72
- draggable: false,
77
+ baseCls: ['neo-toast'],
73
78
  /**
74
- * Header is not meant to be shown.
75
- * @member {Object} headerConfig={hidden:true}
79
+ * If true makes the toast sticky and show a close icon
80
+ * @member {Boolean} closable=false
76
81
  */
77
- headerConfig: {
78
- hidden: true
79
- },
82
+ closable_: false,
83
+ /**
84
+ * If set, it shows this icon in front of the text
85
+ * e.g. 'fa fa-cog'
86
+ * @member {String|null} iconCls=null
87
+ */
88
+ iconCls_: null,
80
89
  /**
81
90
  * Limits the width of the Toast
82
91
  * @member {Number} maxWidth=250
@@ -94,17 +103,13 @@ class Toast extends Base {
94
103
  msg_: null,
95
104
  /**
96
105
  * Describes the position of the toast, e.g. bl=bottom-left
97
- * This creates a cls `toastCls + position`
106
+ * This creates a cls `noe-toast-position`
98
107
  * @member {'tl'|'tc'|'tr'|'bl'|'bc'|'br'} position='tr'
99
108
  */
100
109
  position_: 'tr',
101
- /**
102
- * @member {Boolean} resizable=false
103
- */
104
- resizable: false,
105
110
  /**
106
111
  * Describes which direction from which side the toasts slides-in
107
- * This creates a cls `toastCls + slide- + direction + in`
112
+ * This creates a cls `neo-toast-slide-${direction}-in`
108
113
  * @member {'down'|'up'|'left'|'right'} slideDirection_=null
109
114
  */
110
115
  slideDirection_: 'down',
@@ -114,25 +119,59 @@ class Toast extends Base {
114
119
  */
115
120
  timeout_: 3000,
116
121
  /**
117
- * @member {String|null} title=null
122
+ * Adds a title to the toast
123
+ * @member {Number} title_=null
118
124
  */
119
- title: null,
125
+ title_: null,
120
126
  /**
121
- * @member {Function} itemTpl
127
+ * @member {String|null} title=null
122
128
  */
123
- itemTpl: data => {
124
- let cls = data.cls;
125
-
126
- return [
127
- {cls: [`${cls}icon`, data.iconCls], removeDom: !data.iconCls},
128
- {cls: `${cls}text`, cn: [
129
- {cls: `${cls}title`, innerHTML: `${data.title}`, removeDom: !data.title},
130
- {cls: `${cls}msg`, innerHTML: `${data.msg}`}
129
+ vdom: {cn: [{
130
+ cls: 'neo-toast-inner', cn: [
131
+ {cls: ['neo-toast-icon'], removeDom: true},
132
+ {cls: 'neo-toast-text', cn: [
133
+ {cls: ['neo-toast-title'], removeDom: true},
134
+ {cls: 'neo-toast-msg'}
131
135
  ]},
132
- {cls: `${cls}close fa fa-close`, removeDom: !data.closable}
133
- ]}
136
+ {cls: ['neo-toast-close', 'fa', 'fa-close'], removeDom: true}
137
+ ]
138
+ }]}
134
139
  }}
135
140
 
141
+ construct(config) {
142
+ super.construct(config);
143
+
144
+ let me = this;
145
+
146
+ // click listener for close
147
+ me.addDomListeners([
148
+ {click: {fn: me.unregister, delegate: '.neo-toast-close', scope: me}}
149
+ ])
150
+ }
151
+
152
+ /**
153
+ * @param {String|null} value
154
+ * @param {String|null} oldValue
155
+ */
156
+ afterSetClosable(value, oldValue) {
157
+ let vdom = this.getVdomInner().cn[2];
158
+
159
+ vdom.removeDom = !value;
160
+ }
161
+
162
+ /**
163
+ * @param {String|null} value
164
+ * @param {String|null} oldValue
165
+ */
166
+ afterSetIconCls(value, oldValue) {
167
+ let vdom = this.getVdomInner().cn[0],
168
+ cls = vdom.cls,
169
+ clsFn = !!value ? 'add' : 'remove';
170
+
171
+ vdom.removeDom = Neo.isEmpty(value);
172
+ NeoArray[clsFn](cls, value);
173
+ }
174
+
136
175
  /**
137
176
  * Using the afterSetMsg to trigger the setup of the dom
138
177
  * A new container is added as an item.
@@ -142,21 +181,22 @@ class Toast extends Base {
142
181
  * @param {String|null} oldValue
143
182
  */
144
183
  afterSetMsg(value, oldValue) {
145
- let me = this,
146
- toastCls = me.toastCls,
147
- data = {closable: me.closable, cls: toastCls, iconCls: me.iconCls, msg: me.msg, title: me.title},
148
- titleCls = (me.title && me.iconCls) ? `${toastCls}has-title` : '',
149
- vdom = {cn: me.itemTpl(data)};
150
-
151
- me.add({
152
- cls: [`${toastCls}inner`, titleCls],
153
- vdom
154
- });
155
-
156
- // if closable add a listener to the close-element
157
- me.closable && me.addDomListeners([
158
- {click: {fn: me.unregister, delegate: `.${me.toastCls}close`, scope: me}}
159
- ])
184
+ let vdom = this.getTextRootVdom().cn[1];
185
+
186
+ vdom.innerHTML = value;
187
+ }
188
+
189
+ /**
190
+ * @param {String|null} value
191
+ * @param {String|null} oldValue
192
+ */
193
+ afterSetTitle(value, oldValue) {
194
+ let vdom = this.getTextRootVdom().cn[0],
195
+ clsFn = !!value ? 'add' : 'remove';
196
+
197
+ vdom.removeDom = Neo.isEmpty(value);
198
+ vdom.innerHTML = value;
199
+ NeoArray[clsFn](vdom.cls, 'neo-toast-has-title');
160
200
  }
161
201
 
162
202
  /**
@@ -165,7 +205,7 @@ class Toast extends Base {
165
205
  * @param {String} oldValue
166
206
  */
167
207
  afterSetPosition(value, oldValue) {
168
- value && this.addCls(`${this.toastCls}${value}`)
208
+ value && this.addCls(`neo-toast-${value}`)
169
209
  }
170
210
 
171
211
  /**
@@ -174,7 +214,7 @@ class Toast extends Base {
174
214
  * @param {String} oldValue
175
215
  */
176
216
  afterSetSlideDirection(value, oldValue) {
177
- value && this.addCls(`${this.toastCls}slide-${value}-in`)
217
+ value && this.addCls(`neo-toast-slide-${value}-in`)
178
218
  }
179
219
 
180
220
  /**
@@ -189,6 +229,38 @@ class Toast extends Base {
189
229
  }
190
230
  }
191
231
 
232
+ /**
233
+ * Triggered before the position config gets changed
234
+ * @param {String} value
235
+ * @param {String} oldValue
236
+ * @protected
237
+ */
238
+ beforeSetPosition(value, oldValue) {
239
+ return this.beforeSetEnumValue(value, oldValue, 'position');
240
+ }
241
+
242
+ /**
243
+ * Triggered before the slideDirection config gets changed
244
+ * @param {String} value
245
+ * @param {String} oldValue
246
+ * @protected
247
+ */
248
+ beforeSetSlideDirection(value, oldValue) {
249
+ return this.beforeSetEnumValue(value, oldValue, 'slideDirection');
250
+ }
251
+
252
+ /**
253
+ * This is a dialog, so we have to add an item to be able to
254
+ * @returns {vdom}
255
+ */
256
+ getVdomInner() {
257
+ return this.vdom.cn[0];
258
+ }
259
+
260
+ getTextRootVdom() {
261
+ return this.getVdomInner().cn[1];
262
+ }
263
+
192
264
  /**
193
265
  * After the close-click or timeout, we unregister the toast
194
266
  * from the ToastManager
@@ -203,7 +275,7 @@ class Toast extends Base {
203
275
  }
204
276
  })
205
277
 
206
- me.addCls(me.fadeOutCls);
278
+ me.addCls('neo-toast-fade-out');
207
279
  }
208
280
  }
209
281
 
@@ -96,9 +96,9 @@ class CheckBox extends Base {
96
96
  if (oldValue !== undefined) {
97
97
  me.fire('change', {
98
98
  component: me,
99
- oldValue : oldValue,
100
- value : value
101
- });
99
+ oldValue,
100
+ value
101
+ })
102
102
  }
103
103
  }
104
104
 
@@ -125,6 +125,10 @@ class Text extends Base {
125
125
  * @member {String|null} placeholderText_=null
126
126
  */
127
127
  placeholderText_: null,
128
+ /**
129
+ * @member {Boolean} readOnly_=false
130
+ */
131
+ readOnly_: false,
128
132
  /**
129
133
  * @member {Boolean} required_=false
130
134
  */
@@ -476,6 +480,22 @@ class Text extends Base {
476
480
  this.changeInputElKey('placeholder', value === '' ? null : value);
477
481
  }
478
482
 
483
+ /**
484
+ * Triggered after the readOnly config got changed
485
+ * @param {Boolean} value
486
+ * @param {Boolean} oldValue
487
+ * @protected
488
+ */
489
+ afterSetReadOnly(value, oldValue) {
490
+ let me = this,
491
+ cls = me.cls;
492
+
493
+ NeoArray[value ? 'add' : 'remove'](cls, 'neo-readonly');
494
+ me.cls = cls;
495
+
496
+ me.changeInputElKey('readonly', value ? value : null);
497
+ }
498
+
479
499
  /**
480
500
  * Triggered after the required config got changed
481
501
  * @param {Boolean} value
@@ -888,15 +908,17 @@ class Text extends Base {
888
908
  let me = this,
889
909
  cls = me.cls;
890
910
 
891
- NeoArray.add(cls, 'neo-focus');
892
- me.cls = cls;
911
+ if (!me.readOnly) {
912
+ NeoArray.add(cls, 'neo-focus');
913
+ me.cls = cls;
893
914
 
894
- if (me.labelPosition === 'inline') {
895
- if (me.centerBorderElWidth) {
896
- me.getCenterBorderEl().width = me.centerBorderElWidth;
897
- me.update();
898
- } else {
899
- me.updateCenterBorderElWidth(false);
915
+ if (me.labelPosition === 'inline') {
916
+ if (me.centerBorderElWidth) {
917
+ me.getCenterBorderEl().width = me.centerBorderElWidth;
918
+ me.update();
919
+ } else {
920
+ me.updateCenterBorderElWidth(false);
921
+ }
900
922
  }
901
923
  }
902
924
  }
@@ -911,16 +933,18 @@ class Text extends Base {
911
933
  centerBorderEl = me.getCenterBorderEl(), // labelPosition: 'inline'
912
934
  cls = me.cls;
913
935
 
914
- me.validate(); // silent
936
+ if (!me.readOnly) {
937
+ me.validate(); // silent
915
938
 
916
- NeoArray.remove(cls, 'neo-focus');
917
- me.cls = cls;
939
+ NeoArray.remove(cls, 'neo-focus');
940
+ me.cls = cls;
918
941
 
919
- if (centerBorderEl && me.isEmpty()) {
920
- delete centerBorderEl.width;
921
- }
942
+ if (centerBorderEl && me.isEmpty()) {
943
+ delete centerBorderEl.width;
944
+ }
922
945
 
923
- me.update();
946
+ me.update();
947
+ }
924
948
  }
925
949
 
926
950
  /**
@@ -949,20 +973,26 @@ class Text extends Base {
949
973
  * @param {Object} data
950
974
  */
951
975
  onMouseEnter(data) {
952
- let cls = this.cls;
976
+ let me = this,
977
+ cls = me.cls;
953
978
 
954
- NeoArray.add(cls, 'neo-hovered');
955
- this.cls = cls;
979
+ if (!me.readOnly) {
980
+ NeoArray.add(cls, 'neo-hovered');
981
+ me.cls = cls;
982
+ }
956
983
  }
957
984
 
958
985
  /**
959
986
  * @param {Object} data
960
987
  */
961
988
  onMouseLeave(data) {
962
- let cls = this.cls;
989
+ let me = this,
990
+ cls = me.cls;
963
991
 
964
- NeoArray.remove(cls, 'neo-hovered');
965
- this.cls = cls;
992
+ if (!me.readOnly) {
993
+ NeoArray.remove(cls, 'neo-hovered');
994
+ me.cls = cls;
995
+ }
966
996
  }
967
997
 
968
998
  /**
@@ -27,13 +27,14 @@ class HighlightJS extends Base {
27
27
  highlightJsLineNumbersPath: Neo.config.basePath + 'node_modules/highlightjs-line-numbers.js/dist/highlightjs-line-numbers.min.js',
28
28
  /**
29
29
  * Remote method access for other workers
30
- * @member {Object} remote={app: [//...]}
30
+ * @member {Object} remote
31
31
  * @protected
32
32
  */
33
33
  remote: {
34
34
  app: [
35
35
  'scrollIntoView',
36
36
  'syntaxHighlight',
37
+ 'switchTheme',
37
38
  'syntaxHighlightInit',
38
39
  'syntaxHighlightLine'
39
40
  ]
@@ -62,7 +63,7 @@ class HighlightJS extends Base {
62
63
  DomAccess.addScript({src: me.highlightJsLineNumbersPath});
63
64
  });
64
65
 
65
- Stylesheet.createStyleSheet(null, 'hljs-theme', me.themePath);
66
+ Stylesheet.createStyleSheet(null, 'hljs-theme', me.themePath)
66
67
  }
67
68
 
68
69
  /**
@@ -75,13 +76,11 @@ class HighlightJS extends Base {
75
76
  let parentEl = DomAccess.getElement(data.vnodeId),
76
77
  el = parentEl.querySelector('[data-list-header="' + data.text + '"]');
77
78
 
78
- if (el) {
79
- el.previousSibling.scrollIntoView({
80
- behavior: 'smooth',
81
- block : 'start',
82
- inline : 'nearest'
83
- });
84
- }
79
+ el?.previousSibling.scrollIntoView({
80
+ behavior: 'smooth',
81
+ block : 'start',
82
+ inline : 'nearest'
83
+ })
85
84
  }
86
85
 
87
86
  /**
@@ -95,10 +94,26 @@ class HighlightJS extends Base {
95
94
  hljs.highlightBlock(node);
96
95
  hljs.lineNumbersBlock(node);
97
96
  } else {
98
- console.error('highlight.js is not included inside the main thread.');
97
+ console.error('highlight.js is not included inside the main thread.')
99
98
  }
100
99
  }
101
100
 
101
+ /**
102
+ * You can pass in 'light', 'dark', or a path for a custom theme
103
+ * @param {String} theme
104
+ */
105
+ switchTheme(theme) {
106
+ let definedThemes = {
107
+ dark: './resources/highlightjs-custom-dark-theme.css',
108
+ light: './resources/highlightjs-custom-github-theme.css'
109
+ },
110
+ switchToTheme = definedThemes[theme];
111
+
112
+ switchToTheme ??= theme;
113
+ this.themePath = switchToTheme;
114
+ Stylesheet.createStyleSheet(null, 'hljs-theme', switchToTheme);
115
+ }
116
+
102
117
  /**
103
118
  * @param {Object} data
104
119
  */
@@ -107,7 +122,7 @@ class HighlightJS extends Base {
107
122
  let blocks = document.querySelectorAll('pre code:not(.hljs)');
108
123
  Array.prototype.forEach.call(blocks, hljs.highlightBlock);
109
124
  } else {
110
- console.error('highlight.js is not included inside the main thread.');
125
+ console.error('highlight.js is not included inside the main thread.')
111
126
  }
112
127
  }
113
128
 
@@ -132,16 +147,14 @@ class HighlightJS extends Base {
132
147
  behavior: 'smooth',
133
148
  block : 'start',
134
149
  inline : 'nearest'
135
- });
150
+ })
136
151
  }
137
152
  }
138
153
 
139
154
  if (Neo.isNumber(data.removeLine)) {
140
155
  el = parentEl.querySelector('[data-line-number="' + data.removeLine + '"]');
141
156
 
142
- if (el) {
143
- el.parentNode.classList.remove(cls);
144
- }
157
+ el && el.parentNode.classList.remove(cls)
145
158
  }
146
159
  }
147
160
  }