##// END OF EJS Templates
DOC: Add comment.
Scott Sanderson -
Show More
@@ -1,193 +1,195 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'jquery',
5 'jquery',
6 'base/js/utils',
6 'base/js/utils',
7 'codemirror/lib/codemirror',
7 'codemirror/lib/codemirror',
8 'codemirror/mode/meta',
8 'codemirror/mode/meta',
9 'codemirror/addon/comment/comment',
9 'codemirror/addon/comment/comment',
10 'codemirror/addon/dialog/dialog',
10 'codemirror/addon/dialog/dialog',
11 'codemirror/addon/edit/closebrackets',
11 'codemirror/addon/edit/closebrackets',
12 'codemirror/addon/edit/matchbrackets',
12 'codemirror/addon/edit/matchbrackets',
13 'codemirror/addon/search/searchcursor',
13 'codemirror/addon/search/searchcursor',
14 'codemirror/addon/search/search',
14 'codemirror/addon/search/search',
15 'codemirror/keymap/emacs',
15 'codemirror/keymap/emacs',
16 'codemirror/keymap/sublime',
16 'codemirror/keymap/sublime',
17 'codemirror/keymap/vim',
17 'codemirror/keymap/vim',
18 ],
18 ],
19 function($,
19 function($,
20 utils,
20 utils,
21 CodeMirror
21 CodeMirror
22 ) {
22 ) {
23 "use strict";
23 "use strict";
24
24
25 var Editor = function(selector, options) {
25 var Editor = function(selector, options) {
26 var that = this;
26 var that = this;
27 this.selector = selector;
27 this.selector = selector;
28 this.contents = options.contents;
28 this.contents = options.contents;
29 this.events = options.events;
29 this.events = options.events;
30 this.base_url = options.base_url;
30 this.base_url = options.base_url;
31 this.file_path = options.file_path;
31 this.file_path = options.file_path;
32 this.config = options.config;
32 this.config = options.config;
33 this.codemirror = new CodeMirror($(this.selector)[0]);
33 this.codemirror = new CodeMirror($(this.selector)[0]);
34 this.generation = -1;
34 this.generation = -1;
35
35
36 // It appears we have to set commands on the CodeMirror class, not the
36 // It appears we have to set commands on the CodeMirror class, not the
37 // instance. I'd like to be wrong, but since there should only be one CM
37 // instance. I'd like to be wrong, but since there should only be one CM
38 // instance on the page, this is good enough for now.
38 // instance on the page, this is good enough for now.
39 CodeMirror.commands.save = $.proxy(this.save, this);
39 CodeMirror.commands.save = $.proxy(this.save, this);
40
40
41 this.save_enabled = false;
41 this.save_enabled = false;
42
42
43 this.config.loaded.then(function () {
43 this.config.loaded.then(function () {
44 // load codemirror config
44 // load codemirror config
45 var cfg = that.config.data.Editor || {};
45 var cfg = that.config.data.Editor || {};
46 var cmopts = $.extend(true, {}, // true = recursive copy
46 var cmopts = $.extend(true, {}, // true = recursive copy
47 Editor.default_codemirror_options,
47 Editor.default_codemirror_options,
48 cfg.codemirror_options || {}
48 cfg.codemirror_options || {}
49 );
49 );
50 that._set_codemirror_options(cmopts);
50 that._set_codemirror_options(cmopts);
51 that.events.trigger('config_changed.Editor', {config: that.config});
51 that.events.trigger('config_changed.Editor', {config: that.config});
52 });
52 });
53 };
53 };
54
54
55 // default CodeMirror options
55 // default CodeMirror options
56 Editor.default_codemirror_options = {
56 Editor.default_codemirror_options = {
57 extraKeys: {
57 extraKeys: {
58 "Tab" : "indentMore",
58 "Tab" : "indentMore",
59 },
59 },
60 indentUnit: 4,
60 indentUnit: 4,
61 theme: "ipython",
61 theme: "ipython",
62 lineNumbers: true,
62 lineNumbers: true,
63 lineWrapping: true,
63 lineWrapping: true,
64 };
64 };
65
65
66 Editor.prototype.load = function() {
66 Editor.prototype.load = function() {
67 /** load the file */
67 /** load the file */
68 var that = this;
68 var that = this;
69 var cm = this.codemirror;
69 var cm = this.codemirror;
70 return this.contents.get(this.file_path, {type: 'file', format: 'text'})
70 return this.contents.get(this.file_path, {type: 'file', format: 'text'})
71 .then(function(model) {
71 .then(function(model) {
72 cm.setValue(model.content);
72 cm.setValue(model.content);
73
73
74 // Setting the file's initial value creates a history entry,
74 // Setting the file's initial value creates a history entry,
75 // which we don't want.
75 // which we don't want.
76 cm.clearHistory();
76 cm.clearHistory();
77 that._set_mode_for_model(model);
77 that._set_mode_for_model(model);
78 that.save_enabled = true;
78 that.save_enabled = true;
79 that.generation = cm.changeGeneration();
79 that.generation = cm.changeGeneration();
80 that.events.trigger("file_loaded.Editor", model);
80 that.events.trigger("file_loaded.Editor", model);
81 },
81 },
82 function(error) {
82 function(error) {
83 that.events.trigger("file_load_failed.Editor", error);
83 that.events.trigger("file_load_failed.Editor", error);
84 if (error.xhr.responseJSON.reason === 'bad format') {
84 if (error.xhr.responseJSON.reason === 'bad format') {
85 window.location = utils.url_path_join(
85 window.location = utils.url_path_join(
86 that.base_url,
86 that.base_url,
87 'files',
87 'files',
88 that.file_path
88 that.file_path
89 );
89 );
90 }
90 }
91 cm.setValue("Error! " + error.message +
91 cm.setValue("Error! " + error.message +
92 "\nSaving disabled.");
92 "\nSaving disabled.");
93 that.save_enabled = false;
93 that.save_enabled = false;
94 }
94 }
95 );
95 );
96 };
96 };
97
97
98 Editor.prototype._set_mode_for_model = function (model) {
98 Editor.prototype._set_mode_for_model = function (model) {
99 /** Set the CodeMirror mode based on the file model */
99 /** Set the CodeMirror mode based on the file model */
100
100
101 // Find and load the highlighting mode,
101 // Find and load the highlighting mode,
102 // first by mime-type, then by file extension
102 // first by mime-type, then by file extension
103
103 var modeinfo;
104 var modeinfo;
105 // mimetype is unset on file rename
104 if (model.mimetype) {
106 if (model.mimetype) {
105 modeinfo = CodeMirror.findModeByMIME(model.mimetype);
107 modeinfo = CodeMirror.findModeByMIME(model.mimetype);
106 }
108 }
107 if (!modeinfo || modeinfo.mode === "null") {
109 if (!modeinfo || modeinfo.mode === "null") {
108 // find by mime failed, use find by ext
110 // find by mime failed, use find by ext
109 var ext_idx = model.name.lastIndexOf('.');
111 var ext_idx = model.name.lastIndexOf('.');
110
112
111 if (ext_idx > 0) {
113 if (ext_idx > 0) {
112 // CodeMirror.findModeByExtension wants extension without '.'
114 // CodeMirror.findModeByExtension wants extension without '.'
113 modeinfo = CodeMirror.findModeByExtension(model.name.slice(ext_idx + 1));
115 modeinfo = CodeMirror.findModeByExtension(model.name.slice(ext_idx + 1));
114 }
116 }
115 }
117 }
116 if (modeinfo) {
118 if (modeinfo) {
117 this.set_codemirror_mode(modeinfo);
119 this.set_codemirror_mode(modeinfo);
118 }
120 }
119 };
121 };
120
122
121 Editor.prototype.set_codemirror_mode = function (modeinfo) {
123 Editor.prototype.set_codemirror_mode = function (modeinfo) {
122 /** set the codemirror mode from a modeinfo struct */
124 /** set the codemirror mode from a modeinfo struct */
123 var that = this;
125 var that = this;
124 utils.requireCodeMirrorMode(modeinfo, function () {
126 utils.requireCodeMirrorMode(modeinfo, function () {
125 that.codemirror.setOption('mode', modeinfo.mode);
127 that.codemirror.setOption('mode', modeinfo.mode);
126 that.events.trigger("mode_changed.Editor", modeinfo);
128 that.events.trigger("mode_changed.Editor", modeinfo);
127 });
129 });
128 };
130 };
129
131
130 Editor.prototype.get_filename = function () {
132 Editor.prototype.get_filename = function () {
131 return utils.url_path_split(this.file_path)[1];
133 return utils.url_path_split(this.file_path)[1];
132 };
134 };
133
135
134 Editor.prototype.rename = function (new_name) {
136 Editor.prototype.rename = function (new_name) {
135 /** rename the file */
137 /** rename the file */
136 var that = this;
138 var that = this;
137 var parent = utils.url_path_split(this.file_path)[0];
139 var parent = utils.url_path_split(this.file_path)[0];
138 var new_path = utils.url_path_join(parent, new_name);
140 var new_path = utils.url_path_join(parent, new_name);
139 return this.contents.rename(this.file_path, new_path).then(
141 return this.contents.rename(this.file_path, new_path).then(
140 function (model) {
142 function (model) {
141 that.file_path = model.path;
143 that.file_path = model.path;
142 that.events.trigger('file_renamed.Editor', model);
144 that.events.trigger('file_renamed.Editor', model);
143 that._set_mode_for_model(model);
145 that._set_mode_for_model(model);
144 }
146 }
145 );
147 );
146 };
148 };
147
149
148 Editor.prototype.save = function () {
150 Editor.prototype.save = function () {
149 /** save the file */
151 /** save the file */
150 if (!this.save_enabled) {
152 if (!this.save_enabled) {
151 console.log("Not saving, save disabled");
153 console.log("Not saving, save disabled");
152 return;
154 return;
153 }
155 }
154 var model = {
156 var model = {
155 path: this.file_path,
157 path: this.file_path,
156 type: 'file',
158 type: 'file',
157 format: 'text',
159 format: 'text',
158 content: this.codemirror.getValue(),
160 content: this.codemirror.getValue(),
159 };
161 };
160 var that = this;
162 var that = this;
161 // record change generation for isClean
163 // record change generation for isClean
162 this.generation = this.codemirror.changeGeneration();
164 this.generation = this.codemirror.changeGeneration();
163 return this.contents.save(this.file_path, model).then(function(data) {
165 return this.contents.save(this.file_path, model).then(function(data) {
164 that.events.trigger("file_saved.Editor", data);
166 that.events.trigger("file_saved.Editor", data);
165 });
167 });
166 };
168 };
167
169
168 Editor.prototype._set_codemirror_options = function (options) {
170 Editor.prototype._set_codemirror_options = function (options) {
169 // update codemirror options from a dict
171 // update codemirror options from a dict
170 var codemirror = this.codemirror;
172 var codemirror = this.codemirror;
171 $.map(options, function (value, opt) {
173 $.map(options, function (value, opt) {
172 if (value === null) {
174 if (value === null) {
173 value = CodeMirror.defaults[opt];
175 value = CodeMirror.defaults[opt];
174 }
176 }
175 codemirror.setOption(opt, value);
177 codemirror.setOption(opt, value);
176 });
178 });
177 };
179 };
178
180
179 Editor.prototype.update_codemirror_options = function (options) {
181 Editor.prototype.update_codemirror_options = function (options) {
180 /** update codemirror options locally and save changes in config */
182 /** update codemirror options locally and save changes in config */
181 var that = this;
183 var that = this;
182 this._set_codemirror_options(options);
184 this._set_codemirror_options(options);
183 return this.config.update({
185 return this.config.update({
184 Editor: {
186 Editor: {
185 codemirror_options: options
187 codemirror_options: options
186 }
188 }
187 }).then(
189 }).then(
188 that.events.trigger('config_changed.Editor', {config: that.config})
190 that.events.trigger('config_changed.Editor', {config: that.config})
189 );
191 );
190 };
192 };
191
193
192 return {Editor: Editor};
194 return {Editor: Editor};
193 });
195 });
General Comments 0
You need to be logged in to leave comments. Login now