marty 8.5.0 → 9.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintignore +1 -0
  3. data/.eslintrc.js +26 -0
  4. data/.gitignore +3 -0
  5. data/.gitlab-ci.yml +7 -0
  6. data/.prettierignore +14 -0
  7. data/.rubocop_todo.yml +1 -1
  8. data/Dockerfile.dummy +3 -0
  9. data/Makefile +1 -0
  10. data/app/assets/javascripts/marty/cable.js +7 -3
  11. data/app/assets/javascripts/marty/extjs/extensions/datetime_field/component.js +401 -0
  12. data/app/assets/javascripts/marty/extjs/extensions/datetime_field/field.js +140 -0
  13. data/app/assets/javascripts/marty/extjs/extensions/marty.js +845 -781
  14. data/app/assets/stylesheets/marty/codemirror/codemirror.css +215 -77
  15. data/app/assets/stylesheets/marty/codemirror/delorean.css +2 -2
  16. data/app/assets/stylesheets/marty/dark_mode.css +13 -3
  17. data/app/components/marty/auth_app/client/auth_app.js +107 -102
  18. data/app/components/marty/base_rule_view/client/base_rule_view.js +10 -8
  19. data/app/components/marty/data_grid_view/client/data_grid_edit.js +534 -519
  20. data/app/components/marty/form/client/form.js +3 -3
  21. data/app/components/marty/grid/client/grid.js +110 -87
  22. data/app/components/marty/import_view/client/import_view.js +18 -18
  23. data/app/components/marty/live_search_grid_panel/client/live_search_grid_panel.js +14 -13
  24. data/app/components/marty/main_auth_app/client/main_auth_app.js +42 -42
  25. data/app/components/marty/mcfly_grid_panel/client/mcfly_grid_panel.js +27 -18
  26. data/app/components/marty/new_posting_form/client/new_posting_form.js +3 -3
  27. data/app/components/marty/panel/client/panel.js +3 -3
  28. data/app/components/marty/posting_grid/client/posting_grid.js +24 -18
  29. data/app/components/marty/promise_view/client/promise_view.css +12 -12
  30. data/app/components/marty/promise_view/client/promise_view.js +46 -38
  31. data/app/components/marty/report_form/client/report_form.js +30 -28
  32. data/app/components/marty/report_select/client/report_select.js +28 -23
  33. data/app/components/marty/reporting/client/reporting.js +3 -3
  34. data/app/components/marty/script_form/client/script_form.js +29 -23
  35. data/app/components/marty/script_tester/client/script_tester.js +4 -5
  36. data/app/components/marty/scripting/client/scripting.js +40 -36
  37. data/app/components/marty/simple_app/client/simple_app.js +33 -24
  38. data/app/components/marty/simple_app/client/statusbar_ext.js +1 -1
  39. data/app/controllers/marty/rpc_controller.rb +3 -0
  40. data/app/models/marty/promise.rb +10 -2
  41. data/app/services/marty/data_grid/constraint.rb +2 -1
  42. data/app/services/marty/jobs/schedule.rb +2 -2
  43. data/app/services/marty/promises/delorean/create.rb +9 -2
  44. data/app/services/marty/promises/ruby/create.rb +7 -2
  45. data/config/initializers/delayed_job_config.rb +1 -0
  46. data/delorean/blame_report.dl +50 -58
  47. data/delorean/enum_report.dl +2 -3
  48. data/delorean/{marty_fields.dl → fields.dl} +16 -0
  49. data/delorean/styles.dl +216 -0
  50. data/delorean/table_report.dl +4 -4
  51. data/lib/marty/monkey.rb +17 -0
  52. data/lib/marty/promise_job.rb +9 -0
  53. data/lib/marty/promise_ruby_job.rb +8 -0
  54. data/lib/marty/version.rb +1 -1
  55. data/make-lint.mk +19 -0
  56. data/package.json +16 -0
  57. data/prettier.config.js +6 -0
  58. data/spec/controllers/diagnostic/controller_spec.rb +0 -1
  59. data/spec/controllers/rpc_controller_spec.rb +21 -7
  60. data/spec/dummy/delorean/data_report.dl +4 -4
  61. data/spec/dummy/delorean/fields.dl +1 -0
  62. data/spec/features/data_grid_spec.rb +37 -1
  63. data/spec/job_helper.rb +6 -0
  64. data/spec/lib/data_blame_spec.rb +4 -4
  65. data/spec/lib/data_importer_spec.rb +6 -4
  66. data/spec/models/promise_spec.rb +31 -0
  67. data/spec/spec_helper.rb +8 -0
  68. data/spec/support/download_helper.rb +53 -49
  69. data/spec/support/json_helper.rb +11 -0
  70. data/spec/support/shared_connection_db_helpers.rb +1 -0
  71. data/spec/support/suite.rb +20 -14
  72. data/yarn.lock +967 -0
  73. metadata +16 -4
  74. data/spec/dummy/delorean/marty_fields.dl +0 -1
