marty 8.5.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.eslintignore +1 -0
- data/.eslintrc.js +26 -0
- data/.gitignore +3 -0
- data/.gitlab-ci.yml +7 -0
- data/.prettierignore +14 -0
- data/.rubocop_todo.yml +1 -1
- data/Dockerfile.dummy +3 -0
- data/Makefile +1 -0
- data/app/assets/javascripts/marty/cable.js +7 -3
- data/app/assets/javascripts/marty/extjs/extensions/datetime_field/component.js +401 -0
- data/app/assets/javascripts/marty/extjs/extensions/datetime_field/field.js +140 -0
- data/app/assets/javascripts/marty/extjs/extensions/marty.js +845 -781
- data/app/assets/stylesheets/marty/codemirror/codemirror.css +215 -77
- data/app/assets/stylesheets/marty/codemirror/delorean.css +2 -2
- data/app/assets/stylesheets/marty/dark_mode.css +13 -3
- data/app/components/marty/auth_app/client/auth_app.js +107 -102
- data/app/components/marty/base_rule_view/client/base_rule_view.js +10 -8
- data/app/components/marty/data_grid_view/client/data_grid_edit.js +534 -519
- data/app/components/marty/form/client/form.js +3 -3
- data/app/components/marty/grid/client/grid.js +110 -87
- data/app/components/marty/import_view/client/import_view.js +18 -18
- data/app/components/marty/live_search_grid_panel/client/live_search_grid_panel.js +14 -13
- data/app/components/marty/main_auth_app/client/main_auth_app.js +42 -42
- data/app/components/marty/mcfly_grid_panel/client/mcfly_grid_panel.js +27 -18
- data/app/components/marty/new_posting_form/client/new_posting_form.js +3 -3
- data/app/components/marty/panel/client/panel.js +3 -3
- data/app/components/marty/posting_grid/client/posting_grid.js +24 -18
- data/app/components/marty/promise_view/client/promise_view.css +12 -12
- data/app/components/marty/promise_view/client/promise_view.js +46 -38
- data/app/components/marty/report_form/client/report_form.js +30 -28
- data/app/components/marty/report_select/client/report_select.js +28 -23
- data/app/components/marty/reporting/client/reporting.js +3 -3
- data/app/components/marty/script_form/client/script_form.js +29 -23
- data/app/components/marty/script_tester/client/script_tester.js +4 -5
- data/app/components/marty/scripting/client/scripting.js +40 -36
- data/app/components/marty/simple_app/client/simple_app.js +33 -24
- data/app/components/marty/simple_app/client/statusbar_ext.js +1 -1
- data/app/controllers/marty/rpc_controller.rb +3 -0
- data/app/models/marty/promise.rb +10 -2
- data/app/services/marty/data_grid/constraint.rb +2 -1
- data/app/services/marty/jobs/schedule.rb +2 -2
- data/app/services/marty/promises/delorean/create.rb +9 -2
- data/app/services/marty/promises/ruby/create.rb +7 -2
- data/config/initializers/delayed_job_config.rb +1 -0
- data/delorean/blame_report.dl +50 -58
- data/delorean/enum_report.dl +2 -3
- data/delorean/{marty_fields.dl → fields.dl} +16 -0
- data/delorean/styles.dl +216 -0
- data/delorean/table_report.dl +4 -4
- data/lib/marty/monkey.rb +17 -0
- data/lib/marty/promise_job.rb +9 -0
- data/lib/marty/promise_ruby_job.rb +8 -0
- data/lib/marty/version.rb +1 -1
- data/make-lint.mk +19 -0
- data/package.json +16 -0
- data/prettier.config.js +6 -0
- data/spec/controllers/diagnostic/controller_spec.rb +0 -1
- data/spec/controllers/rpc_controller_spec.rb +21 -7
- data/spec/dummy/delorean/data_report.dl +4 -4
- data/spec/dummy/delorean/fields.dl +1 -0
- data/spec/features/data_grid_spec.rb +37 -1
- data/spec/job_helper.rb +6 -0
- data/spec/lib/data_blame_spec.rb +4 -4
- data/spec/lib/data_importer_spec.rb +6 -4
- data/spec/models/promise_spec.rb +31 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/download_helper.rb +53 -49
- data/spec/support/json_helper.rb +11 -0
- data/spec/support/shared_connection_db_helpers.rb +1 -0
- data/spec/support/suite.rb +20 -14
- data/yarn.lock +967 -0
- metadata +16 -4
- 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(
|
2
|
-
override:
|
3
|
-
netzkeHandleItemdblclick
|
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
|
-
|
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
|
-
|
16
|
-
|
15
|
+
netzkeReloadStore(opts = {}) {
|
16
|
+
const store = this.getStore();
|
17
17
|
|
18
18
|
// MONKEY: add beforenetzkereload and netzkerevent on store
|
19
|
-
store.fireEvent(
|
20
|
-
|
19
|
+
store.fireEvent("beforenetzkereload");
|
20
|
+
const callback = opts.callback;
|
21
21
|
opts.callback = function() {
|
22
|
-
if (callback) {
|
23
|
-
|
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(
|
34
|
-
override:
|
35
|
+
Ext.define("Ext.toolbar.Paging", {
|
36
|
+
override: "Ext.toolbar.Paging",
|
35
37
|
|
36
38
|
handleRefresh: Ext.emptyFn,
|
37
39
|
|
38
|
-
doRefresh
|
39
|
-
|
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(
|
46
|
+
me.store.fireEvent("netzkerefresh", me);
|
45
47
|
|
46
|
-
if (me.fireEvent(
|
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(
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
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
|
-
|
68
|
-
|
68
|
+
const recordFromStore =
|
69
|
+
editor && editor.isXType("combobox") && editor.findRecordByValue(value);
|
70
|
+
let renderedValue;
|
69
71
|
|
70
72
|
if (recordFromStore) {
|
71
|
-
renderedValue = recordFromStore.get(
|
72
|
-
} else if (
|
73
|
-
|
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
|
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(
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
119
|
+
renderItems: Ext.emptyFn,
|
114
120
|
|
115
|
-
|
116
|
-
|
117
|
-
|
121
|
+
getRenderTarget() {
|
122
|
+
return this.owner.bodyEl;
|
123
|
+
},
|
118
124
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
132
|
-
|
139
|
+
publishInnerWidth(ownerContext, width) {
|
140
|
+
const me = this;
|
133
141
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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(
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
|
171
|
-
|
176
|
+
// FIXME: the layout mechanism is currently busted
|
177
|
+
// componentLayout: 'codemirror',
|
172
178
|
|
173
|
-
|
179
|
+
editorWrapCls: Ext.baseCSSPrefix + "html-editor-wrap",
|
174
180
|
|
175
|
-
|
181
|
+
maskOnDisable: true,
|
176
182
|
|
177
|
-
|
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
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
-
|
310
|
-
|
315
|
+
scriptsLoaded: [],
|
316
|
+
lastMode: "",
|
311
317
|
|
312
|
-
|
313
|
-
|
318
|
+
initComponent() {
|
319
|
+
const me = this;
|
314
320
|
|
315
|
-
|
321
|
+
me.callParent(arguments);
|
316
322
|
|
317
|
-
|
318
|
-
|
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
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
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
|
-
|
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
|
-
|
355
|
-
|
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
|
-
|
360
|
-
|
361
|
-
onRender: function() {
|
362
|
-
var me = this;
|
364
|
+
getSubTplMarkup() {
|
365
|
+
return this.getTpl("fieldSubTpl").apply(this.getSubTplData());
|
366
|
+
},
|
363
367
|
|
364
|
-
|
365
|
-
|
366
|
-
|
368
|
+
/**
|
369
|
+
* @private override
|
370
|
+
*/
|
371
|
+
onRender() {
|
372
|
+
const me = this;
|
367
373
|
|
368
|
-
|
369
|
-
|
374
|
+
me.callParent(arguments);
|
375
|
+
me.editorEl = me.getEl("editorEl");
|
376
|
+
me.bodyEl = me.getEl("bodyEl");
|
370
377
|
|
371
|
-
|
372
|
-
|
378
|
+
me.disableItems(true);
|
379
|
+
me.initEditor();
|
373
380
|
|
374
|
-
|
375
|
-
|
376
|
-
return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
|
377
|
-
},
|
381
|
+
me.rendered = true;
|
382
|
+
},
|
378
383
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
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
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
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
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
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
|
-
|
468
|
-
|
469
|
-
|
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
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
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
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
var me = this;
|
477
|
+
/**
|
478
|
+
* @private
|
479
|
+
*/
|
480
|
+
relayBtnCmd(btn) {
|
481
|
+
this.relayCmd(btn.getItemId());
|
482
|
+
},
|
505
483
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
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
|
-
|
513
|
-
|
507
|
+
// line numbers
|
508
|
+
case "insertorderedlist":
|
509
|
+
me.doChangeLineNumbers();
|
510
|
+
break;
|
511
|
+
}
|
512
|
+
},
|
513
|
+
10,
|
514
|
+
this
|
515
|
+
);
|
516
|
+
},
|
514
517
|
|
515
|
-
|
516
|
-
|
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
|
-
|
521
|
-
*/
|
522
|
-
doIndentSelection: function(){
|
523
|
-
var me = this;
|
537
|
+
doChangeLineNumbers() {
|
538
|
+
const me = this;
|
524
539
|
|
525
|
-
|
540
|
+
me.enableLineNumbers = !me.enableLineNumbers;
|
541
|
+
me.editor.setOption("lineNumbers", me.enableLineNumbers);
|
542
|
+
},
|
526
543
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
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
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
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
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
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
|
-
|
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
|
-
|
610
|
-
me.loadScript(me.scripts[i].options);
|
611
|
-
}
|
612
|
-
},
|
632
|
+
}
|
633
|
+
};
|
613
634
|
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
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
|
-
|
638
|
-
|
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
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
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
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
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
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
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
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
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
|
-
|
707
|
-
|
708
|
-
|
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
|
-
|
713
|
-
|
714
|
-
|
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
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
766
|
+
onDisable() {
|
767
|
+
this.bodyEl.mask();
|
768
|
+
this.callParent(arguments);
|
769
|
+
},
|
721
770
|
|
722
|
-
|
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
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
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
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
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
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
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
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
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
|
-
|
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(
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
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
|
-
//
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
//
|
883
|
-
//
|
884
|
-
|
885
|
-
|
886
|
-
//
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
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
|
-
|
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(
|
902
|
-
|
967
|
+
Ext.define("overrides.grid.column.Column", {
|
968
|
+
override: "Ext.grid.column.Column",
|
903
969
|
|
904
|
-
|
905
|
-
|
906
|
-
|
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(
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
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
|