marty 0.5.15 → 0.5.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +27 -0
- data/.rspec +3 -0
- data/.travis.yml +23 -0
- data/Gemfile +23 -0
- data/INDEPENDENCE_ISSUES.md +23 -0
- data/app/assets/images/marty/.gitkeep +0 -0
- data/app/components/marty/report_form.rb +9 -4
- data/gemini_deprecations.md +6 -0
- data/lib/marty/data_change.rb +99 -0
- data/lib/marty/data_conversion.rb +11 -3
- data/lib/marty/data_exporter.rb +9 -0
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +35 -0
- data/script/rails +8 -0
- data/spec/controllers/application_controller_spec.rb +52 -0
- data/spec/controllers/job_controller_spec.rb +226 -0
- data/spec/controllers/rpc_controller_spec.rb +379 -0
- data/spec/controllers/rpc_import_spec.rb +45 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/components_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/gemini/amortization_type.rb +5 -0
- data/spec/dummy/app/models/gemini/bud_category.rb +7 -0
- data/spec/dummy/app/models/gemini/entity.rb +2 -0
- data/spec/dummy/app/models/gemini/extras/data_import.rb +5 -0
- data/spec/dummy/app/models/gemini/extras/settlement_import.rb +28 -0
- data/spec/dummy/app/models/gemini/fannie_bup.rb +29 -0
- data/spec/dummy/app/models/gemini/grouping.rb +8 -0
- data/spec/dummy/app/models/gemini/grouping_head_version.rb +14 -0
- data/spec/dummy/app/models/gemini/head.rb +7 -0
- data/spec/dummy/app/models/gemini/head_version.rb +14 -0
- data/spec/dummy/app/models/gemini/helper.rb +44 -0
- data/spec/dummy/app/models/gemini/loan_program.rb +11 -0
- data/spec/dummy/app/models/gemini/mortgage_type.rb +5 -0
- data/spec/dummy/app/models/gemini/simple.rb +6 -0
- data/spec/dummy/app/models/gemini/streamline_type.rb +16 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +82 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml.example +10 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +35 -0
- data/spec/dummy/config/environments/production.rb +69 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/delayed_job.rb +5 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/db/migrate/20140801000000_create_groupings.rb +11 -0
- data/spec/dummy/db/migrate/20150406171536_create_categories.rb +27 -0
- data/spec/dummy/db/migrate/20150408200916_create_loan_programs.rb +26 -0
- data/spec/dummy/db/migrate/20150408201429_create_types.rb +21 -0
- data/spec/dummy/db/migrate/20150420000001_create_heads.rb +14 -0
- data/spec/dummy/db/migrate/20150420000002_create_head_versions.rb +15 -0
- data/spec/dummy/db/migrate/20150420000003_create_grouping_head_versions.rb +12 -0
- data/spec/dummy/db/migrate/20151023000001_create_simple.rb +12 -0
- data/spec/dummy/db/seeds.rb +8 -0
- data/spec/dummy/delorean/blame_report.dl +171 -0
- data/spec/dummy/delorean/data_report.dl +105 -0
- data/spec/dummy/delorean/fields.dl +52 -0
- data/spec/dummy/delorean/styles.dl +134 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/lib/class_list.rb +3 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/icons/READ.txt +3 -0
- data/spec/dummy/public/icons/application_cascade.png +0 -0
- data/spec/dummy/public/icons/application_delete.png +0 -0
- data/spec/dummy/public/icons/application_put.png +0 -0
- data/spec/dummy/public/icons/application_view_detail.png +0 -0
- data/spec/dummy/public/icons/arrow_in.png +0 -0
- data/spec/dummy/public/icons/arrow_refresh.png +0 -0
- data/spec/dummy/public/icons/database_save.png +0 -0
- data/spec/dummy/public/icons/door_in.png +0 -0
- data/spec/dummy/public/icons/door_out.png +0 -0
- data/spec/dummy/public/icons/group.png +0 -0
- data/spec/dummy/public/icons/page_lightning.png +0 -0
- data/spec/dummy/public/icons/printer.png +0 -0
- data/spec/dummy/public/icons/report_disk.png +0 -0
- data/spec/dummy/public/icons/report_go.png +0 -0
- data/spec/dummy/public/icons/report_magnify.png +0 -0
- data/spec/dummy/public/icons/script.png +0 -0
- data/spec/dummy/public/icons/script_add.png +0 -0
- data/spec/dummy/public/icons/script_go.png +0 -0
- data/spec/dummy/public/icons/script_key.png +0 -0
- data/spec/dummy/public/icons/table_go.png +0 -0
- data/spec/dummy/public/icons/time.png +0 -0
- data/spec/dummy/public/icons/time_add.png +0 -0
- data/spec/dummy/public/icons/time_go.png +0 -0
- data/spec/dummy/public/icons/timeline_marker.png +0 -0
- data/spec/dummy/public/icons/user_add.png +0 -0
- data/spec/dummy/public/icons/user_delete.png +0 -0
- data/spec/dummy/public/icons/user_edit.png +0 -0
- data/spec/dummy/public/icons/wrench.png +0 -0
- data/spec/dummy/script/delayed_job +6 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/features/javascripts/job_dashboard_live_search.js.coffee +8 -0
- data/spec/features/javascripts/login.js.coffee +8 -0
- data/spec/features/jobs_dashboard_netzke_spec.rb +24 -0
- data/spec/features/jobs_dashboard_spec.rb +49 -0
- data/spec/fixtures/scripts/load_tests/script1.dl +2 -0
- data/spec/fixtures/scripts/load_tests/script2.dl +2 -0
- data/spec/job_helper.rb +102 -0
- data/spec/lib/data_exporter_spec.rb +71 -0
- data/spec/lib/data_importer_spec.rb +461 -0
- data/spec/lib/xl_spec.rb +198 -0
- data/spec/lib/xl_styles_spec.rb +115 -0
- data/spec/models/api_auth_spec.rb +187 -0
- data/spec/models/posting_spec.rb +107 -0
- data/spec/models/promise_spec.rb +65 -0
- data/spec/models/script_spec.rb +187 -0
- data/spec/models/user_spec.rb +68 -0
- data/spec/requests/routes_spec.rb +12 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/clean_db_helpers.rb +18 -0
- data/spec/support/delayed_job_helpers.rb +12 -0
- data/spec/support/user_helpers.rb +12 -0
- metadata +139 -89
- data/app/components/marty/auth_app.rb~ +0 -51
- data/app/components/marty/auth_app/javascripts/auth_app.js~ +0 -91
- data/app/components/marty/cm_form_panel.rb~ +0 -5
- data/app/components/marty/cm_grid_panel.rb~ +0 -35
- data/app/components/marty/data_import_view.rb~ +0 -142
- data/app/components/marty/extras/layout.rb~ +0 -46
- data/app/components/marty/live_search_grid_panel.rb~ +0 -49
- data/app/components/marty/main_auth_app.rb~ +0 -238
- data/app/components/marty/mcfly_grid_panel.rb~ +0 -80
- data/app/components/marty/new_posting_form.rb~ +0 -46
- data/app/components/marty/new_posting_window.rb~ +0 -21
- data/app/components/marty/pivot_grid.rb +0 -52
- data/app/components/marty/pivot_grid/endpoints.rb +0 -45
- data/app/components/marty/pivot_grid/javascripts/extensions.js +0 -150
- data/app/components/marty/pivot_grid/javascripts/pivot_grid.js +0 -86
- data/app/components/marty/pivot_grid/services.rb +0 -44
- data/app/components/marty/posting_grid.rb~ +0 -140
- data/app/components/marty/promise_view.rb~ +0 -157
- data/app/components/marty/promise_view/stylesheets/promise_view.css~ +0 -15
- data/app/components/marty/report_form.rb~ +0 -217
- data/app/components/marty/report_select.rb~ +0 -133
- data/app/components/marty/reporting.rb~ +0 -39
- data/app/components/marty/script_detail.rb~ +0 -430
- data/app/components/marty/script_form.rb~ +0 -233
- data/app/components/marty/script_form/javascripts/Ext.ux.form.field.CodeMirror.js~ +0 -909
- data/app/components/marty/script_grid.rb~ +0 -99
- data/app/components/marty/script_tester.rb~ +0 -213
- data/app/components/marty/scripting.rb~ +0 -124
- data/app/components/marty/select_report.rb~ +0 -143
- data/app/components/marty/simple_app.rb~ +0 -101
- data/app/components/marty/tag_grid.rb~ +0 -89
- data/app/components/marty/tree_panel.rb~ +0 -256
- data/app/components/marty/tree_panel/javascripts/tree_panel.js~ +0 -317
- data/app/components/marty/user_pivot.rb +0 -128
- data/app/components/marty/user_view.rb~ +0 -188
- data/app/controllers/marty/application_controller.rb~ +0 -133
- data/app/controllers/marty/components_controller.rb~ +0 -37
- data/app/controllers/marty/job_controller.rb~ +0 -28
- data/app/controllers/marty/rpc_controller.rb~ +0 -61
- data/app/helpers/marty/script_set.rb~ +0 -59
- data/app/models/marty/api_auth.rb~ +0 -48
- data/app/models/marty/data_change.rb~ +0 -141
- data/app/models/marty/enum.rb~ +0 -16
- data/app/models/marty/import_type.rb~ +0 -48
- data/app/models/marty/poop.rb~ +0 -169
- data/app/models/marty/posting.rb~ +0 -86
- data/app/models/marty/posting_type.rb~ +0 -21
- data/app/models/marty/promise.rb~ +0 -196
- data/app/models/marty/role.rb~ +0 -10
- data/app/models/marty/script.rb~ +0 -62
- data/app/models/marty/tag.rb~ +0 -91
- data/app/models/marty/user.rb~ +0 -148
- data/app/models/marty/user_role.rb~ +0 -13
- data/app/views/layouts/marty/application.html.erb~ +0 -11
- data/config/routes.rb~ +0 -10
- data/db/migrate/019_create_marty_postings.rb~ +0 -19
- data/db/migrate/095_create_marty_tags.rb~ +0 -19
- data/lib/marty.rb~ +0 -13
- data/lib/marty/content_handler.rb~ +0 -93
- data/lib/marty/data_exporter.rb~ +0 -137
- data/lib/marty/data_importer.rb~ +0 -114
- data/lib/marty/data_row_processor.rb~ +0 -206
- data/lib/marty/drop_folder_hook.rb~ +0 -17
- data/lib/marty/folder_hook.rb~ +0 -9
- data/lib/marty/lazy_column_loader.rb~ +0 -47
- data/lib/marty/mcfly_query.rb~ +0 -188
- data/lib/marty/migrations.rb~ +0 -65
- data/lib/marty/monkey.rb~ +0 -160
- data/lib/marty/permissions.rb~ +0 -69
- data/lib/marty/promise.rb~ +0 -41
- data/lib/marty/promise_job.rb~ +0 -121
- data/lib/marty/promise_proxy.rb~ +0 -69
- data/lib/marty/util.rb~ +0 -80
- data/lib/marty/version.rb~ +0 -3
- data/lib/marty/xl.rb~ +0 -526
- data/lib/pyxll/README.txt~ +0 -16
- data/lib/pyxll/gemini.py~ +0 -110
- data/lib/pyxll/pyxll.cfg~ +0 -12
@@ -1,233 +0,0 @@
|
|
1
|
-
require 'delorean_lang'
|
2
|
-
require 'coderay'
|
3
|
-
|
4
|
-
class Marty::ScriptForm < Marty::CmFormPanel
|
5
|
-
DASH = 0x2012.chr('utf-8')
|
6
|
-
|
7
|
-
css_configure do |c|
|
8
|
-
c.require :codemirror
|
9
|
-
c.require :delorean
|
10
|
-
end
|
11
|
-
|
12
|
-
js_configure do |c|
|
13
|
-
c.require :"Ext.ux.form.field.CodeMirror"
|
14
|
-
c.require :codemirror
|
15
|
-
c.require File.dirname(__FILE__) +
|
16
|
-
"/script_form/javascripts/mode/delorean/delorean.js"
|
17
|
-
|
18
|
-
c.set_action_modes = <<-JS
|
19
|
-
function(a) {
|
20
|
-
this.actions.apply.setDisabled(!a["save"]);
|
21
|
-
// style input field text based on whether it is editable
|
22
|
-
this.getForm().findField('body').editor.setOption(
|
23
|
-
"readOnly", !a["save"]);
|
24
|
-
}
|
25
|
-
JS
|
26
|
-
|
27
|
-
c.get_script_id = <<-JS
|
28
|
-
function() {
|
29
|
-
return this.getForm().findField('id').getValue();
|
30
|
-
}
|
31
|
-
JS
|
32
|
-
|
33
|
-
c.get_script_body = <<-JS
|
34
|
-
function() {
|
35
|
-
return this.getForm().findField('body').getValue();
|
36
|
-
}
|
37
|
-
JS
|
38
|
-
|
39
|
-
# Sets an editor line class (unset any previous line class). For
|
40
|
-
# now, only one line is classed at a time.
|
41
|
-
c.set_line_error = <<-JS
|
42
|
-
function(line) {
|
43
|
-
line -= 1;
|
44
|
-
var editor = this.getForm().findField('body').editor;
|
45
|
-
if (editor.oldline) {
|
46
|
-
editor.oldline.className = null;
|
47
|
-
}
|
48
|
-
if (line > -1) {
|
49
|
-
editor.oldline = editor.setLineClass(line, "errorline");
|
50
|
-
}
|
51
|
-
editor.refresh();
|
52
|
-
}
|
53
|
-
JS
|
54
|
-
|
55
|
-
######################################################################
|
56
|
-
|
57
|
-
c.refresh_parent = <<-JS
|
58
|
-
function(script_name) {
|
59
|
-
this.netzkeGetParentComponent().scriptRefresh(script_name);
|
60
|
-
}
|
61
|
-
JS
|
62
|
-
|
63
|
-
######################################################################
|
64
|
-
|
65
|
-
c.on_print = <<-JS
|
66
|
-
function() {
|
67
|
-
window.open(
|
68
|
-
"/marty/components/#{self.name}.html?script_id=" + this.getScriptId(),
|
69
|
-
"printing",
|
70
|
-
'width=800,height=700,toolbar=no,location=no,directories=no,'+
|
71
|
-
'status=no,menubar=no,scrollbars=yes,copyhistory=no,resizable=yes');
|
72
|
-
}
|
73
|
-
JS
|
74
|
-
end
|
75
|
-
|
76
|
-
######################################################################
|
77
|
-
|
78
|
-
endpoint :netzke_load do |params, this|
|
79
|
-
|
80
|
-
return this.netzke_feedback("Permission Denied") unless
|
81
|
-
self.class.has_any_perm?
|
82
|
-
|
83
|
-
script_name = params[:script_name]
|
84
|
-
tag_id = root_sess[:selected_tag_id]
|
85
|
-
|
86
|
-
# logic from basepack's form_panel.service -- need to set @record.
|
87
|
-
@record = script = Marty::Script.find_script(script_name, tag_id)
|
88
|
-
|
89
|
-
title = [script.name, script.find_tag.try(:name)].
|
90
|
-
join(" #{Marty::ScriptForm::DASH} ") if script
|
91
|
-
|
92
|
-
# create an empty record if no script
|
93
|
-
js_data = @record ? js_record_data : {
|
94
|
-
"body" => "",
|
95
|
-
"id" => -1,
|
96
|
-
"meta" => {},
|
97
|
-
}
|
98
|
-
|
99
|
-
this.set_form_values(js_data)
|
100
|
-
this.set_title title
|
101
|
-
this.set_readonly_mode !can_save?(script)
|
102
|
-
|
103
|
-
modes = {
|
104
|
-
save: can_save?(script),
|
105
|
-
}
|
106
|
-
|
107
|
-
this.set_action_modes(modes)
|
108
|
-
end
|
109
|
-
|
110
|
-
def can_save?(script)
|
111
|
-
script && self.class.has_dev_perm? && Mcfly.is_infinity(script.obsoleted_dt)
|
112
|
-
end
|
113
|
-
|
114
|
-
######################################################################
|
115
|
-
|
116
|
-
action :apply do |a|
|
117
|
-
a.text = I18n.t("script_form.save")
|
118
|
-
a.tooltip = I18n.t("script_form.save")
|
119
|
-
a.icon = :database_save
|
120
|
-
a.disabled = true
|
121
|
-
end
|
122
|
-
|
123
|
-
endpoint :netzke_submit do |params, this|
|
124
|
-
|
125
|
-
return this.netzke_feedback("Permission Denied") unless
|
126
|
-
self.class.has_any_perm?
|
127
|
-
|
128
|
-
# copied from corresponding method in form_panel.services
|
129
|
-
data = ActiveSupport::JSON.decode(params[:data])
|
130
|
-
data.each_pair do |k,v|
|
131
|
-
data[k] = nil if v.blank? || v == "null"
|
132
|
-
end
|
133
|
-
|
134
|
-
@record = script = Marty::Script.find_by_id(data["id"])
|
135
|
-
|
136
|
-
unless script
|
137
|
-
this.netzke_feedback "no record"
|
138
|
-
return
|
139
|
-
end
|
140
|
-
|
141
|
-
if script.body == data["body"]
|
142
|
-
this.netzke_feedback "no save needed"
|
143
|
-
# clear the error line if any
|
144
|
-
this.set_line_error -1
|
145
|
-
return
|
146
|
-
end
|
147
|
-
|
148
|
-
unless can_save?(script)
|
149
|
-
this.netzke_feedback "Permission denied"
|
150
|
-
return
|
151
|
-
end
|
152
|
-
|
153
|
-
begin
|
154
|
-
dev = Marty::Tag.find_by_name("DEV")
|
155
|
-
Marty::ScriptSet.new(dev).parse_check(script.name, data["body"])
|
156
|
-
rescue Delorean::ParseError => exc
|
157
|
-
this.netzke_feedback exc.message
|
158
|
-
this.apply_form_errors({})
|
159
|
-
this.set_line_error(exc.line)
|
160
|
-
return
|
161
|
-
end
|
162
|
-
|
163
|
-
script.body = data["body"]
|
164
|
-
|
165
|
-
if script.save
|
166
|
-
this.set_form_values(js_record_data)
|
167
|
-
this.netzke_set_result(true)
|
168
|
-
this.refresh_parent(script.name)
|
169
|
-
return
|
170
|
-
end
|
171
|
-
|
172
|
-
data_adapter.errors_array(script).each do |error|
|
173
|
-
flash error: error
|
174
|
-
end
|
175
|
-
|
176
|
-
this.netzke_feedback @flash
|
177
|
-
this.apply_form_errors(build_form_errors(record))
|
178
|
-
end
|
179
|
-
|
180
|
-
######################################################################
|
181
|
-
|
182
|
-
action :print do |a|
|
183
|
-
a.text = I18n.t("script_form.print")
|
184
|
-
a.tooltip = I18n.t("script_form.print")
|
185
|
-
a.icon = :printer
|
186
|
-
a.handler = :on_print
|
187
|
-
end
|
188
|
-
|
189
|
-
######################################################################
|
190
|
-
|
191
|
-
def configure_bbar(c)
|
192
|
-
c[:bbar] = [
|
193
|
-
:apply,
|
194
|
-
:print,
|
195
|
-
]
|
196
|
-
end
|
197
|
-
|
198
|
-
######################################################################
|
199
|
-
|
200
|
-
# used for printing
|
201
|
-
def export_content(format, title, params={})
|
202
|
-
raise "unknown format: #{format}" unless format == "html"
|
203
|
-
|
204
|
-
r = Marty::Script.find_by_id(params[:script_id])
|
205
|
-
res = CodeRay.scan(r.body, :ruby).div(line_numbers: :table)
|
206
|
-
|
207
|
-
[res, "text/html", "inline", "#{title}.html"]
|
208
|
-
end
|
209
|
-
|
210
|
-
def configure(c)
|
211
|
-
super
|
212
|
-
|
213
|
-
c.title = "Script Form"
|
214
|
-
c.model = "Marty::Script"
|
215
|
-
c.items =
|
216
|
-
[
|
217
|
-
{
|
218
|
-
mode: "text/x-delorean",
|
219
|
-
line_numbers: true,
|
220
|
-
indent_unit: 4,
|
221
|
-
tab_mode: "shift",
|
222
|
-
match_brackets: true,
|
223
|
-
hide_label: true,
|
224
|
-
xtype: :codemirror,
|
225
|
-
name: :body,
|
226
|
-
empty_text: "No script selected.",
|
227
|
-
getter: lambda { |r| r.body },
|
228
|
-
},
|
229
|
-
]
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
ScriptForm = Marty::ScriptForm
|
@@ -1,909 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
|
3
|
-
This is a modified version of the ExtJS Codemirror component from
|
4
|
-
http://www.mzsolutions.eu/Extjs-CodeMirror-component.html. It's been
|
5
|
-
modified to remove the toolbar and also it uses delorean mode by
|
6
|
-
default.
|
7
|
-
|
8
|
-
*/
|
9
|
-
|
10
|
-
/**
|
11
|
-
* @private
|
12
|
-
* @class Ext.ux.layout.component.field.CodeMirror
|
13
|
-
* @extends Ext.layout.component.field.Field
|
14
|
-
* @author Adrian Teodorescu (ateodorescu@gmail.com)
|
15
|
-
*
|
16
|
-
* Layout class for {@link Ext.ux.form.field.CodeMirror} fields. Handles sizing the codemirror field.
|
17
|
-
*/
|
18
|
-
Ext.define('Ext.ux.layout.component.field.CodeMirror', {
|
19
|
-
extend: 'Ext.layout.component.field.Field',
|
20
|
-
alias: ['layout.codemirror'],
|
21
|
-
|
22
|
-
type: 'codemirror',
|
23
|
-
|
24
|
-
beginLayout: function(ownerContext) {
|
25
|
-
this.callParent(arguments);
|
26
|
-
|
27
|
-
ownerContext.textAreaContext = ownerContext.getEl('textareaEl');
|
28
|
-
ownerContext.editorContext = ownerContext.getEl('editorEl');
|
29
|
-
},
|
30
|
-
|
31
|
-
renderItems: Ext.emptyFn,
|
32
|
-
|
33
|
-
getRenderTarget: function() {
|
34
|
-
return this.owner.bodyEl;
|
35
|
-
},
|
36
|
-
|
37
|
-
publishInnerHeight: function (ownerContext, height) {
|
38
|
-
var me = this,
|
39
|
-
innerHeight = height - me.measureLabelErrorHeight(ownerContext) -
|
40
|
-
ownerContext.bodyCellContext.getPaddingInfo().height;
|
41
|
-
|
42
|
-
|
43
|
-
if (Ext.isNumber(innerHeight)) {
|
44
|
-
ownerContext.textAreaContext.setHeight(innerHeight);
|
45
|
-
ownerContext.editorContext.setHeight(innerHeight);
|
46
|
-
} else {
|
47
|
-
me.done = false;
|
48
|
-
}
|
49
|
-
},
|
50
|
-
|
51
|
-
publishInnerWidth: function (ownerContext, width) {
|
52
|
-
var me = this;
|
53
|
-
|
54
|
-
if (Ext.isNumber(width)) {
|
55
|
-
ownerContext.textAreaContext.setWidth(width);
|
56
|
-
ownerContext.editorContext.setWidth(width);
|
57
|
-
} else {
|
58
|
-
me.done = false;
|
59
|
-
}
|
60
|
-
}
|
61
|
-
});
|
62
|
-
|
63
|
-
/**
|
64
|
-
* @class Ext.ux.form.field.CodeMirror
|
65
|
-
* @extends Ext.form.field.Base
|
66
|
-
* @author Adrian Teodorescu (ateodorescu@gmail.com; http://www.mzsolutions.eu)
|
67
|
-
* @docauthor Adrian Teodorescu (ateodorescu@gmail.com; http://www.mzsolutions.eu)
|
68
|
-
* @license [MIT][1]
|
69
|
-
*
|
70
|
-
* @version 1.5
|
71
|
-
*
|
72
|
-
*
|
73
|
-
* Provides a [CodeMirror][2] component wrapper for Sencha. The supported and tested CodeMirror versions are 2.2, 2.3 and 2.4.
|
74
|
-
* The component works with Extjs 4.1.x.
|
75
|
-
*
|
76
|
-
* [1]: http://www.mzsolutions.eu/extjs/license.txt
|
77
|
-
* [2]: http://codemirror.net/
|
78
|
-
*
|
79
|
-
*
|
80
|
-
* The editor's toolbar buttons have tooltips defined in the {@link #buttonTips} property, but they are not
|
81
|
-
* enabled by default unless the global {@link Ext.tip.QuickTipManager} singleton is {@link Ext.tip.QuickTipManager#init initialized}.
|
82
|
-
*
|
83
|
-
* If you include the modes script files by yourself then ignore the {@link #modes} property.
|
84
|
-
* If you also include the extensions script files by yourself then ignore the {@link #extensions} property.
|
85
|
-
*
|
86
|
-
*
|
87
|
-
*
|
88
|
-
#Example usage:#
|
89
|
-
|
90
|
-
{@img Ext.ux.form.field.CodeMirror.png Ext.ux.form.field.CodeMirror component}
|
91
|
-
|
92
|
-
var form = Ext.create('Ext.form.Panel', {
|
93
|
-
title: 'Function info',
|
94
|
-
bodyPadding: 10,
|
95
|
-
width: 500,
|
96
|
-
renderTo: Ext.getBody(),
|
97
|
-
items: [{
|
98
|
-
xtype: 'textfield',
|
99
|
-
name: 'name',
|
100
|
-
anchor: '100%',
|
101
|
-
fieldLabel: 'Name',
|
102
|
-
allowBlank: false // requires a non-empty value
|
103
|
-
}, {
|
104
|
-
xtype: 'codemirror',
|
105
|
-
name: 'function',
|
106
|
-
fieldLabel: 'Code',
|
107
|
-
anchor: '100%'
|
108
|
-
}],
|
109
|
-
|
110
|
-
buttons: [{
|
111
|
-
text: 'Save',
|
112
|
-
handler: function(){
|
113
|
-
if(form.getForm().isValid()){
|
114
|
-
alert(form.getForm().getValues().function);
|
115
|
-
}
|
116
|
-
}
|
117
|
-
}]
|
118
|
-
});
|
119
|
-
|
120
|
-
|
121
|
-
#Plugin example for the CodeMirror component:#
|
122
|
-
|
123
|
-
Ext.define('Ext.ux.form.plugin.CodeMirror', {
|
124
|
-
mixins: {
|
125
|
-
observable: 'Ext.util.Observable'
|
126
|
-
},
|
127
|
-
alternateClassName: 'Ext.form.plugin.CodeMirror',
|
128
|
-
requires: [
|
129
|
-
'Ext.tip.QuickTipManager',
|
130
|
-
'Ext.ux.form.field.CodeMirror'
|
131
|
-
],
|
132
|
-
|
133
|
-
constructor: function(config) {
|
134
|
-
Ext.apply(this, config);
|
135
|
-
},
|
136
|
-
|
137
|
-
init: function(codemirror){
|
138
|
-
var me = this;
|
139
|
-
me.codemirror = codemirror;
|
140
|
-
me.mon(codemirror, 'initialize', me.onInitialize, me);
|
141
|
-
},
|
142
|
-
|
143
|
-
onInitialize: function(){
|
144
|
-
var me = this, undef,
|
145
|
-
items = [],
|
146
|
-
baseCSSPrefix = Ext.baseCSSPrefix,
|
147
|
-
tipsEnabled = Ext.tip.QuickTipManager && Ext.tip.QuickTipManager.isEnabled();
|
148
|
-
|
149
|
-
function btn(id, toggle, handler){
|
150
|
-
return {
|
151
|
-
itemId : id,
|
152
|
-
cls : baseCSSPrefix + 'btn-icon',
|
153
|
-
iconCls: baseCSSPrefix + 'edit-'+id,
|
154
|
-
enableToggle:toggle !== false,
|
155
|
-
scope: me,
|
156
|
-
handler:handler||me.relayBtnCmd,
|
157
|
-
clickEvent:'mousedown',
|
158
|
-
tooltip: tipsEnabled ? me.buttonTips[id] || undef : undef,
|
159
|
-
overflowText: me.buttonTips[id].title || undef,
|
160
|
-
tabIndex:-1
|
161
|
-
};
|
162
|
-
}
|
163
|
-
|
164
|
-
items.push(btn('test', false));
|
165
|
-
if(items.length > 0){
|
166
|
-
me.codemirror.getToolbar().add(items);
|
167
|
-
}
|
168
|
-
},
|
169
|
-
|
170
|
-
relayBtnCmd: function(btn){
|
171
|
-
alert('test');
|
172
|
-
},
|
173
|
-
|
174
|
-
buttonTips : {
|
175
|
-
test : {
|
176
|
-
title: 'Test',
|
177
|
-
text: 'Test button.',
|
178
|
-
cls: Ext.baseCSSPrefix + 'html-editor-tip'
|
179
|
-
}
|
180
|
-
}
|
181
|
-
|
182
|
-
});
|
183
|
-
|
184
|
-
|
185
|
-
*/
|
186
|
-
Ext.define('Ext.ux.form.field.CodeMirror', {
|
187
|
-
extend: 'Ext.Component',
|
188
|
-
mixins: {
|
189
|
-
labelable: 'Ext.form.Labelable',
|
190
|
-
field: 'Ext.form.field.Field'
|
191
|
-
},
|
192
|
-
alias: 'widget.codemirror',
|
193
|
-
alternateClassName: 'Ext.form.CodeMirror',
|
194
|
-
requires: [
|
195
|
-
'Ext.tip.QuickTipManager',
|
196
|
-
'Ext.util.Format',
|
197
|
-
'Ext.ux.layout.component.field.CodeMirror'
|
198
|
-
],
|
199
|
-
|
200
|
-
childEls: [
|
201
|
-
'editorEl', 'textareaEl'
|
202
|
-
],
|
203
|
-
|
204
|
-
fieldSubTpl: [
|
205
|
-
'<textarea id="{cmpId}-textareaEl" name="{name}" tabIndex="-1" class="{textareaCls}" ',
|
206
|
-
'style="{size}" autocomplete="off"></textarea>',
|
207
|
-
'<div id="{cmpId}-editorEl" class="{editorCls}" name="{editorName}" style="{size}"></div>',
|
208
|
-
{
|
209
|
-
disableFormats: true
|
210
|
-
}
|
211
|
-
],
|
212
|
-
|
213
|
-
componentLayout: 'codemirror',
|
214
|
-
|
215
|
-
editorWrapCls: Ext.baseCSSPrefix + 'html-editor-wrap',
|
216
|
-
|
217
|
-
maskOnDisable: true,
|
218
|
-
|
219
|
-
afterBodyEl: '</div>',
|
220
|
-
|
221
|
-
/**
|
222
|
-
* @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.
|
223
|
-
* It may be a string, which either simply names the mode or is a MIME type associated with the mode. Alternatively,
|
224
|
-
* it may be an object containing configuration options for the mode, with a name property that names the mode
|
225
|
-
* (for example {name: "javascript", json: true}). The demo pages for each mode contain information about what
|
226
|
-
* configuration parameters the mode supports.
|
227
|
-
*/
|
228
|
-
mode: 'text/plain',
|
229
|
-
|
230
|
-
/**
|
231
|
-
* @cfg {Boolean} showAutoIndent Enable auto indent button for indenting the selected range
|
232
|
-
*/
|
233
|
-
showAutoIndent: true,
|
234
|
-
|
235
|
-
/**
|
236
|
-
* @cfg {Boolean} showLineNumbers Enable line numbers button in the toolbar.
|
237
|
-
*/
|
238
|
-
showLineNumbers: true,
|
239
|
-
|
240
|
-
/**
|
241
|
-
* @cfg {Boolean} enableMatchBrackets Force matching-bracket-highlighting to happen
|
242
|
-
*/
|
243
|
-
enableMatchBrackets: true,
|
244
|
-
|
245
|
-
/**
|
246
|
-
* @cfg {Boolean} enableElectricChars Configures whether the editor should re-indent the current line when a character is typed
|
247
|
-
* that might change its proper indentation (only works if the mode supports indentation).
|
248
|
-
*/
|
249
|
-
enableElectricChars: false,
|
250
|
-
|
251
|
-
/**
|
252
|
-
* @cfg {Boolean} enableIndentWithTabs Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs.
|
253
|
-
*/
|
254
|
-
enableIndentWithTabs: true,
|
255
|
-
|
256
|
-
/**
|
257
|
-
* @cfg {Boolean} enableSmartIndent Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before).
|
258
|
-
*/
|
259
|
-
enableSmartIndent: true,
|
260
|
-
|
261
|
-
/**
|
262
|
-
* @cfg {Boolean} enableLineWrapping Whether CodeMirror should scroll or wrap for long lines.
|
263
|
-
*/
|
264
|
-
enableLineWrapping: false,
|
265
|
-
|
266
|
-
/**
|
267
|
-
* @cfg {Boolean} enableLineNumbers Whether to show line numbers to the left of the editor.
|
268
|
-
*/
|
269
|
-
enableLineNumbers: true,
|
270
|
-
|
271
|
-
/**
|
272
|
-
* @cfg {Boolean} enableGutter Can be used to force a 'gutter' (empty space on the left of the editor) to be shown even
|
273
|
-
* when no line numbers are active. This is useful for setting markers.
|
274
|
-
*/
|
275
|
-
enableGutter: true,
|
276
|
-
|
277
|
-
/**
|
278
|
-
* @cfg {Boolean} enableFixedGutter When enabled (off by default), this will make the gutter stay visible when the
|
279
|
-
* document is scrolled horizontally.
|
280
|
-
*/
|
281
|
-
enableFixedGutter: false,
|
282
|
-
|
283
|
-
/**
|
284
|
-
* @cfg {Number} firstLineNumber At which number to start counting lines.
|
285
|
-
*/
|
286
|
-
firstLineNumber: 1,
|
287
|
-
|
288
|
-
/**
|
289
|
-
* @cfg {Boolean} readOnly <tt>true</tt> to mark the field as readOnly.
|
290
|
-
*/
|
291
|
-
readOnly : false,
|
292
|
-
|
293
|
-
/**
|
294
|
-
* @cfg {Number} pollInterval Indicates how quickly (miliseconds) CodeMirror should poll its input textarea for changes.
|
295
|
-
* Most input is captured by events, but some things, like IME input on some browsers, doesn't generate events
|
296
|
-
* that allow CodeMirror to properly detect it. Thus, it polls.
|
297
|
-
*/
|
298
|
-
pollInterval: 100,
|
299
|
-
|
300
|
-
/**
|
301
|
-
* @cfg {Number} indentUnit How many spaces a block (whatever that means in the edited language) should be indented.
|
302
|
-
*/
|
303
|
-
indentUnit: 4,
|
304
|
-
|
305
|
-
/**
|
306
|
-
* @cfg {Number} tabSize The width of a tab character.
|
307
|
-
*/
|
308
|
-
tabSize: 4,
|
309
|
-
|
310
|
-
/**
|
311
|
-
* @cfg {String} theme The theme to style the editor with. You must make sure the CSS file defining the corresponding
|
312
|
-
* .cm-s-[name] styles is loaded (see the theme directory in the distribution). The default is "default", for which
|
313
|
-
* colors are included in codemirror.css. It is possible to use multiple theming classes at once—for example
|
314
|
-
* "foo bar" will assign both the cm-s-foo and the cm-s-bar classes to the editor.
|
315
|
-
*/
|
316
|
-
theme: 'default',
|
317
|
-
|
318
|
-
/**
|
319
|
-
* @property {String} pathModes Path to the modes folder to dinamically load the required scripts. You could also
|
320
|
-
* include all your required modes in a big script file and this path will be ignored.
|
321
|
-
* Do not fill in the trailing slash.
|
322
|
-
*/
|
323
|
-
pathModes: 'mode',
|
324
|
-
|
325
|
-
/**
|
326
|
-
* @property {String} pathExtensions Path to the extensions folder to dinamically load the required scripts. You could also
|
327
|
-
* include all your required extensions in a big script file and this path will be ignored.
|
328
|
-
* Do not fill in the trailing slash.
|
329
|
-
*/
|
330
|
-
pathExtensions: 'lib/util',
|
331
|
-
|
332
|
-
/**
|
333
|
-
* @property {Array} extensions Define here extensions script dependencies; This is used by toolbar buttons to automatically
|
334
|
-
* load the scripts before using an extension.
|
335
|
-
*/
|
336
|
-
extensions:{
|
337
|
-
format: {
|
338
|
-
dependencies: ['formatting.js']
|
339
|
-
}
|
340
|
-
},
|
341
|
-
|
342
|
-
scriptsLoaded: [],
|
343
|
-
lastMode: '',
|
344
|
-
|
345
|
-
initComponent : function(){
|
346
|
-
var me = this;
|
347
|
-
|
348
|
-
me.addEvents(
|
349
|
-
/**
|
350
|
-
* @event initialize
|
351
|
-
* Fires when the editor is fully initialized (including the iframe)
|
352
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
353
|
-
*/
|
354
|
-
'initialize',
|
355
|
-
/**
|
356
|
-
* @event activate
|
357
|
-
* Fires when the editor is first receives the focus. Any insertion must wait
|
358
|
-
* until after this event.
|
359
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
360
|
-
*/
|
361
|
-
'activate',
|
362
|
-
/**
|
363
|
-
* @event deactivate
|
364
|
-
* Fires when the editor looses the focus.
|
365
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
366
|
-
*/
|
367
|
-
'deactivate',
|
368
|
-
/**
|
369
|
-
* @event change
|
370
|
-
* Fires when the content of the editor is changed.
|
371
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
372
|
-
* @param {String} newValue New value
|
373
|
-
* @param {String} oldValue Old value
|
374
|
-
* @param {Array} options
|
375
|
-
*/
|
376
|
-
'change',
|
377
|
-
/**
|
378
|
-
* @event modechanged
|
379
|
-
* Fires when the editor mode changes.
|
380
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
381
|
-
* @param {String} newMode New mode
|
382
|
-
* @param {String} oldMode Old mode
|
383
|
-
*/
|
384
|
-
'modechanged',
|
385
|
-
/**
|
386
|
-
* @event cursoractivity
|
387
|
-
* Fires when the cursor or selection moves, or any change is made to the editor content.
|
388
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
389
|
-
*/
|
390
|
-
'cursoractivity',
|
391
|
-
/**
|
392
|
-
* @event gutterclick
|
393
|
-
* Fires whenever the editor gutter (the line-number area) is clicked.
|
394
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
395
|
-
* @param {Number} lineNumber Zero-based number of the line that was clicked
|
396
|
-
* @param {Object} event The raw mousedown event
|
397
|
-
*/
|
398
|
-
'gutterclick',
|
399
|
-
/**
|
400
|
-
* @event scroll
|
401
|
-
* Fires whenever the editor is scrolled.
|
402
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
403
|
-
*/
|
404
|
-
'scroll',
|
405
|
-
/**
|
406
|
-
* @event highlightcomplete
|
407
|
-
* Fires whenever the editor's content has been fully highlighted.
|
408
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
409
|
-
*/
|
410
|
-
'highlightcomplete',
|
411
|
-
/**
|
412
|
-
* @event update
|
413
|
-
* Fires whenever CodeMirror updates its DOM display.
|
414
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
415
|
-
*/
|
416
|
-
'update',
|
417
|
-
/**
|
418
|
-
* @event keyevent
|
419
|
-
* Fires on eery keydown, keyup, and keypress event that CodeMirror captures.
|
420
|
-
* @param {Ext.ux.form.field.CodeMirror} this
|
421
|
-
* @param {Object} event This key event is pretty much the raw key event, except that a stop() method is always
|
422
|
-
* added to it. You could feed it to, for example, jQuery.Event to further normalize it. This function can inspect
|
423
|
-
* the key event, and handle it if it wants to. It may return true to tell CodeMirror to ignore the event.
|
424
|
-
* Be wary that, on some browsers, stopping a keydown does not stop the keypress from firing, whereas on others
|
425
|
-
* it does. If you respond to an event, you should probably inspect its type property and only do something when
|
426
|
-
* it is keydown (or keypress for actions that need character data).
|
427
|
-
*/
|
428
|
-
'keyevent'
|
429
|
-
);
|
430
|
-
|
431
|
-
|
432
|
-
me.callParent(arguments);
|
433
|
-
|
434
|
-
me.initLabelable();
|
435
|
-
me.initField();
|
436
|
-
|
437
|
-
/*
|
438
|
-
Fix resize issues as suggested by user koblass on the Extjs forums
|
439
|
-
http://www.sencha.com/forum/showthread.php?167047-Ext.ux.form.field.CodeMirror-for-Ext-4.x&p=860535&viewfull=1#post860535
|
440
|
-
*/
|
441
|
-
me.on('resize', function() {
|
442
|
-
if (me.editor) {
|
443
|
-
me.editor.refresh();
|
444
|
-
}
|
445
|
-
}, me);
|
446
|
-
|
447
|
-
},
|
448
|
-
|
449
|
-
getMaskTarget: function(){
|
450
|
-
return this.bodyEl;
|
451
|
-
},
|
452
|
-
|
453
|
-
/**
|
454
|
-
* @private override
|
455
|
-
*/
|
456
|
-
getSubTplData: function() {
|
457
|
-
var cssPrefix = Ext.baseCSSPrefix;
|
458
|
-
return {
|
459
|
-
$comp : this,
|
460
|
-
cmpId : this.id,
|
461
|
-
id : this.getInputId(),
|
462
|
-
toolbarWrapCls : cssPrefix + 'html-editor-tb',
|
463
|
-
textareaCls : cssPrefix + 'hidden',
|
464
|
-
editorCls : cssPrefix + 'codemirror',
|
465
|
-
editorName : Ext.id(),
|
466
|
-
//size : 'height:100px;width:100%'
|
467
|
-
// PennyMac: setting height to 100%.
|
468
|
-
size : 'height:100%;width:100%',
|
469
|
-
};
|
470
|
-
},
|
471
|
-
|
472
|
-
getSubTplMarkup: function() {
|
473
|
-
return this.getTpl('fieldSubTpl').apply(this.getSubTplData());
|
474
|
-
},
|
475
|
-
|
476
|
-
finishRenderChildren: function () {
|
477
|
-
this.callParent();
|
478
|
-
},
|
479
|
-
|
480
|
-
/**
|
481
|
-
* @private override
|
482
|
-
*/
|
483
|
-
onRender: function() {
|
484
|
-
var me = this;
|
485
|
-
|
486
|
-
me.callParent(arguments);
|
487
|
-
me.inputEl = me.editorEl;
|
488
|
-
|
489
|
-
me.disableItems(true);
|
490
|
-
me.initEditor();
|
491
|
-
|
492
|
-
me.rendered = true;
|
493
|
-
},
|
494
|
-
|
495
|
-
initRenderTpl: function() {
|
496
|
-
var me = this;
|
497
|
-
if (!me.hasOwnProperty('renderTpl')) {
|
498
|
-
me.renderTpl = me.getTpl('labelableRenderTpl');
|
499
|
-
}
|
500
|
-
return me.callParent();
|
501
|
-
},
|
502
|
-
|
503
|
-
initRenderData: function() {
|
504
|
-
this.beforeSubTpl = '<div class="' + this.editorWrapCls + '">';
|
505
|
-
return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
|
506
|
-
},
|
507
|
-
|
508
|
-
/**
|
509
|
-
* @private override
|
510
|
-
*/
|
511
|
-
initEditor : function(){
|
512
|
-
var me = this,
|
513
|
-
mode = "text/x-delorean";
|
514
|
-
|
515
|
-
// if no mode is loaded we could get an error like "Object #<Object> has no method 'startState'"
|
516
|
-
// search mime to find script dependencies
|
517
|
-
var item = me.getMime(me.mode);
|
518
|
-
if(item) {
|
519
|
-
mode = me.getMimeMode(me.mode);
|
520
|
-
if(!mode){
|
521
|
-
mode = "text/x-delorean";
|
522
|
-
}
|
523
|
-
}
|
524
|
-
|
525
|
-
me.editor = CodeMirror(me.editorEl, {
|
526
|
-
matchBrackets: me.enableMatchBrackets,
|
527
|
-
electricChars: me.enableElectricChars,
|
528
|
-
autoClearEmptyLines:true,
|
529
|
-
value: me.rawValue,
|
530
|
-
indentUnit: me.indentUnit,
|
531
|
-
smartIndent: me.enableSmartIndent,
|
532
|
-
indentWithTabs: me.indentWithTabs,
|
533
|
-
pollInterval: me.pollInterval,
|
534
|
-
lineNumbers: me.enableLineNumbers,
|
535
|
-
lineWrapping: me.enableLineWrapping,
|
536
|
-
firstLineNumber: me.firstLineNumber,
|
537
|
-
tabSize: me.tabSize,
|
538
|
-
gutter: me.enableGutter,
|
539
|
-
fixedGutter: me.enableFixedGutter,
|
540
|
-
theme: me.theme,
|
541
|
-
mode: mode,
|
542
|
-
onChange: function(editor, tc){
|
543
|
-
me.checkChange();
|
544
|
-
//me.fireEvent('change', me, tc.from, tc.to, tc.text, tc.next || null);
|
545
|
-
},
|
546
|
-
onCursorActivity: function(editor){
|
547
|
-
me.fireEvent('cursoractivity', me);
|
548
|
-
},
|
549
|
-
onGutterClick: function(editor, line, event){
|
550
|
-
me.fireEvent('gutterclick', me, line, event);
|
551
|
-
},
|
552
|
-
onFocus: function(editor){
|
553
|
-
me.fireEvent('activate', me);
|
554
|
-
},
|
555
|
-
onBlur: function(editor){
|
556
|
-
me.fireEvent('deactivate', me);
|
557
|
-
},
|
558
|
-
onScroll: function(editor){
|
559
|
-
me.fireEvent('scroll', me);
|
560
|
-
},
|
561
|
-
onHighlightComplete: function(editor){
|
562
|
-
me.fireEvent('highlightcomplete', me);
|
563
|
-
},
|
564
|
-
onUpdate: function(editor){
|
565
|
-
me.fireEvent('update', me);
|
566
|
-
},
|
567
|
-
onKeyEvent: function(editor, event){
|
568
|
-
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)
|
569
|
-
me.fireEvent('keyevent', me, event);
|
570
|
-
}
|
571
|
-
});
|
572
|
-
//me.editor.setValue(me.rawValue);
|
573
|
-
me.setMode(me.mode);
|
574
|
-
me.setReadOnly(me.readOnly);
|
575
|
-
me.fireEvent('initialize', me);
|
576
|
-
|
577
|
-
// change the codemirror css
|
578
|
-
var css = Ext.util.CSS.getRule('.CodeMirror');
|
579
|
-
if(css){
|
580
|
-
css.style.height = '100%';
|
581
|
-
css.style.position = 'relative';
|
582
|
-
css.style.overflow = 'hidden';
|
583
|
-
}
|
584
|
-
var css = Ext.util.CSS.getRule('.CodeMirror-Scroll');
|
585
|
-
if(css){
|
586
|
-
css.style.height = '100%';
|
587
|
-
}
|
588
|
-
|
589
|
-
// PennyMac: align the body to the top. Otherwise it ends up
|
590
|
-
// in the center of the enclosing table.
|
591
|
-
var el = document.getElementById(me.bodyEl.id);
|
592
|
-
el.setAttribute("valign", "top");
|
593
|
-
},
|
594
|
-
|
595
|
-
/**
|
596
|
-
* @private
|
597
|
-
*/
|
598
|
-
relayBtnCmd: function(btn){
|
599
|
-
this.relayCmd(btn.getItemId());
|
600
|
-
},
|
601
|
-
|
602
|
-
/**
|
603
|
-
* @private
|
604
|
-
*/
|
605
|
-
relayCmd: function(cmd){
|
606
|
-
Ext.defer(function() {
|
607
|
-
var me = this;
|
608
|
-
me.editor.focus();
|
609
|
-
switch(cmd){
|
610
|
-
// auto formatting
|
611
|
-
case 'justifycenter':
|
612
|
-
if(!CodeMirror.extensions.autoIndentRange){
|
613
|
-
me.loadDependencies(me.extensions.format, me.pathExtensions, me.doIndentSelection, me);
|
614
|
-
}else{
|
615
|
-
me.doIndentSelection();
|
616
|
-
}
|
617
|
-
break;
|
618
|
-
|
619
|
-
// line numbers
|
620
|
-
case 'insertorderedlist':
|
621
|
-
me.doChangeLineNumbers();
|
622
|
-
break;
|
623
|
-
}
|
624
|
-
}, 10, this);
|
625
|
-
},
|
626
|
-
|
627
|
-
/**
|
628
|
-
* @private
|
629
|
-
* Reload all CodeMirror extensions for the current instance;
|
630
|
-
*
|
631
|
-
*/
|
632
|
-
reloadExtentions: function(){
|
633
|
-
var me = this;
|
634
|
-
|
635
|
-
for (var ext in CodeMirror.extensions)
|
636
|
-
if (CodeMirror.extensions.propertyIsEnumerable(ext) &&
|
637
|
-
!me.editor.propertyIsEnumerable(ext))
|
638
|
-
me.editor[ext] = CodeMirror.extensions[ext];
|
639
|
-
},
|
640
|
-
|
641
|
-
doChangeLineNumbers: function(){
|
642
|
-
var me = this;
|
643
|
-
|
644
|
-
me.enableLineNumbers = !me.enableLineNumbers;
|
645
|
-
me.editor.setOption('lineNumbers', me.enableLineNumbers);
|
646
|
-
},
|
647
|
-
|
648
|
-
/**
|
649
|
-
* @private
|
650
|
-
*/
|
651
|
-
doIndentSelection: function(){
|
652
|
-
var me = this;
|
653
|
-
|
654
|
-
me.reloadExtentions();
|
655
|
-
|
656
|
-
try{
|
657
|
-
var range = { from: me.editor.getCursor(true), to: me.editor.getCursor(false) };
|
658
|
-
me.editor.autoIndentRange(range.from, range.to);
|
659
|
-
}catch(err){}
|
660
|
-
},
|
661
|
-
|
662
|
-
modes: [
|
663
|
-
{
|
664
|
-
mime: ["text/x-delorean"],
|
665
|
-
dependencies: []
|
666
|
-
},
|
667
|
-
],
|
668
|
-
|
669
|
-
/**
|
670
|
-
* @private
|
671
|
-
*/
|
672
|
-
getMime: function(mime){
|
673
|
-
var me = this, item, found = false;
|
674
|
-
|
675
|
-
for(var i=0;i<me.modes.length;i++){
|
676
|
-
item = me.modes[i];
|
677
|
-
if(Ext.isArray(item.mime)){
|
678
|
-
if(Ext.Array.contains(item.mime, mime)){
|
679
|
-
found = true;
|
680
|
-
break;
|
681
|
-
}
|
682
|
-
}else{
|
683
|
-
if(item == mime){
|
684
|
-
found = true;
|
685
|
-
break;
|
686
|
-
}
|
687
|
-
}
|
688
|
-
}
|
689
|
-
if(found)
|
690
|
-
return item;
|
691
|
-
else
|
692
|
-
return null;
|
693
|
-
},
|
694
|
-
|
695
|
-
/**
|
696
|
-
* @private
|
697
|
-
*/
|
698
|
-
loadDependencies: function(item, path, handler, scope){
|
699
|
-
var me = this;
|
700
|
-
|
701
|
-
me.scripts = [];
|
702
|
-
me.scriptIndex = -1;
|
703
|
-
|
704
|
-
// load the dependencies
|
705
|
-
for(var i=0; i < item.dependencies.length; i++){
|
706
|
-
if(!Ext.Array.contains(me.scriptsLoaded, path + '/' + item.dependencies[i])){
|
707
|
-
var options = {
|
708
|
-
url: path + '/' + item.dependencies[i],
|
709
|
-
index: ++me.scriptIndex,
|
710
|
-
onLoad: function(options){
|
711
|
-
var ok = true;
|
712
|
-
for(j=0; j < me.scripts.length; j++){
|
713
|
-
if(me.scripts[j].called) {// this event could be raised before one script if fetched
|
714
|
-
ok = ok && me.scripts[j].success;
|
715
|
-
if(me.scripts[j].success && !Ext.Array.contains(me.scriptsLoaded, me.scripts[j].url)){
|
716
|
-
me.scriptsLoaded.push(me.scripts[j].url);
|
717
|
-
}
|
718
|
-
}else{
|
719
|
-
ok = false;
|
720
|
-
}
|
721
|
-
}
|
722
|
-
if(ok){
|
723
|
-
handler.call(scope || me.editor);
|
724
|
-
}
|
725
|
-
}
|
726
|
-
};
|
727
|
-
|
728
|
-
me.scripts[me.scriptIndex] = {
|
729
|
-
url: options.url,
|
730
|
-
success: true,
|
731
|
-
called: false,
|
732
|
-
options: options,
|
733
|
-
onLoad: options.onLoad || Ext.emptyFn,
|
734
|
-
onError: options.onError || Ext.emptyFn
|
735
|
-
};
|
736
|
-
}
|
737
|
-
}
|
738
|
-
for(var i=0; i < me.scripts.length; i++){
|
739
|
-
me.loadScript(me.scripts[i].options);
|
740
|
-
}
|
741
|
-
},
|
742
|
-
|
743
|
-
/**
|
744
|
-
* @private
|
745
|
-
*/
|
746
|
-
loadScript: function(options){
|
747
|
-
var me = this;
|
748
|
-
Ext.Ajax.request({
|
749
|
-
url: options.url,
|
750
|
-
scriptIndex: options.index,
|
751
|
-
success: function(response, options) {
|
752
|
-
var script = 'Ext.getCmp("' + this.id + '").scripts[' + options.scriptIndex + ']';
|
753
|
-
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);
|
754
|
-
},
|
755
|
-
failure: function(response, options) {
|
756
|
-
var script = this.scripts[options.scriptIndex];
|
757
|
-
script.success = false;
|
758
|
-
script.called = true;
|
759
|
-
script.onError(script.options, response.status);
|
760
|
-
},
|
761
|
-
scope: me
|
762
|
-
});
|
763
|
-
},
|
764
|
-
|
765
|
-
/**
|
766
|
-
* @private
|
767
|
-
* Return mode depending on the mime; If the mime is not loaded then return null
|
768
|
-
*
|
769
|
-
* @param mime
|
770
|
-
*/
|
771
|
-
getMimeMode: function(mime){
|
772
|
-
var mode = null;
|
773
|
-
var mimes = CodeMirror.listMIMEs();
|
774
|
-
for(var i=0; i<mimes.length; i++){
|
775
|
-
if(mimes[i].mime == mime){
|
776
|
-
mode = mimes[i].mode;
|
777
|
-
if(typeof mode == "object")
|
778
|
-
mode = mode.name;
|
779
|
-
break;
|
780
|
-
}
|
781
|
-
}
|
782
|
-
return mode;
|
783
|
-
},
|
784
|
-
|
785
|
-
/**
|
786
|
-
* Change the CodeMirror mode to the specified mime.
|
787
|
-
*
|
788
|
-
* @param {String} mime The MIME value according to the CodeMirror documentation
|
789
|
-
*/
|
790
|
-
setMode: function(mime){
|
791
|
-
var me = this,
|
792
|
-
found = false;
|
793
|
-
// search mime to find script dependencies
|
794
|
-
var item = me.getMime(mime);
|
795
|
-
|
796
|
-
if(!item) {
|
797
|
-
// mime not found
|
798
|
-
return;
|
799
|
-
}
|
800
|
-
|
801
|
-
var mode = me.getMimeMode(mime);
|
802
|
-
|
803
|
-
if(!mode){
|
804
|
-
me.loadDependencies(item, me.pathModes, function(){
|
805
|
-
var mode = me.getMimeMode(mime);
|
806
|
-
if(typeof mode == "string")
|
807
|
-
me.editor.setOption('mode', mime);
|
808
|
-
else
|
809
|
-
me.editor.setOption('mode', mode);
|
810
|
-
});
|
811
|
-
}else{
|
812
|
-
if(typeof mode == "string")
|
813
|
-
me.editor.setOption('mode', mime);
|
814
|
-
else
|
815
|
-
me.editor.setOption('mode', mode);
|
816
|
-
}
|
817
|
-
|
818
|
-
if(me.modesSelect){
|
819
|
-
me.modesSelect.dom.value = mime;
|
820
|
-
}
|
821
|
-
try{
|
822
|
-
me.fireEvent('modechanged', me, mime, me.lastMode);
|
823
|
-
me.lastMode = mime;
|
824
|
-
}catch(err){}
|
825
|
-
},
|
826
|
-
|
827
|
-
/**
|
828
|
-
* Set the editor as read only
|
829
|
-
*
|
830
|
-
* @param {Boolean} readOnly
|
831
|
-
*/
|
832
|
-
setReadOnly: function(readOnly) {
|
833
|
-
var me = this;
|
834
|
-
|
835
|
-
if(me.editor){
|
836
|
-
me.editor.setOption('readOnly', readOnly);
|
837
|
-
me.disableItems(readOnly);
|
838
|
-
}
|
839
|
-
},
|
840
|
-
|
841
|
-
onDisable: function() {
|
842
|
-
this.bodyEl.mask();
|
843
|
-
this.callParent(arguments);
|
844
|
-
},
|
845
|
-
|
846
|
-
onEnable: function() {
|
847
|
-
this.bodyEl.unmask();
|
848
|
-
this.callParent(arguments);
|
849
|
-
},
|
850
|
-
|
851
|
-
disableItems: function(disabled) {
|
852
|
-
},
|
853
|
-
|
854
|
-
/**
|
855
|
-
* Sets a data value into the field and runs the change detection.
|
856
|
-
* @param {Mixed} value The value to set
|
857
|
-
* @return {Ext.ux.form.field.CodeMirror} this
|
858
|
-
*/
|
859
|
-
setValue: function(value){
|
860
|
-
var me = this;
|
861
|
-
|
862
|
-
me.mixins.field.setValue.call(me, value);
|
863
|
-
me.rawValue = value;
|
864
|
-
if(me.editor)
|
865
|
-
me.editor.setValue(value);
|
866
|
-
return me;
|
867
|
-
},
|
868
|
-
|
869
|
-
/**
|
870
|
-
* Return submit value to the owner form.
|
871
|
-
* @return {Mixed} The field value
|
872
|
-
*/
|
873
|
-
getSubmitValue: function(){
|
874
|
-
var me = this;
|
875
|
-
return me.getValue();
|
876
|
-
},
|
877
|
-
|
878
|
-
/**
|
879
|
-
* Return the value of the CodeMirror editor
|
880
|
-
* @return {Mixed} The field value
|
881
|
-
*/
|
882
|
-
getValue: function(){
|
883
|
-
var me = this;
|
884
|
-
|
885
|
-
if(me.editor)
|
886
|
-
return me.editor.getValue();
|
887
|
-
else
|
888
|
-
return null;
|
889
|
-
},
|
890
|
-
|
891
|
-
/**
|
892
|
-
* @private
|
893
|
-
*/
|
894
|
-
onDestroy: function(){
|
895
|
-
var me = this;
|
896
|
-
if(me.rendered){
|
897
|
-
try {
|
898
|
-
Ext.EventManager.removeAll(me.editor);
|
899
|
-
for (prop in me.editor) {
|
900
|
-
if (me.editor.hasOwnProperty(prop)) {
|
901
|
-
delete me.editor[prop];
|
902
|
-
}
|
903
|
-
}
|
904
|
-
}catch(e){}
|
905
|
-
}
|
906
|
-
me.callParent();
|
907
|
-
},
|
908
|
-
|
909
|
-
});
|