@@ -0,0 +1,140 @@
1
+ /*
2
+ * File: DateTimeField.js
3
+ *
4
+ * This file requires use of the Ext JS library, under independent license.
5
+ * This is part of the UX for DateTimeField developed by Guilherme Portela
6
+ */
7
+ Ext.define("Ext.ux.DateTimeField", {
8
+ extend: "Ext.form.field.Date",
9
+ alias: "widget.datetimefield",
10
+ requires: ["Ext.ux.DateTimePicker"],
11
+
12
+ //<locale>
13
+ /**
14
+ * @cfg {String} format
15
+ * The default date format string which can be overriden for localization support. The format must be valid
16
+ * according to {@link Ext.Date#parse}.
17
+ */
18
+ format: "m/d/Y H:i",
19
+ //</locale>
20
+ /**
21
+ * @cfg {String} altFormats
22
+ * Multiple date formats separated by "|" to try when parsing a user input value and it does not match the defined
23
+ * format.
24
+ */
25
+ altFormats: "m/d/Y H:i:s|c",
26
+ width: 270,
27
+
28
+ collapseIf(e) {
29
+ const me = this,
30
+ picker = me.picker;
31
+
32
+ if (picker.timePicker && !e.within(picker.timePicker.el, false, true)) {
33
+ me.callParent([e]);
34
+ }
35
+ },
36
+
37
+ createPicker() {
38
+ const me = this,
39
+ parentPicker = this.callParent(),
40
+ parentConfig = Ext.clone(parentPicker.initialConfig),
41
+ initialConfig = Ext.clone(me.initialConfig),
42
+ excludes = ["renderTo", "width", "height", "bind", "reference"];
43
+
44
+ // Avoiding duplicate ids error
45
+ parentPicker.destroy();
46
+
47
+ for (let i = 0; i < excludes.length; i++) {
48
+ if (initialConfig[excludes[i]] !== undefined) {
49
+ delete initialConfig[excludes[i]];
50
+ }
51
+ }
52
+
53
+ return Ext.create(
54
+ "Ext.ux.DateTimePicker",
55
+ Ext.merge(initialConfig, parentConfig)
56
+ );
57
+ },
58
+
59
+ getErrors(value) {
60
+ value =
61
+ arguments.length > 0
62
+ ? value
63
+ : this.formatDate(this.processRawValue(this.getRawValue()));
64
+
65
+ const me = this,
66
+ format = Ext.String.format,
67
+ errors = me.superclass.superclass.getErrors.apply(this, arguments),
68
+ disabledDays = me.disabledDays,
69
+ disabledDatesRE = me.disabledDatesRE,
70
+ minValue = me.minValue,
71
+ maxValue = me.maxValue,
72
+ len = disabledDays ? disabledDays.length : 0;
73
+
74
+ let i = 0,
75
+ day;
76
+
77
+ if (value === null || value.length < 1) {
78
+ // if it's blank and textfield didn't flag it then it's valid
79
+ return errors;
80
+ }
81
+
82
+ const svalue = value;
83
+ value = me.parseDate(value);
84
+ if (!value) {
85
+ errors.push(
86
+ format(me.invalidText, svalue, Ext.Date.unescapeFormat(me.format))
87
+ );
88
+ return errors;
89
+ }
90
+
91
+ const time = value.getTime();
92
+ if (minValue && time < minValue.getTime()) {
93
+ errors.push(format(me.minText, me.formatDate(minValue)));
94
+ }
95
+
96
+ if (maxValue && time > maxValue.getTime()) {
97
+ errors.push(format(me.maxText, me.formatDate(maxValue)));
98
+ }
99
+
100
+ if (disabledDays) {
101
+ day = value.getDay();
102
+
103
+ for (; i < len; i++) {
104
+ if (day === disabledDays[i]) {
105
+ errors.push(me.disabledDaysText);
106
+ break;
107
+ }
108
+ }
109
+ }
110
+
111
+ const fvalue = me.formatDate(value);
112
+ if (disabledDatesRE && disabledDatesRE.test(fvalue)) {
113
+ errors.push(format(me.disabledDatesText, fvalue));
114
+ }
115
+
116
+ return errors;
117
+ },
118
+
119
+ getRefItems() {
120
+ const me = this,
121
+ result = me.callParent();
122
+
123
+ if (me.picker && me.picker.timePicker) {
124
+ result.push(me.picker.timePicker);
125
+ }
126
+
127
+ return result;
128
+ },
129
+
130
+ onExpand() {
131
+ const me = this;
132
+
133
+ me.callParent();
134
+ const timePicker = me.picker && me.picker.timePicker;
135
+
136
+ if (timePicker) {
137
+ me.picker.alignTimePicker();
138
+ }
139
+ }
140
+ });
@@ -1,10 +1,10 @@
1
- Ext.define('Netzke.Grid.EventHandlers', {
2
- override: 'Netzke.Grid.EventHandlers',
3
- netzkeHandleItemdblclick: function(view, record) {
1
+ Ext.define("Netzke.Grid.EventHandlers", {
2
+ override: "Netzke.Grid.EventHandlers",
3
+ netzkeHandleItemdblclick(view, record) {
4
4
  if (this.editsInline) return; // inline editing is handled elsewhere
5
5
 
6
6
  // MONKEY: add view in form capability
7
- var has_perm = (this.permissions || {});
7
+ const has_perm = this.permissions || {};
8
8
  if (has_perm.read !== false && !has_perm.update) {
9
9
  this.doViewInForm(record);
10
10
  } else if (has_perm.update !== false) {
@@ -12,38 +12,40 @@ Ext.define('Netzke.Grid.EventHandlers', {
12
12
  }
13
13
  },
14
14
 
15
- netzkeReloadStore: function(opts={}) {
16
- var store = this.getStore();
15
+ netzkeReloadStore(opts = {}) {
16
+ const store = this.getStore();
17
17
 
18
18
  // MONKEY: add beforenetzkereload and netzkerevent on store
19
- store.fireEvent('beforenetzkereload');
20
- var callback = opts.callback;
19
+ store.fireEvent("beforenetzkereload");
20
+ const callback = opts.callback;
21
21
  opts.callback = function() {
22
- if (callback) { callback() }
23
- store.fireEvent('netzkereload');
24
- }
22
+ if (callback) {
23
+ callback();
24
+ }
25
+ store.fireEvent("netzkereload");
26
+ };
25
27
 
26
28
  // NETZKE'S HACK to work around buffered store's buggy reload()
27
29
  if (!store.lastRequestStart) {
28
30
  store.load(opts);
29
31
  } else store.reload(opts);
30
- },
32
+ }
31
33
  });
32
34
 
33
- Ext.define('Ext.toolbar.Paging', {
34
- override: 'Ext.toolbar.Paging',
35
+ Ext.define("Ext.toolbar.Paging", {
36
+ override: "Ext.toolbar.Paging",
35
37
 
36
38
  handleRefresh: Ext.emptyFn,
37
39
 
38
- doRefresh: function() {
39
- var me = this,
40
+ doRefresh() {
41
+ const me = this,
40
42
  current = me.store.currentPage;
41
43
 
42
44
  // MONKEY: add netzkerefresh to ExtJS paging toolbar refresh
43
45
  // as beforechange is too generic
44
- me.store.fireEvent('netzkerefresh', me);
46
+ me.store.fireEvent("netzkerefresh", me);
45
47
 
46
- if (me.fireEvent('beforechange', me, current) !== false) {
48
+ if (me.fireEvent("beforechange", me, current) !== false) {
47
49
  me.store.loadPage(current);
48
50
 
49
51
  me.handleRefresh();
@@ -51,33 +53,37 @@ Ext.define('Ext.toolbar.Paging', {
51
53
  }
52
54
  });
53
55
 
54
- Ext.define('Netzke.Grid.Columns', {
55
- override: 'Netzke.Grid.Columns',
56
- netzkeNormalizeAssociationRenderer: function(c) {
57
- var passedRenderer = c.renderer, // renderer we got from netzkeNormalizeRenderer
58
- assocValue;
56
+ Ext.define("Netzke.Grid.Columns", {
57
+ override: "Netzke.Grid.Columns",
58
+ netzkeNormalizeAssociationRenderer(c) {
59
+ const passedRenderer = c.renderer; // renderer we got from netzkeNormalizeRenderer
60
+ let assocValue;
59
61
  c.scope = this;
60
- c.renderer = function(value, a, r, ri, ci, store, view){
61
- var column = view.headerCt.items.getAt(ci),
62
- editor = column.getEditor && column.getEditor(),
63
-
64
- /* MONKEY: use findRecordByValue instead of findRecord to remedy inline editing temporarily
62
+ c.renderer = function(value, a, r, ri, ci, store, view) {
63
+ const column = view.headerCt.items.getAt(ci);
64
+ const editor = column.getEditor && column.getEditor();
65
+ /* MONKEY: use findRecordByValue instead of findRecord to remedy inline editing temporarily
65
66
  changing N/A columns to the recently changed value.
66
67
  */
67
- recordFromStore = editor && editor.isXType('combobox') && editor.findRecordByValue(value),
68
- renderedValue;
68
+ const recordFromStore =
69
+ editor && editor.isXType("combobox") && editor.findRecordByValue(value);
70
+ let renderedValue;
69
71
 
70
72
  if (recordFromStore) {
71
- renderedValue = recordFromStore.get('text');
72
- } else if ((assocValue = (r.get('association_values') || {})[c.name]) !== undefined) {
73
- renderedValue = (assocValue == undefined) ? c.emptyText : assocValue;
73
+ renderedValue = recordFromStore.get("text");
74
+ } else if (
75
+ (assocValue = (r.get("association_values") || {})[c.name]) !== undefined
76
+ ) {
77
+ renderedValue = assocValue == undefined ? c.emptyText : assocValue;
74
78
  } else {
75
79
  renderedValue = value;
76
80
  }
77
81
 
78
- return passedRenderer ? passedRenderer.call(this, renderedValue) : renderedValue;
82
+ return passedRenderer
83
+ ? passedRenderer.call(this, renderedValue)
84
+ : renderedValue;
79
85
  };
80
- },
86
+ }
81
87
  });
82
88
 
83
89
  /*
@@ -90,93 +96,93 @@ default.
90
96
  */
91
97
 
92
98
  /**
93
- * @private
94
- * @class Ext.ux.layout.component.field.CodeMirror
95
- * @extends Ext.layout.component.field.Field
96
- * @author Adrian Teodorescu (ateodorescu@gmail.com)
97
- *
98
- * Layout class for {@link Ext.ux.form.field.CodeMirror} fields. Handles sizing the codemirror field.
99
- */
100
- Ext.define('Ext.ux.layout.component.field.CodeMirror', {
101
- extend: 'Ext.layout.component.Auto',
102
- alias: ['layout.codemirror'],
103
-
104
- type: 'codemirror',
105
-
106
- beginLayout: function(ownerContext) {
107
- this.callParent(arguments);
108
-
109
- ownerContext.textAreaContext = ownerContext.getEl('textareaEl');
110
- ownerContext.editorContext = ownerContext.getEl('editorEl');
111
- },
99
+ * @private
100
+ * @class Ext.ux.layout.component.field.CodeMirror
101
+ * @extends Ext.layout.component.field.Field
102
+ * @author Adrian Teodorescu (ateodorescu@gmail.com)
103
+ *
104
+ * Layout class for {@link Ext.ux.form.field.CodeMirror} fields. Handles sizing the codemirror field.
105
+ */
106
+ Ext.define("Ext.ux.layout.component.field.CodeMirror", {
107
+ extend: "Ext.layout.component.Auto",
108
+ alias: ["layout.codemirror"],
109
+
110
+ type: "codemirror",
111
+
112
+ beginLayout(ownerContext) {
113
+ this.callParent(arguments);
114
+
115
+ ownerContext.textAreaContext = ownerContext.getEl("textareaEl");
116
+ ownerContext.editorContext = ownerContext.getEl("editorEl");
117
+ },
112
118
 
113
- renderItems: Ext.emptyFn,
119
+ renderItems: Ext.emptyFn,
114
120
 
115
- getRenderTarget: function() {
116
- return this.owner.bodyEl;
117
- },
121
+ getRenderTarget() {
122
+ return this.owner.bodyEl;
123
+ },
118
124
 
119
- publishInnerHeight: function (ownerContext, height) {
120
- var me = this,
121
- innerHeight = height - me.measureLabelErrorHeight(ownerContext) -
122
- ownerContext.bodyCellContext.getPaddingInfo().height;
123
- if (Ext.isNumber(innerHeight)) {
124
- ownerContext.textAreaContext.setHeight(innerHeight);
125
- ownerContext.editorContext.setHeight(innerHeight);
126
- } else {
127
- me.done = false;
128
- }
129
- },
125
+ publishInnerHeight(ownerContext, height) {
126
+ const me = this,
127
+ innerHeight =
128
+ height -
129
+ me.measureLabelErrorHeight(ownerContext) -
130
+ ownerContext.bodyCellContext.getPaddingInfo().height;
131
+ if (Ext.isNumber(innerHeight)) {
132
+ ownerContext.textAreaContext.setHeight(innerHeight);
133
+ ownerContext.editorContext.setHeight(innerHeight);
134
+ } else {
135
+ me.done = false;
136
+ }
137
+ },
130
138
 
131
- publishInnerWidth: function (ownerContext, width) {
132
- var me = this;
139
+ publishInnerWidth(ownerContext, width) {
140
+ const me = this;
133
141
 
134
- if (Ext.isNumber(width)) {
135
- ownerContext.textAreaContext.setWidth(width);
136
- ownerContext.editorContext.setWidth(width);
137
- } else {
138
- me.done = false;
139
- }
142
+ if (Ext.isNumber(width)) {
143
+ ownerContext.textAreaContext.setWidth(width);
144
+ ownerContext.editorContext.setWidth(width);
145
+ } else {
146
+ me.done = false;
140
147
  }
148
+ }
141
149
  });
142
150
 
143
- Ext.define('Ext.ux.form.field.CodeMirror', {
144
- extend: 'Ext.Component',
145
- mixins: {
146
- labelable: 'Ext.form.Labelable',
147
- field: 'Ext.form.field.Field'
148
- },
149
- alias: 'widget.codemirror',
150
- alternateClassName: 'Ext.form.CodeMirror',
151
- requires: [
152
- 'Ext.tip.QuickTipManager',
153
- 'Ext.util.Format',
154
- 'Ext.ux.layout.component.field.CodeMirror'
155
- ],
156
-
157
- childEls: [
158
- 'editorEl', 'textareaEl'
159
- ],
160
-
161
- fieldSubTpl: [
162
- '<textarea id="{cmpId}-textareaEl" name="{name}" tabIndex="-1" class="{textareaCls}" ',
163
- 'style="{size}" autocomplete="off"></textarea>',
164
- '<div id="{cmpId}-editorEl" class="{editorCls}" name="{editorName}" style="{size}"></div>',
165
- {
166
- disableFormats: true
167
- }
168
- ],
151
+ Ext.define("Ext.ux.form.field.CodeMirror", {
152
+ extend: "Ext.Component",
153
+ mixins: {
154
+ labelable: "Ext.form.Labelable",
155
+ field: "Ext.form.field.Field"
156
+ },
157
+ alias: "widget.codemirror",
158
+ alternateClassName: "Ext.form.CodeMirror",
159
+ requires: [
160
+ "Ext.tip.QuickTipManager",
161
+ "Ext.util.Format",
162
+ "Ext.ux.layout.component.field.CodeMirror"
163
+ ],
164
+
165
+ childEls: ["editorEl", "textareaEl"],
166
+
167
+ fieldSubTpl: [
168
+ '<textarea id="{cmpId}-textareaEl" name="{name}" tabIndex="-1" class="{textareaCls}" ',
169
+ 'style="{size}" autocomplete="off"></textarea>',
170
+ '<div id="{cmpId}-editorEl" class="{editorCls}" name="{editorName}" style="{size}"></div>',
171
+ {
172
+ disableFormats: true
173
+ }
174
+ ],
169
175
 
170
- // FIXME: the layout mechanism is currently busted
171
- // componentLayout: 'codemirror',
176
+ // FIXME: the layout mechanism is currently busted
177
+ // componentLayout: 'codemirror',
172
178
 
173
- editorWrapCls: Ext.baseCSSPrefix + 'html-editor-wrap',
179
+ editorWrapCls: Ext.baseCSSPrefix + "html-editor-wrap",
174
180
 
175
- maskOnDisable: true,
181
+ maskOnDisable: true,
176
182
 
177
- afterBodyEl: '</div>',
183
+ afterBodyEl: "</div>",
178
184
 
179
- /*
185
+ /*
180
186
  // map tabs to 4 spaces -- arman (doesn't work - may need new version)
181
187
  extraKeys: {
182
188
  "Tab": function() {
@@ -185,597 +191,643 @@ Ext.define('Ext.ux.form.field.CodeMirror', {
185
191
  },
186
192
  */
187
193
 
188
- /**
189
- * @cfg {String} mode The default mode to use when the editor is initialized. When not given, this will default to the first mode that was loaded.
190
- * It may be a string, which either simply names the mode or is a MIME type associated with the mode. Alternatively,
191
- * it may be an object containing configuration options for the mode, with a name property that names the mode
192
- * (for example {name: "javascript", json: true}). The demo pages for each mode contain information about what
193
- * configuration parameters the mode supports.
194
- */
195
- mode: 'text/plain',
196
-
197
- /**
198
- * @cfg {Boolean} showAutoIndent Enable auto indent button for indenting the selected range
199
- */
200
- showAutoIndent: true,
201
-
202
- /**
203
- * @cfg {Boolean} showLineNumbers Enable line numbers button in the toolbar.
204
- */
205
- showLineNumbers: true,
206
-
207
- /**
208
- * @cfg {Boolean} enableMatchBrackets Force matching-bracket-highlighting to happen
209
- */
210
- enableMatchBrackets: true,
211
-
212
- /**
213
- * @cfg {Boolean} enableElectricChars Configures whether the editor should re-indent the current line when a character is typed
214
- * that might change its proper indentation (only works if the mode supports indentation).
215
- */
216
- enableElectricChars: false,
217
-
218
- /**
219
- * @cfg {Boolean} enableIndentWithTabs Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs.
220
- */
221
- enableIndentWithTabs: true,
222
-
223
- /**
224
- * @cfg {Boolean} enableSmartIndent Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before).
225
- */
226
- enableSmartIndent: true,
227
-
228
- /**
229
- * @cfg {Boolean} enableLineWrapping Whether CodeMirror should scroll or wrap for long lines.
230
- */
231
- enableLineWrapping: false,
232
-
233
- /**
234
- * @cfg {Boolean} enableLineNumbers Whether to show line numbers to the left of the editor.
235
- */
236
- enableLineNumbers: true,
237
-
238
- /**
239
- * @cfg {Boolean} enableGutter Can be used to force a 'gutter' (empty space on the left of the editor) to be shown even
240
- * when no line numbers are active. This is useful for setting markers.
241
- */
242
- enableGutter: true,
243
-
244
- /**
245
- * @cfg {Boolean} enableFixedGutter When enabled (off by default), this will make the gutter stay visible when the
246
- * document is scrolled horizontally.
247
- */
248
- enableFixedGutter: false,
249
-
250
- /**
251
- * @cfg {Number} firstLineNumber At which number to start counting lines.
252
- */
253
- firstLineNumber: 1,
254
-
255
- /**
256
- * @cfg {Boolean} readOnly <tt>true</tt> to mark the field as readOnly.
257
- */
258
- readOnly : false,
259
-
260
- /**
261
- * @cfg {Number} pollInterval Indicates how quickly (miliseconds) CodeMirror should poll its input textarea for changes.
262
- * Most input is captured by events, but some things, like IME input on some browsers, doesn't generate events
263
- * that allow CodeMirror to properly detect it. Thus, it polls.
264
- */
265
- pollInterval: 100,
266
-
267
- /**
268
- * @cfg {Number} indentUnit How many spaces a block (whatever that means in the edited language) should be indented.
269
- */
270
- indentUnit: 4,
271
-
272
- /**
273
- * @cfg {Number} tabSize The width of a tab character.
274
- */
275
- tabSize: 4,
276
-
277
- /**
278
- * @cfg {String} theme The theme to style the editor with. You must make sure the CSS file defining the corresponding
279
- * .cm-s-[name] styles is loaded (see the theme directory in the distribution). The default is "default", for which
280
- * colors are included in codemirror.css. It is possible to use multiple theming classes at once—for example
281
- * "foo bar" will assign both the cm-s-foo and the cm-s-bar classes to the editor.
282
- */
283
- theme: 'default',
284
-
285
- /**
286
- * @property {String} pathModes Path to the modes folder to dinamically load the required scripts. You could also
287
- * include all your required modes in a big script file and this path will be ignored.
288
- * Do not fill in the trailing slash.
289
- */
290
- pathModes: 'mode',
291
-
292
- /**
293
- * @property {String} pathExtensions Path to the extensions folder to dinamically load the required scripts. You could also
294
- * include all your required extensions in a big script file and this path will be ignored.
295
- * Do not fill in the trailing slash.
296
- */
297
- pathExtensions: 'lib/util',
298
-
299
- /**
300
- * @property {Array} extensions Define here extensions script dependencies; This is used by toolbar buttons to automatically
301
- * load the scripts before using an extension.
302
- */
303
- extensions:{
304
- format: {
305
- dependencies: ['formatting.js']
306
- }
307
- },
194
+ /**
195
+ * @cfg {String} mode The default mode to use when the editor is initialized. When not given, this will default to the first mode that was loaded.
196
+ * It may be a string, which either simply names the mode or is a MIME type associated with the mode. Alternatively,
197
+ * it may be an object containing configuration options for the mode, with a name property that names the mode
198
+ * (for example {name: "javascript", json: true}). The demo pages for each mode contain information about what
199
+ * configuration parameters the mode supports.
200
+ */
201
+ mode: "text/plain",
202
+
203
+ /**
204
+ * @cfg {Boolean} showAutoIndent Enable auto indent button for indenting the selected range
205
+ */
206
+ showAutoIndent: true,
207
+
208
+ /**
209
+ * @cfg {Boolean} showLineNumbers Enable line numbers button in the toolbar.
210
+ */
211
+ showLineNumbers: true,
212
+
213
+ /**
214
+ * @cfg {Boolean} enableMatchBrackets Force matching-bracket-highlighting to happen
215
+ */
216
+ enableMatchBrackets: true,
217
+
218
+ /**
219
+ * @cfg {Boolean} enableElectricChars Configures whether the editor should re-indent the current line when a character is typed
220
+ * that might change its proper indentation (only works if the mode supports indentation).
221
+ */
222
+ enableElectricChars: false,
223
+
224
+ /**
225
+ * @cfg {Boolean} enableIndentWithTabs Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs.
226
+ */
227
+ enableIndentWithTabs: true,
228
+
229
+ /**
230
+ * @cfg {Boolean} enableSmartIndent Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before).
231
+ */
232
+ enableSmartIndent: true,
233
+
234
+ /**
235
+ * @cfg {Boolean} enableLineWrapping Whether CodeMirror should scroll or wrap for long lines.
236
+ */
237
+ enableLineWrapping: false,
238
+
239
+ /**
240
+ * @cfg {Boolean} enableLineNumbers Whether to show line numbers to the left of the editor.
241
+ */
242
+ enableLineNumbers: true,
243
+
244
+ /**
245
+ * @cfg {Boolean} enableGutter Can be used to force a 'gutter' (empty space on the left of the editor) to be shown even
246
+ * when no line numbers are active. This is useful for setting markers.
247
+ */
248
+ enableGutter: true,
249
+
250
+ /**
251
+ * @cfg {Boolean} enableFixedGutter When enabled (off by default), this will make the gutter stay visible when the
252
+ * document is scrolled horizontally.
253
+ */
254
+ enableFixedGutter: false,
255
+
256
+ /**
257
+ * @cfg {Number} firstLineNumber At which number to start counting lines.
258
+ */
259
+ firstLineNumber: 1,
260
+
261
+ /**
262
+ * @cfg {Boolean} readOnly <tt>true</tt> to mark the field as readOnly.
263
+ */
264
+ readOnly: false,
265
+
266
+ /**
267
+ * @cfg {Number} pollInterval Indicates how quickly (miliseconds) CodeMirror should poll its input textarea for changes.
268
+ * Most input is captured by events, but some things, like IME input on some browsers, doesn't generate events
269
+ * that allow CodeMirror to properly detect it. Thus, it polls.
270
+ */
271
+ pollInterval: 100,
272
+
273
+ /**
274
+ * @cfg {Number} indentUnit How many spaces a block (whatever that means in the edited language) should be indented.
275
+ */
276
+ indentUnit: 4,
277
+
278
+ /**
279
+ * @cfg {Number} tabSize The width of a tab character.
280
+ */
281
+ tabSize: 4,
282
+
283
+ /**
284
+ * @cfg {String} theme The theme to style the editor with. You must make sure the CSS file defining the corresponding
285
+ * .cm-s-[name] styles is loaded (see the theme directory in the distribution). The default is "default", for which
286
+ * colors are included in codemirror.css. It is possible to use multiple theming classes at once—for example
287
+ * "foo bar" will assign both the cm-s-foo and the cm-s-bar classes to the editor.
288
+ */
289
+ theme: "default",
290
+
291
+ /**
292
+ * @property {String} pathModes Path to the modes folder to dinamically load the required scripts. You could also
293
+ * include all your required modes in a big script file and this path will be ignored.
294
+ * Do not fill in the trailing slash.
295
+ */
296
+ pathModes: "mode",
297
+
298
+ /**
299
+ * @property {String} pathExtensions Path to the extensions folder to dinamically load the required scripts. You could also
300
+ * include all your required extensions in a big script file and this path will be ignored.
301
+ * Do not fill in the trailing slash.
302
+ */
303
+ pathExtensions: "lib/util",
304
+
305
+ /**
306
+ * @property {Array} extensions Define here extensions script dependencies; This is used by toolbar buttons to automatically
307
+ * load the scripts before using an extension.
308
+ */
309
+ extensions: {
310
+ format: {
311
+ dependencies: ["formatting.js"]
312
+ }
313
+ },
308
314
 
309
- scriptsLoaded: [],
310
- lastMode: '',
315
+ scriptsLoaded: [],
316
+ lastMode: "",
311
317
 
312
- initComponent : function(){
313
- var me = this;
318
+ initComponent() {
319
+ const me = this;
314
320
 
315
- me.callParent(arguments);
321
+ me.callParent(arguments);
316
322
 
317
- me.initLabelable();
318
- me.initField();
323
+ me.initLabelable();
324
+ me.initField();
319
325
 
320
- /*
326
+ /*
321
327
  Fix resize issues as suggested by user koblass on the Extjs forums
322
328
  http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&p=860535&viewfull=1#post860535
323
329
  */
324
- me.on('resize', function() {
325
- if (me.editor) {
326
- me.editor.refresh();
327
- }
328
- }, me);
329
- },
330
-
331
- getMaskTarget: function(){
332
- return this.bodyEl;
333
- },
330
+ me.on(
331
+ "resize",
332
+ function() {
333
+ if (me.editor) {
334
+ me.editor.refresh();
335
+ }
336
+ },
337
+ me
338
+ );
339
+ },
334
340
 
335
- /**
336
- * @private override
337
- */
338
- getSubTplData: function() {
339
- var cssPrefix = Ext.baseCSSPrefix;
340
- return {
341
- $comp : this,
342
- cmpId : this.id,
343
- id : this.getInputId(),
344
- toolbarWrapCls : cssPrefix + 'html-editor-tb',
345
- textareaCls : cssPrefix + 'hidden',
346
- editorCls : cssPrefix + 'codemirror',
347
- editorName : Ext.id(),
348
- //size : 'height:100px;width:100%'
349
- // PennyMac: setting height to 100%.
350
- size : 'height:100%;width:100%',
351
- };
352
- },
341
+ getMaskTarget() {
342
+ return this.bodyEl;
343
+ },
353
344
 
354
- getSubTplMarkup: function() {
355
- return this.getTpl('fieldSubTpl').apply(this.getSubTplData());
356
- },
345
+ /**
346
+ * @private override
347
+ */
348
+ getSubTplData() {
349
+ const cssPrefix = Ext.baseCSSPrefix;
350
+ return {
351
+ $comp: this,
352
+ cmpId: this.id,
353
+ id: this.getInputId(),
354
+ toolbarWrapCls: cssPrefix + "html-editor-tb",
355
+ textareaCls: cssPrefix + "hidden",
356
+ editorCls: cssPrefix + "codemirror",
357
+ editorName: Ext.id(),
358
+ //size : 'height:100px;width:100%'
359
+ // PennyMac: setting height to 100%.
360
+ size: "height:100%;width:100%"
361
+ };
362
+ },
357
363
 
358
- /**
359
- * @private override
360
- */
361
- onRender: function() {
362
- var me = this;
364
+ getSubTplMarkup() {
365
+ return this.getTpl("fieldSubTpl").apply(this.getSubTplData());
366
+ },
363
367
 
364
- me.callParent(arguments);
365
- me.editorEl = me.getEl('editorEl');
366
- me.bodyEl = me.getEl('bodyEl');
368
+ /**
369
+ * @private override
370
+ */
371
+ onRender() {
372
+ const me = this;
367
373
 
368
- me.disableItems(true);
369
- me.initEditor();
374
+ me.callParent(arguments);
375
+ me.editorEl = me.getEl("editorEl");
376
+ me.bodyEl = me.getEl("bodyEl");
370
377
 
371
- me.rendered = true;
372
- },
378
+ me.disableItems(true);
379
+ me.initEditor();
373
380
 
374
- initRenderData: function() {
375
- this.beforeSubTpl = '<div class="' + this.editorWrapCls + '">';
376
- return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
377
- },
381
+ me.rendered = true;
382
+ },
378
383
 
379
- /**
380
- * @private override
381
- */
382
- initEditor : function(){
383
- var me = this;
384
- var mode = me.mode;
385
-
386
- // if no mode is loaded we could get an error like "Object #<Object> has no method 'startState'"
387
- // search mime to find script dependencies
388
- var item = me.getMime(me.mode);
389
- if(item) {
390
- mode = me.getMimeMode(me.mode);
391
- if(!mode){
392
- mode = "text/x-delorean";
393
- }
394
- }
384
+ initRenderData() {
385
+ this.beforeSubTpl = '<div class="' + this.editorWrapCls + '">';
386
+ return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
387
+ },
395
388
 
396
- me.editor = CodeMirror(me.editorEl, {
397
- matchBrackets: me.enableMatchBrackets,
398
- electricChars: me.enableElectricChars,
399
- autoClearEmptyLines:true,
400
- value: me.rawValue || "",
401
- indentUnit: me.indentUnit,
402
- smartIndent: me.enableSmartIndent,
403
- indentWithTabs: me.indentWithTabs,
404
- pollInterval: me.pollInterval,
405
- lineNumbers: me.enableLineNumbers,
406
- lineWrapping: me.enableLineWrapping,
407
- firstLineNumber: me.firstLineNumber,
408
- tabSize: me.tabSize,
409
- gutter: me.enableGutter,
410
- fixedGutter: me.enableFixedGutter,
411
- theme: me.theme,
412
- mode: mode,
413
- onChange: function(editor, tc){
414
- me.checkChange();
415
- //me.fireEvent('change', me, tc.from, tc.to, tc.text, tc.next || null);
416
- },
417
- onCursorActivity: function(editor){
418
- me.fireEvent('cursoractivity', me);
419
- },
420
- onGutterClick: function(editor, line, event){
421
- me.fireEvent('gutterclick', me, line, event);
422
- },
423
- onFocus: function(editor){
424
- me.fireEvent('activate', me);
425
- },
426
- onBlur: function(editor){
427
- me.fireEvent('deactivate', me);
428
- },
429
- onScroll: function(editor){
430
- me.fireEvent('scroll', me);
431
- },
432
- onHighlightComplete: function(editor){
433
- me.fireEvent('highlightcomplete', me);
434
- },
435
- onUpdate: function(editor){
436
- me.fireEvent('update', me);
437
- },
438
- onKeyEvent: function(editor, event){
439
- event.cancelBubble = true; // fix suggested by koblass user on Sencha forums (http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&p=862029&viewfull=1#post862029)
440
- me.fireEvent('keyevent', me, event);
441
- }
442
- });
443
- //me.editor.setValue(me.rawValue);
444
- me.setMode(me.mode);
445
- me.setReadOnly(me.readOnly);
446
- me.fireEvent('initialize', me);
447
-
448
- // change the codemirror css
449
- var css = Ext.util.CSS.getRule('.CodeMirror');
450
- if(css){
451
- css.style.height = '100%';
452
- css.style.position = 'relative';
453
- css.style.overflow = 'hidden';
454
- }
455
- var css = Ext.util.CSS.getRule('.CodeMirror-Scroll');
456
- if(css){
457
- css.style.height = '100%';
458
- }
389
+ /**
390
+ * @private override
391
+ */
392
+ initEditor() {
393
+ const me = this;
394
+ let mode = me.mode;
395
+
396
+ // if no mode is loaded we could get an error like "Object #<Object> has no method 'startState'"
397
+ // search mime to find script dependencies
398
+ const item = me.getMime(me.mode);
399
+ if (item) {
400
+ mode = me.getMimeMode(me.mode);
401
+ if (!mode) {
402
+ mode = "text/x-delorean";
403
+ }
404
+ }
459
405
 
460
- // PennyMac: align the body to the top. Otherwise it ends up
461
- // in the center of the enclosing table.
462
- var el = document.getElementById(me.bodyEl.id);
463
- el.setAttribute("valign", "top");
464
- },
406
+ me.editor = CodeMirror(me.editorEl, {
407
+ matchBrackets: me.enableMatchBrackets,
408
+ electricChars: me.enableElectricChars,
409
+ autoClearEmptyLines: true,
410
+ value: me.rawValue || "",
411
+ indentUnit: me.indentUnit,
412
+ smartIndent: me.enableSmartIndent,
413
+ indentWithTabs: me.indentWithTabs,
414
+ pollInterval: me.pollInterval,
415
+ lineNumbers: me.enableLineNumbers,
416
+ lineWrapping: me.enableLineWrapping,
417
+ firstLineNumber: me.firstLineNumber,
418
+ tabSize: me.tabSize,
419
+ gutter: me.enableGutter,
420
+ fixedGutter: me.enableFixedGutter,
421
+ theme: me.theme,
422
+ mode,
423
+ onChange() {
424
+ me.checkChange();
425
+ //me.fireEvent('change', me, tc.from, tc.to, tc.text, tc.next || null);
426
+ },
427
+ onCursorActivity() {
428
+ me.fireEvent("cursoractivity", me);
429
+ },
430
+ onGutterClick(editor, line, event) {
431
+ me.fireEvent("gutterclick", me, line, event);
432
+ },
433
+ onFocus() {
434
+ me.fireEvent("activate", me);
435
+ },
436
+ onBlur() {
437
+ me.fireEvent("deactivate", me);
438
+ },
439
+ onScroll() {
440
+ me.fireEvent("scroll", me);
441
+ },
442
+ onHighlightComplete() {
443
+ me.fireEvent("highlightcomplete", me);
444
+ },
445
+ onUpdate() {
446
+ me.fireEvent("update", me);
447
+ },
448
+ onKeyEvent(editor, event) {
449
+ event.cancelBubble = true; // fix suggested by koblass user on Sencha forums (http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&p=862029&viewfull=1#post862029)
450
+ me.fireEvent("keyevent", me, event);
451
+ }
452
+ });
453
+ //me.editor.setValue(me.rawValue);
454
+ me.setMode(me.mode);
455
+ me.setReadOnly(me.readOnly);
456
+ me.fireEvent("initialize", me);
457
+
458
+ // change the codemirror css
459
+ const css1 = Ext.util.CSS.getRule(".CodeMirror");
460
+ if (css1) {
461
+ css1.style.height = "100%";
462
+ css1.style.position = "relative";
463
+ css1.style.overflow = "hidden";
464
+ }
465
465
 
466
- /**
467
- * @private
468
- */
469
- relayBtnCmd: function(btn){
470
- this.relayCmd(btn.getItemId());
471
- },
466
+ const css2 = Ext.util.CSS.getRule(".CodeMirror-Scroll");
467
+ if (css2) {
468
+ css2.style.height = "100%";
469
+ }
472
470
 
473
- /**
474
- * @private
475
- */
476
- relayCmd: function(cmd){
477
- Ext.defer(function() {
478
- var me = this;
479
- me.editor.focus();
480
- switch(cmd){
481
- // auto formatting
482
- case 'justifycenter':
483
- if(!CodeMirror.extensions.autoIndentRange){
484
- me.loadDependencies(me.extensions.format, me.pathExtensions, me.doIndentSelection, me);
485
- }else{
486
- me.doIndentSelection();
487
- }
488
- break;
489
-
490
- // line numbers
491
- case 'insertorderedlist':
492
- me.doChangeLineNumbers();
493
- break;
494
- }
495
- }, 10, this);
496
- },
471
+ // PennyMac: align the body to the top. Otherwise it ends up
472
+ // in the center of the enclosing table.
473
+ const el = document.getElementById(me.bodyEl.id);
474
+ el.setAttribute("valign", "top");
475
+ },
497
476
 
498
- /**
499
- * @private
500
- * Reload all CodeMirror extensions for the current instance;
501
- *
502
- */
503
- reloadExtentions: function(){
504
- var me = this;
477
+ /**
478
+ * @private
479
+ */
480
+ relayBtnCmd(btn) {
481
+ this.relayCmd(btn.getItemId());
482
+ },
505
483
 
506
- for (var ext in CodeMirror.extensions)
507
- if (CodeMirror.extensions.propertyIsEnumerable(ext) &&
508
- !me.editor.propertyIsEnumerable(ext))
509
- me.editor[ext] = CodeMirror.extensions[ext];
510
- },
484
+ /**
485
+ * @private
486
+ */
487
+ relayCmd(cmd) {
488
+ Ext.defer(
489
+ function() {
490
+ const me = this;
491
+ me.editor.focus();
492
+ switch (cmd) {
493
+ // auto formatting
494
+ case "justifycenter":
495
+ if (!CodeMirror.extensions.autoIndentRange) {
496
+ me.loadDependencies(
497
+ me.extensions.format,
498
+ me.pathExtensions,
499
+ me.doIndentSelection,
500
+ me
501
+ );
502
+ } else {
503
+ me.doIndentSelection();
504
+ }
505
+ break;
511
506
 
512
- doChangeLineNumbers: function(){
513
- var me = this;
507
+ // line numbers
508
+ case "insertorderedlist":
509
+ me.doChangeLineNumbers();
510
+ break;
511
+ }
512
+ },
513
+ 10,
514
+ this
515
+ );
516
+ },
514
517
 
515
- me.enableLineNumbers = !me.enableLineNumbers;
516
- me.editor.setOption('lineNumbers', me.enableLineNumbers);
517
- },
518
+ /**
519
+ * @private
520
+ * Reload all CodeMirror extensions for the current instance;
521
+ *
522
+ */
523
+ reloadExtentions() {
524
+ const me = this;
525
+
526
+ for (const ext in CodeMirror.extensions)
527
+ if (
528
+ Object.prototype.propertyIsEnumerable.call(
529
+ CodeMirror.extensions,
530
+ ext
531
+ ) &&
532
+ !Object.prototype.propertyIsEnumerable.call(me.editor, ext)
533
+ )
534
+ me.editor[ext] = CodeMirror.extensions[ext];
535
+ },
518
536
 
519
- /**
520
- * @private
521
- */
522
- doIndentSelection: function(){
523
- var me = this;
537
+ doChangeLineNumbers() {
538
+ const me = this;
524
539
 
525
- me.reloadExtentions();
540
+ me.enableLineNumbers = !me.enableLineNumbers;
541
+ me.editor.setOption("lineNumbers", me.enableLineNumbers);
542
+ },
526
543
 
527
- try{
528
- var range = { from: me.editor.getCursor(true), to: me.editor.getCursor(false) };
529
- me.editor.autoIndentRange(range.from, range.to);
530
- }catch(err){}
531
- },
544
+ /**
545
+ * @private
546
+ */
547
+ doIndentSelection() {
548
+ const me = this;
549
+
550
+ me.reloadExtentions();
551
+
552
+ try {
553
+ const range = {
554
+ from: me.editor.getCursor(true),
555
+ to: me.editor.getCursor(false)
556
+ };
557
+ me.editor.autoIndentRange(range.from, range.to);
558
+ } catch (err) {
559
+ // do nothing
560
+ }
561
+ },
532
562
 
533
- modes: [
534
- {
535
- mime: CodeMirror.mimeModes,
536
- dependencies: []
537
- },
538
- ],
563
+ modes: [
564
+ {
565
+ mime: CodeMirror.mimeModes,
566
+ dependencies: []
567
+ }
568
+ ],
569
+
570
+ /**
571
+ * @private
572
+ */
573
+ getMime(mime) {
574
+ const me = this;
575
+ let item,
576
+ found = false;
577
+
578
+ for (let i = 0; i < me.modes.length; i++) {
579
+ item = me.modes[i];
580
+ if (Ext.isArray(item.mime)) {
581
+ if (Ext.Array.contains(item.mime, mime)) {
582
+ found = true;
583
+ break;
584
+ }
585
+ } else {
586
+ if (item == mime) {
587
+ found = true;
588
+ break;
589
+ }
590
+ }
591
+ }
592
+ if (found) return item;
593
+ else return null;
594
+ },
539
595
 
540
- /**
541
- * @private
542
- */
543
- getMime: function(mime){
544
- var me = this, item, found = false;
545
-
546
- for(var i=0;i<me.modes.length;i++){
547
- item = me.modes[i];
548
- if(Ext.isArray(item.mime)){
549
- if(Ext.Array.contains(item.mime, mime)){
550
- found = true;
551
- break;
552
- }
553
- }else{
554
- if(item == mime){
555
- found = true;
556
- break;
596
+ /**
597
+ * @private
598
+ */
599
+ loadDependencies(item, path, handler, scope) {
600
+ const me = this;
601
+
602
+ me.scripts = [];
603
+ me.scriptIndex = -1;
604
+
605
+ // load the dependencies
606
+ for (let i = 0; i < item.dependencies.length; i++) {
607
+ if (
608
+ !Ext.Array.contains(me.scriptsLoaded, path + "/" + item.dependencies[i])
609
+ ) {
610
+ const options = {
611
+ url: path + "/" + item.dependencies[i],
612
+ index: ++me.scriptIndex,
613
+ onLoad() {
614
+ let ok = true;
615
+ for (let j = 0; j < me.scripts.length; j++) {
616
+ if (me.scripts[j].called) {
617
+ // this event could be raised before one script if fetched
618
+ ok = ok && me.scripts[j].success;
619
+ if (
620
+ me.scripts[j].success &&
621
+ !Ext.Array.contains(me.scriptsLoaded, me.scripts[j].url)
622
+ ) {
623
+ me.scriptsLoaded.push(me.scripts[j].url);
557
624
  }
625
+ } else {
626
+ ok = false;
627
+ }
558
628
  }
559
- }
560
- if(found)
561
- return item;
562
- else
563
- return null;
564
- },
565
-
566
- /**
567
- * @private
568
- */
569
- loadDependencies: function(item, path, handler, scope){
570
- var me = this;
571
-
572
- me.scripts = [];
573
- me.scriptIndex = -1;
574
-
575
- // load the dependencies
576
- for(var i=0; i < item.dependencies.length; i++){
577
- if(!Ext.Array.contains(me.scriptsLoaded, path + '/' + item.dependencies[i])){
578
- var options = {
579
- url: path + '/' + item.dependencies[i],
580
- index: ++me.scriptIndex,
581
- onLoad: function(options){
582
- var ok = true;
583
- for(j=0; j < me.scripts.length; j++){
584
- if(me.scripts[j].called) {// this event could be raised before one script if fetched
585
- ok = ok && me.scripts[j].success;
586
- if(me.scripts[j].success && !Ext.Array.contains(me.scriptsLoaded, me.scripts[j].url)){
587
- me.scriptsLoaded.push(me.scripts[j].url);
588
- }
589
- }else{
590
- ok = false;
591
- }
592
- }
593
- if(ok){
594
- handler.call(scope || me.editor);
595
- }
596
- }
597
- };
598
-
599
- me.scripts[me.scriptIndex] = {
600
- url: options.url,
601
- success: true,
602
- called: false,
603
- options: options,
604
- onLoad: options.onLoad || Ext.emptyFn,
605
- onError: options.onError || Ext.emptyFn
606
- };
629
+ if (ok) {
630
+ handler.call(scope || me.editor);
607
631
  }
608
- }
609
- for(var i=0; i < me.scripts.length; i++){
610
- me.loadScript(me.scripts[i].options);
611
- }
612
- },
632
+ }
633
+ };
613
634
 
614
- /**
615
- * @private
616
- */
617
- loadScript: function(options){
618
- var me = this;
619
- Ext.Ajax.request({
620
- url: options.url,
621
- scriptIndex: options.index,
622
- success: function(response, options) {
623
- var script = 'Ext.getCmp("' + this.id + '").scripts[' + options.scriptIndex + ']';
624
- window.setTimeout('try { ' + response.responseText + ' } catch(e) { '+script+'.success = false; '+script+'.onError('+script+'.options, e); }; ' + script + '.called = true; if ('+script+'.success) '+script+'.onLoad('+script+'.options);', 0);
625
- },
626
- failure: function(response, options) {
627
- var script = this.scripts[options.scriptIndex];
628
- script.success = false;
629
- script.called = true;
630
- script.onError(script.options, response.status);
631
- },
632
- scope: me
633
- });
634
- },
635
+ me.scripts[me.scriptIndex] = {
636
+ url: options.url,
637
+ success: true,
638
+ called: false,
639
+ options,
640
+ onLoad: options.onLoad || Ext.emptyFn,
641
+ onError: options.onError || Ext.emptyFn
642
+ };
643
+ }
644
+ }
635
645
 
636
- /**
637
- * @private
638
- * Return mode depending on the mime; If the mime is not loaded then return null
639
- *
640
- * @param mime
641
- */
642
- getMimeMode: function(mime){
643
- var mode = null;
644
- var mimes = CodeMirror.mimeModes;
645
- for(var i=0; i<mimes.length; i++){
646
- if(mimes[i].mime == mime){
647
- mode = mimes[i].mode;
648
- if(typeof mode == "object")
649
- mode = mode.name;
650
- break;
651
- }
652
- }
653
- return mode;
654
- },
646
+ for (let k = 0; k < me.scripts.length; k++) {
647
+ me.loadScript(me.scripts[k].options);
648
+ }
649
+ },
655
650
 
656
- /**
657
- * Change the CodeMirror mode to the specified mime.
658
- *
659
- * @param {String} mime The MIME value according to the CodeMirror documentation
660
- */
661
- setMode: function(mime){
662
- var me = this,
663
- found = false;
664
- // search mime to find script dependencies
665
- var item = me.getMime(mime);
666
-
667
- if(!item) {
668
- // mime not found
669
- return;
670
- }
651
+ /**
652
+ * @private
653
+ */
654
+ loadScript(options) {
655
+ const me = this;
656
+ Ext.Ajax.request({
657
+ url: options.url,
658
+ scriptIndex: options.index,
659
+ success(response, options) {
660
+ const script =
661
+ 'Ext.getCmp("' + this.id + '").scripts[' + options.scriptIndex + "]";
662
+ window.setTimeout(
663
+ "try { " +
664
+ response.responseText +
665
+ " } catch(e) { " +
666
+ script +
667
+ ".success = false; " +
668
+ script +
669
+ ".onError(" +
670
+ script +
671
+ ".options, e); }; " +
672
+ script +
673
+ ".called = true; if (" +
674
+ script +
675
+ ".success) " +
676
+ script +
677
+ ".onLoad(" +
678
+ script +
679
+ ".options);",
680
+ 0
681
+ );
682
+ },
683
+ failure(response, options) {
684
+ const script = this.scripts[options.scriptIndex];
685
+ script.success = false;
686
+ script.called = true;
687
+ script.onError(script.options, response.status);
688
+ },
689
+ scope: me
690
+ });
691
+ },
671
692
 
672
- var mode = me.getMimeMode(mime);
673
-
674
- if(!mode){
675
- me.loadDependencies(item, me.pathModes, function(){
676
- var mode = me.getMimeMode(mime);
677
- if(typeof mode == "string")
678
- me.editor.setOption('mode', mime);
679
- else
680
- me.editor.setOption('mode', mode);
681
- });
682
- }else{
683
- if(typeof mode == "string")
684
- me.editor.setOption('mode', mime);
685
- else
686
- me.editor.setOption('mode', mode);
687
- }
693
+ /**
694
+ * @private
695
+ * Return mode depending on the mime; If the mime is not loaded then return null
696
+ *
697
+ * @param mime
698
+ */
699
+ getMimeMode(mime) {
700
+ let mode = null;
701
+ const mimes = CodeMirror.mimeModes;
702
+ for (let i = 0; i < mimes.length; i++) {
703
+ if (mimes[i].mime == mime) {
704
+ mode = mimes[i].mode;
705
+ if (typeof mode == "object") mode = mode.name;
706
+ break;
707
+ }
708
+ }
709
+ return mode;
710
+ },
688
711
 
689
- if(me.modesSelect){
690
- me.modesSelect.dom.value = mime;
691
- }
692
- try{
693
- me.fireEvent('modechanged', me, mime, me.lastMode);
694
- me.lastMode = mime;
695
- }catch(err){}
696
- },
712
+ /**
713
+ * Change the CodeMirror mode to the specified mime.
714
+ *
715
+ * @param {String} mime The MIME value according to the CodeMirror documentation
716
+ */
717
+ setMode(mime) {
718
+ const me = this;
719
+ // found = false;
720
+ // search mime to find script dependencies
721
+ const item = me.getMime(mime);
722
+
723
+ if (!item) {
724
+ // mime not found
725
+ return;
726
+ }
697
727
 
698
- /**
699
- * Set the editor as read only
700
- *
701
- * @param {Boolean} readOnly
702
- */
703
- setReadOnly: function(readOnly) {
704
- var me = this;
728
+ const mode = me.getMimeMode(mime);
729
+
730
+ if (!mode) {
731
+ me.loadDependencies(item, me.pathModes, function() {
732
+ const mode = me.getMimeMode(mime);
733
+ if (typeof mode == "string") me.editor.setOption("mode", mime);
734
+ else me.editor.setOption("mode", mode);
735
+ });
736
+ } else {
737
+ if (typeof mode == "string") me.editor.setOption("mode", mime);
738
+ else me.editor.setOption("mode", mode);
739
+ }
705
740
 
706
- if(me.editor){
707
- me.editor.setOption('readOnly', readOnly);
708
- me.disableItems(readOnly);
709
- }
710
- },
741
+ if (me.modesSelect) {
742
+ me.modesSelect.dom.value = mime;
743
+ }
744
+ try {
745
+ me.fireEvent("modechanged", me, mime, me.lastMode);
746
+ me.lastMode = mime;
747
+ } catch (err) {
748
+ // do nothing
749
+ }
750
+ },
711
751
 
712
- onDisable: function() {
713
- this.bodyEl.mask();
714
- this.callParent(arguments);
715
- },
752
+ /**
753
+ * Set the editor as read only
754
+ *
755
+ * @param {Boolean} readOnly
756
+ */
757
+ setReadOnly(readOnly) {
758
+ const me = this;
759
+
760
+ if (me.editor) {
761
+ me.editor.setOption("readOnly", readOnly);
762
+ me.disableItems(readOnly);
763
+ }
764
+ },
716
765
 
717
- onEnable: function() {
718
- this.bodyEl.unmask();
719
- this.callParent(arguments);
720
- },
766
+ onDisable() {
767
+ this.bodyEl.mask();
768
+ this.callParent(arguments);
769
+ },
721
770
 
722
- disableItems: function(disabled) {
723
- },
771
+ onEnable() {
772
+ this.bodyEl.unmask();
773
+ this.callParent(arguments);
774
+ },
724
775
 
725
- /**
726
- * Sets a data value into the field and runs the change detection.
727
- * @param {Mixed} value The value to set
728
- * @return {Ext.ux.form.field.CodeMirror} this
729
- */
730
- setValue: function(value){
731
- var me = this;
732
-
733
- me.mixins.field.setValue.call(me, value);
734
- me.rawValue = value;
735
- if(me.editor)
736
- me.editor.setValue(value);
737
- return me;
738
- },
776
+ disableItems() {},
739
777
 
740
- /**
741
- * Return submit value to the owner form.
742
- * @return {Mixed} The field value
743
- */
744
- getSubmitValue: function(){
745
- var me = this;
746
- return me.getValue();
747
- },
778
+ /**
779
+ * Sets a data value into the field and runs the change detection.
780
+ * @param {Mixed} value The value to set
781
+ * @return {Ext.ux.form.field.CodeMirror} this
782
+ */
783
+ setValue(value) {
784
+ const me = this;
748
785
 
749
- /**
750
- * Return the value of the CodeMirror editor
751
- * @return {Mixed} The field value
752
- */
753
- getValue: function(){
754
- var me = this;
786
+ me.mixins.field.setValue.call(me, value);
787
+ me.rawValue = value;
788
+ if (me.editor) me.editor.setValue(value);
789
+ return me;
790
+ },
755
791
 
756
- if(me.editor)
757
- return me.editor.getValue();
758
- else
759
- return null;
760
- },
792
+ /**
793
+ * Return submit value to the owner form.
794
+ * @return {Mixed} The field value
795
+ */
796
+ getSubmitValue() {
797
+ const me = this;
798
+ return me.getValue();
799
+ },
761
800
 
762
- /**
763
- * @private
764
- */
765
- onDestroy: function(){
766
- var me = this;
767
- if(me.rendered){
768
- try {
769
- Ext.EventManager.removeAll(me.editor);
770
- for (prop in me.editor) {
771
- if (me.editor.hasOwnProperty(prop)) {
772
- delete me.editor[prop];
773
- }
774
- }
775
- }catch(e){}
801
+ /**
802
+ * Return the value of the CodeMirror editor
803
+ * @return {Mixed} The field value
804
+ */
805
+ getValue() {
806
+ const me = this;
807
+
808
+ if (me.editor) return me.editor.getValue();
809
+ else return null;
810
+ },
811
+
812
+ /**
813
+ * @private
814
+ */
815
+ onDestroy() {
816
+ const me = this;
817
+ if (me.rendered) {
818
+ try {
819
+ Ext.EventManager.removeAll(me.editor);
820
+ for (const prop in me.editor) {
821
+ if (Object.prototype.hasOwnProperty.call(me.editor, prop)) {
822
+ delete me.editor[prop];
823
+ }
776
824
  }
777
- me.callParent();
778
- },
825
+ } catch (e) {
826
+ // do nothing
827
+ }
828
+ }
829
+ me.callParent();
830
+ }
779
831
  });
780
832
 
781
833
  // There is an error with code tester. Sometimes the Ext app craches when you click test again after some time passed
@@ -788,144 +840,156 @@ Ext.define('Ext.ux.form.field.CodeMirror', {
788
840
  // check for outerCt.destroyed value. If it's destroyed then it's dom is gone and
789
841
  // and it's style and dimentions are not available
790
842
  // If it's not destroyed go with regular way
791
- Ext.define('Marty.layout.container.Auto', {
792
- override: 'Ext.layout.container.Auto',
793
-
794
- // Sometimes outerCt is already destroyed. in that case it's DOM is null and all methods
795
- // that call DOM should not be called
796
- beginLayoutCycle: function(ownerContext) {
797
- var me = this,
798
- outerCt = me.outerCt,
799
- lastOuterCtWidth = me.lastOuterCtWidth || '',
800
- lastOuterCtHeight = me.lastOuterCtHeight || '',
801
- lastOuterCtTableLayout = me.lastOuterCtTableLayout || '',
802
- state = ownerContext.state,
803
- overflowXStyle, outerCtWidth, outerCtHeight, outerCtTableLayout, inheritedStateInner;
804
-
805
- // FIX
806
- //- me.callParent(arguments);
807
- // If callParent would call overriden method, which leads to and exception
808
- // when outerCt is destroyed. In that case we use callSuper, which ignores overriden method.
809
- // If outerCt is not destroyed, then we call overriden method and exit the function. Fixes bellow are not needed
810
- if (outerCt.destroyed) {
811
- me.callSuper(arguments);
812
- } else {
813
- return me.callParent(arguments);
814
- }
815
-
816
- // Default to "shrink wrap styles".
817
- outerCtWidth = outerCtHeight = outerCtTableLayout = '';
818
- if (!ownerContext.widthModel.shrinkWrap) {
819
- // if we're not shrink wrapping width, we need to get the innerCt out of the
820
- // way to avoid any shrink wrapping effect on child items
821
- // fill the available width within the container
822
- outerCtWidth = '100%';
823
- inheritedStateInner = me.owner.inheritedStateInner;
824
- // expand no further than the available width, even if contents are wider
825
- // unless there is a potential for horizontal overflow, then allow
826
- // the outerCt to expand to the width of the contents
827
- overflowXStyle = me.getOverflowXStyle(ownerContext);
828
- outerCtTableLayout = (inheritedStateInner.inShrinkWrapTable || overflowXStyle === 'auto' || overflowXStyle === 'scroll') ? '' : 'fixed';
829
- }
830
- if (!ownerContext.heightModel.shrinkWrap && !Ext.supports.PercentageHeightOverflowBug) {
831
- // if we're not shrink wrapping height, we need to get the outerCt out of the
832
- // way so that percentage height children will be sized correctly. We do this
833
- // by giving the outerCt a height of '100%' unless the browser is affected by
834
- // the "percentage height overflow bug", in which case the outerCt will get a
835
- // pixel height set during the calculate phase after we know the targetEl size.
836
- outerCtHeight = '100%';
837
- }
838
- // if the outerCt width changed since last time (becuase of a widthModel change)
839
- // or if we set a pixel width on the outerCt last time to work around a browser-
840
- // specific bug, we need to set the width of the outerCt
841
- if ((outerCtWidth !== lastOuterCtWidth) || me.hasOuterCtPxWidth) {
842
- // FIX: Added check for !outerCt.destroyed
843
- if (!outerCt.destroyed) {
844
- outerCt.setStyle('width', outerCtWidth);
845
- }
846
- me.lastOuterCtWidth = outerCtWidth;
847
- me.hasOuterCtPxWidth = false;
848
- }
849
- // Set the outerCt table-layout property if different from last time.
850
- if (outerCtTableLayout !== lastOuterCtTableLayout) {
851
- outerCt.setStyle('table-layout', outerCtTableLayout);
852
- me.lastOuterCtTableLayout = outerCtTableLayout;
853
- }
854
- // if the outerCt height changed since last time (becuase of a heightModel change)
855
- // or if we set a pixel height on the outerCt last time to work around a browser-
856
- // specific bug, we need to set the height of the outerCt
857
- if ((outerCtHeight !== lastOuterCtHeight) || me.hasOuterCtPxHeight) {
858
- // FIX: Added check for !outerCt.destroyed
859
- if (!outerCt.destroyed) {
860
- outerCt.setStyle('height', outerCtHeight);
861
- }
862
- me.lastOuterCtHeight = outerCtHeight;
863
- me.hasOuterCtPxHeight = false;
864
- }
865
- if (me.hasInnerCtPxHeight) {
866
- // FIX: Added check for !innerCt.destroyed
867
- if (!me.innerCt.destroyed) {
868
- me.innerCt.setStyle('height', '');
869
- }
870
- me.hasInnerCtPxHeight = false;
871
- }
872
- // Begin with the scrollbar adjustment that we used last time - this is more likely
873
- // to be correct than beginning with no adjustment at all, but only if it is not
874
- // already defined - it may have already been set by invalidate()
875
- state.overflowAdjust = state.overflowAdjust || me.lastOverflowAdjust;
876
- },
843
+ Ext.define("Marty.layout.container.Auto", {
844
+ override: "Ext.layout.container.Auto",
845
+
846
+ // Sometimes outerCt is already destroyed. in that case it's DOM is null and all methods
847
+ // that call DOM should not be called
848
+ beginLayoutCycle(ownerContext) {
849
+ const me = this;
850
+ const outerCt = me.outerCt;
851
+ const lastOuterCtWidth = me.lastOuterCtWidth || "";
852
+ const lastOuterCtHeight = me.lastOuterCtHeight || "";
853
+ const lastOuterCtTableLayout = me.lastOuterCtTableLayout || "";
854
+ const state = ownerContext.state;
855
+ let overflowXStyle;
856
+ let outerCtWidth;
857
+ let outerCtHeight;
858
+ let outerCtTableLayout;
859
+ let inheritedStateInner;
860
+
861
+ // FIX
862
+ //- me.callParent(arguments);
863
+ // If callParent would call overriden method, which leads to and exception
864
+ // when outerCt is destroyed. In that case we use callSuper, which ignores overriden method.
865
+ // If outerCt is not destroyed, then we call overriden method and exit the function. Fixes bellow are not needed
866
+ if (outerCt.destroyed) {
867
+ me.callSuper(arguments);
868
+ } else {
869
+ return me.callParent(arguments);
870
+ }
877
871
 
878
- // The fix checks whether outerCt is destroyed or not
879
- // If it's destroyed, then the dom is gone and calling getHeight() would lead to exception
880
- // set contentHeight to 0 if outerCt is destroyed
881
- measureContentHeight: function(ownerContext) {
882
- // contentHeight includes padding, but not border, framing or margins
883
- // FIX
884
- // var contentHeight = this.outerCt.getHeight();
885
- var contentHeight = this.outerCt.destroyed ? 0 : this.outerCt.getHeight();
886
- // END FIX
887
- var target = ownerContext.target;
888
-
889
- if (this.managePadding && (target[target.contentPaddingProperty] === undefined)) {
890
- // if padding was not configured using the appropriate contentPaddingProperty
891
- // then the padding will not be on the paddingContext, and therfore not included
892
- // in the outerCt measurement, so we need to read the padding from the
893
- // targetContext
894
- contentHeight += ownerContext.targetContext.getPaddingInfo().height;
872
+ // Default to "shrink wrap styles".
873
+ outerCtWidth = outerCtHeight = outerCtTableLayout = "";
874
+ if (!ownerContext.widthModel.shrinkWrap) {
875
+ // if we're not shrink wrapping width, we need to get the innerCt out of the
876
+ // way to avoid any shrink wrapping effect on child items
877
+ // fill the available width within the container
878
+ outerCtWidth = "100%";
879
+ inheritedStateInner = me.owner.inheritedStateInner;
880
+ // expand no further than the available width, even if contents are wider
881
+ // unless there is a potential for horizontal overflow, then allow
882
+ // the outerCt to expand to the width of the contents
883
+ overflowXStyle = me.getOverflowXStyle(ownerContext);
884
+ outerCtTableLayout =
885
+ inheritedStateInner.inShrinkWrapTable ||
886
+ overflowXStyle === "auto" ||
887
+ overflowXStyle === "scroll"
888
+ ? ""
889
+ : "fixed";
890
+ }
891
+ if (
892
+ !ownerContext.heightModel.shrinkWrap &&
893
+ !Ext.supports.PercentageHeightOverflowBug
894
+ ) {
895
+ // if we're not shrink wrapping height, we need to get the outerCt out of the
896
+ // way so that percentage height children will be sized correctly. We do this
897
+ // by giving the outerCt a height of '100%' unless the browser is affected by
898
+ // the "percentage height overflow bug", in which case the outerCt will get a
899
+ // pixel height set during the calculate phase after we know the targetEl size.
900
+ outerCtHeight = "100%";
901
+ }
902
+ // if the outerCt width changed since last time (becuase of a widthModel change)
903
+ // or if we set a pixel width on the outerCt last time to work around a browser-
904
+ // specific bug, we need to set the width of the outerCt
905
+ if (outerCtWidth !== lastOuterCtWidth || me.hasOuterCtPxWidth) {
906
+ // FIX: Added check for !outerCt.destroyed
907
+ if (!outerCt.destroyed) {
908
+ outerCt.setStyle("width", outerCtWidth);
895
909
  }
896
- return contentHeight;
897
- },
910
+ me.lastOuterCtWidth = outerCtWidth;
911
+ me.hasOuterCtPxWidth = false;
912
+ }
913
+ // Set the outerCt table-layout property if different from last time.
914
+ if (outerCtTableLayout !== lastOuterCtTableLayout) {
915
+ outerCt.setStyle("table-layout", outerCtTableLayout);
916
+ me.lastOuterCtTableLayout = outerCtTableLayout;
917
+ }
918
+ // if the outerCt height changed since last time (becuase of a heightModel change)
919
+ // or if we set a pixel height on the outerCt last time to work around a browser-
920
+ // specific bug, we need to set the height of the outerCt
921
+ if (outerCtHeight !== lastOuterCtHeight || me.hasOuterCtPxHeight) {
922
+ // FIX: Added check for !outerCt.destroyed
923
+ if (!outerCt.destroyed) {
924
+ outerCt.setStyle("height", outerCtHeight);
925
+ }
926
+ me.lastOuterCtHeight = outerCtHeight;
927
+ me.hasOuterCtPxHeight = false;
928
+ }
929
+ if (me.hasInnerCtPxHeight) {
930
+ // FIX: Added check for !innerCt.destroyed
931
+ if (!me.innerCt.destroyed) {
932
+ me.innerCt.setStyle("height", "");
933
+ }
934
+ me.hasInnerCtPxHeight = false;
935
+ }
936
+ // Begin with the scrollbar adjustment that we used last time - this is more likely
937
+ // to be correct than beginning with no adjustment at all, but only if it is not
938
+ // already defined - it may have already been set by invalidate()
939
+ state.overflowAdjust = state.overflowAdjust || me.lastOverflowAdjust;
940
+ },
898
941
 
942
+ // The fix checks whether outerCt is destroyed or not
943
+ // If it's destroyed, then the dom is gone and calling getHeight() would lead to exception
944
+ // set contentHeight to 0 if outerCt is destroyed
945
+ measureContentHeight(ownerContext) {
946
+ // contentHeight includes padding, but not border, framing or margins
947
+ // FIX
948
+ // var contentHeight = this.outerCt.getHeight();
949
+ let contentHeight = this.outerCt.destroyed ? 0 : this.outerCt.getHeight();
950
+ // END FIX
951
+ const target = ownerContext.target;
952
+
953
+ if (
954
+ this.managePadding &&
955
+ target[target.contentPaddingProperty] === undefined
956
+ ) {
957
+ // if padding was not configured using the appropriate contentPaddingProperty
958
+ // then the padding will not be on the paddingContext, and therfore not included
959
+ // in the outerCt measurement, so we need to read the padding from the
960
+ // targetContext
961
+ contentHeight += ownerContext.targetContext.getPaddingInfo().height;
962
+ }
963
+ return contentHeight;
964
+ }
899
965
  });
900
966
 
901
- Ext.define('overrides.grid.column.Column', {
902
- override: 'Ext.grid.column.Column',
967
+ Ext.define("overrides.grid.column.Column", {
968
+ override: "Ext.grid.column.Column",
903
969
 
904
- initConfig: function(config) {
905
- if (!config.renderer && !this.updater) {
906
- config.formatter = 'htmlEncode'
907
- }
908
- return this.callParent(arguments)
970
+ initConfig(config) {
971
+ if (!config.renderer && !this.updater) {
972
+ config.formatter = "htmlEncode";
909
973
  }
974
+ return this.callParent(arguments);
910
975
  }
911
- );
912
-
913
- Ext.define('Ext.netzke.marty.MultiSelectCombo', {
914
- extend: 'Ext.form.ComboBox',
915
- alias: 'widget.multiselectcombo',
916
- separator: ",",
917
- multiSelect: true,
918
-
919
- setValue: function(v) {
920
- if (Ext.isString(v)) {
921
- var vArray = v.split(this.separator);
922
- this.callParent([vArray]);
923
- } else {
924
- this.callParent(arguments);
925
- }
926
- },
976
+ });
977
+
978
+ Ext.define("Ext.netzke.marty.MultiSelectCombo", {
979
+ extend: "Ext.form.ComboBox",
980
+ alias: "widget.multiselectcombo",
981
+ separator: ",",
982
+ multiSelect: true,
983
+
984
+ setValue(v) {
985
+ if (Ext.isString(v)) {
986
+ const vArray = v.split(this.separator);
987
+ this.callParent([vArray]);
988
+ } else {
989
+ this.callParent(arguments);
990
+ }
927
991
  }
928
- );
992
+ });
929
993
 
930
994
  // Fix component fetching in ExtJS 7
931
995
  // This flag was false by default in ExtJS 6