##// END OF EJS Templates
Merge pull request #6924 from takluyver/contents-promises...
Min RK -
r18863:6fa05ce6 merge
parent child Browse files
Show More
@@ -591,6 +591,21 b' define(['
591 return wrapped_error;
591 return wrapped_error;
592 };
592 };
593
593
594 var promising_ajax = function(url, settings) {
595 // Like $.ajax, but returning an ES6 promise. success and error settings
596 // will be ignored.
597 return new Promise(function(resolve, reject) {
598 settings.success = function(data, status, jqXHR) {
599 resolve(data);
600 };
601 settings.error = function(jqXHR, status, error) {
602 log_ajax_error(jqXHR, status, error);
603 reject(wrap_ajax_error(jqXHR, status, error));
604 };
605 $.ajax(url, settings);
606 });
607 };
608
594 var utils = {
609 var utils = {
595 regex_split : regex_split,
610 regex_split : regex_split,
596 uuid : uuid,
611 uuid : uuid,
@@ -618,7 +633,8 b' define(['
618 log_ajax_error : log_ajax_error,
633 log_ajax_error : log_ajax_error,
619 requireCodeMirrorMode : requireCodeMirrorMode,
634 requireCodeMirrorMode : requireCodeMirrorMode,
620 XHR_ERROR : XHR_ERROR,
635 XHR_ERROR : XHR_ERROR,
621 wrap_ajax_error : wrap_ajax_error
636 wrap_ajax_error : wrap_ajax_error,
637 promising_ajax : promising_ajax,
622 };
638 };
623
639
624 // Backwards compatability.
640 // Backwards compatability.
@@ -1,1 +1,1 b''
1 Subproject commit f8f0c3b8958b1f91a888b5f15d2b17404a476016
1 Subproject commit ba94581b824a62ee630dd0b92a5aea8678248a24
@@ -90,14 +90,13 b' define(['
90 // Create a new notebook in the same path as the current
90 // Create a new notebook in the same path as the current
91 // notebook's path.
91 // notebook's path.
92 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
92 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
93 that.contents.new_untitled(parent, {
93 that.contents.new_untitled(parent, {type: "notebook"}).then(
94 type: "notebook",
94 function (data) {
95 success: function (data) {
96 w.location = utils.url_join_encode(
95 w.location = utils.url_join_encode(
97 that.base_url, 'notebooks', data.path
96 that.base_url, 'notebooks', data.path
98 );
97 );
99 },
98 },
100 error: function(error) {
99 function(error) {
101 w.close();
100 w.close();
102 dialog.modal({
101 dialog.modal({
103 title : 'Creating Notebook Failed',
102 title : 'Creating Notebook Failed',
@@ -105,7 +104,7 b' define(['
105 buttons : {'OK' : {'class' : 'btn-primary'}}
104 buttons : {'OK' : {'class' : 'btn-primary'}}
106 });
105 });
107 }
106 }
108 });
107 );
109 });
108 });
110 this.element.find('#open_notebook').click(function () {
109 this.element.find('#open_notebook').click(function () {
111 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
110 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
@@ -1902,12 +1902,12 b' define(['
1902 var start = new Date().getTime();
1902 var start = new Date().getTime();
1903
1903
1904 var that = this;
1904 var that = this;
1905 this.contents.save(this.notebook_path, model, {
1905 this.contents.save(this.notebook_path, model).then(
1906 success: $.proxy(this.save_notebook_success, this, start),
1906 $.proxy(this.save_notebook_success, this, start),
1907 error: function (error) {
1907 function (error) {
1908 that.events.trigger('notebook_save_failed.Notebook', error);
1908 that.events.trigger('notebook_save_failed.Notebook', error);
1909 }
1909 }
1910 });
1910 );
1911 };
1911 };
1912
1912
1913 /**
1913 /**
@@ -2025,17 +2025,17 b' define(['
2025 var base_url = this.base_url;
2025 var base_url = this.base_url;
2026 var w = window.open();
2026 var w = window.open();
2027 var parent = utils.url_path_split(this.notebook_path)[0];
2027 var parent = utils.url_path_split(this.notebook_path)[0];
2028 this.contents.copy(this.notebook_path, parent, {
2028 this.contents.copy(this.notebook_path, parent).then(
2029 success: function (data) {
2029 function (data) {
2030 w.location = utils.url_join_encode(
2030 w.location = utils.url_join_encode(
2031 base_url, 'notebooks', data.path
2031 base_url, 'notebooks', data.path
2032 );
2032 );
2033 },
2033 },
2034 error : function(error) {
2034 function(error) {
2035 w.close();
2035 w.close();
2036 console.log(error);
2036 console.log(error);
2037 },
2037 }
2038 });
2038 );
2039 };
2039 };
2040
2040
2041 Notebook.prototype.rename = function (new_name) {
2041 Notebook.prototype.rename = function (new_name) {
@@ -2046,15 +2046,15 b' define(['
2046 var that = this;
2046 var that = this;
2047 var parent = utils.url_path_split(this.notebook_path)[0];
2047 var parent = utils.url_path_split(this.notebook_path)[0];
2048 var new_path = utils.url_path_join(parent, new_name);
2048 var new_path = utils.url_path_join(parent, new_name);
2049 this.contents.rename(this.notebook_path, new_path, {
2049 this.contents.rename(this.notebook_path, new_path).then(
2050 success: function (json) {
2050 function (json) {
2051 that.notebook_name = json.name;
2051 that.notebook_name = json.name;
2052 that.notebook_path = json.path;
2052 that.notebook_path = json.path;
2053 that.session.rename_notebook(json.path);
2053 that.session.rename_notebook(json.path);
2054 that.events.trigger('notebook_renamed.Notebook', json);
2054 that.events.trigger('notebook_renamed.Notebook', json);
2055 },
2055 },
2056 error: $.proxy(this.rename_error, this)
2056 $.proxy(this.rename_error, this)
2057 });
2057 );
2058 };
2058 };
2059
2059
2060 Notebook.prototype.delete = function () {
2060 Notebook.prototype.delete = function () {
@@ -2103,11 +2103,10 b' define(['
2103 this.notebook_path = notebook_path;
2103 this.notebook_path = notebook_path;
2104 this.notebook_name = utils.url_path_split(this.notebook_path)[1];
2104 this.notebook_name = utils.url_path_split(this.notebook_path)[1];
2105 this.events.trigger('notebook_loading.Notebook');
2105 this.events.trigger('notebook_loading.Notebook');
2106 this.contents.get(notebook_path, {
2106 this.contents.get(notebook_path, {type: 'notebook'}).then(
2107 type: 'notebook',
2107 $.proxy(this.load_notebook_success, this),
2108 success: $.proxy(this.load_notebook_success, this),
2108 $.proxy(this.load_notebook_error, this)
2109 error: $.proxy(this.load_notebook_error, this)
2109 );
2110 });
2111 };
2110 };
2112
2111
2113 /**
2112 /**
@@ -2327,12 +2326,12 b' define(['
2327 */
2326 */
2328 Notebook.prototype.list_checkpoints = function () {
2327 Notebook.prototype.list_checkpoints = function () {
2329 var that = this;
2328 var that = this;
2330 this.contents.list_checkpoints(this.notebook_path, {
2329 this.contents.list_checkpoints(this.notebook_path).then(
2331 success: $.proxy(this.list_checkpoints_success, this),
2330 $.proxy(this.list_checkpoints_success, this),
2332 error: function(error) {
2331 function(error) {
2333 that.events.trigger('list_checkpoints_failed.Notebook', error);
2332 that.events.trigger('list_checkpoints_failed.Notebook', error);
2334 }
2333 }
2335 });
2334 );
2336 };
2335 };
2337
2336
2338 /**
2337 /**
@@ -2342,7 +2341,6 b' define(['
2342 * @param {Object} data JSON representation of a checkpoint
2341 * @param {Object} data JSON representation of a checkpoint
2343 */
2342 */
2344 Notebook.prototype.list_checkpoints_success = function (data) {
2343 Notebook.prototype.list_checkpoints_success = function (data) {
2345 data = $.parseJSON(data);
2346 this.checkpoints = data;
2344 this.checkpoints = data;
2347 if (data.length) {
2345 if (data.length) {
2348 this.last_checkpoint = data[data.length - 1];
2346 this.last_checkpoint = data[data.length - 1];
@@ -2359,12 +2357,12 b' define(['
2359 */
2357 */
2360 Notebook.prototype.create_checkpoint = function () {
2358 Notebook.prototype.create_checkpoint = function () {
2361 var that = this;
2359 var that = this;
2362 this.contents.create_checkpoint(this.notebook_path, {
2360 this.contents.create_checkpoint(this.notebook_path).then(
2363 success: $.proxy(this.create_checkpoint_success, this),
2361 $.proxy(this.create_checkpoint_success, this),
2364 error: function (error) {
2362 function (error) {
2365 that.events.trigger('checkpoint_failed.Notebook', error);
2363 that.events.trigger('checkpoint_failed.Notebook', error);
2366 }
2364 }
2367 });
2365 );
2368 };
2366 };
2369
2367
2370 /**
2368 /**
@@ -2374,7 +2372,6 b' define(['
2374 * @param {Object} data JSON representation of a checkpoint
2372 * @param {Object} data JSON representation of a checkpoint
2375 */
2373 */
2376 Notebook.prototype.create_checkpoint_success = function (data) {
2374 Notebook.prototype.create_checkpoint_success = function (data) {
2377 data = $.parseJSON(data);
2378 this.add_checkpoint(data);
2375 this.add_checkpoint(data);
2379 this.events.trigger('checkpoint_created.Notebook', data);
2376 this.events.trigger('checkpoint_created.Notebook', data);
2380 };
2377 };
@@ -2429,13 +2426,12 b' define(['
2429 Notebook.prototype.restore_checkpoint = function (checkpoint) {
2426 Notebook.prototype.restore_checkpoint = function (checkpoint) {
2430 this.events.trigger('notebook_restoring.Notebook', checkpoint);
2427 this.events.trigger('notebook_restoring.Notebook', checkpoint);
2431 var that = this;
2428 var that = this;
2432 this.contents.restore_checkpoint(this.notebook_path,
2429 this.contents.restore_checkpoint(this.notebook_path, checkpoint).then(
2433 checkpoint, {
2430 $.proxy(this.restore_checkpoint_success, this),
2434 success: $.proxy(this.restore_checkpoint_success, this),
2431 function (error) {
2435 error: function (error) {
2436 that.events.trigger('checkpoint_restore_failed.Notebook', error);
2432 that.events.trigger('checkpoint_restore_failed.Notebook', error);
2437 }
2433 }
2438 });
2434 );
2439 };
2435 };
2440
2436
2441 /**
2437 /**
@@ -2457,13 +2453,12 b' define(['
2457 Notebook.prototype.delete_checkpoint = function (checkpoint) {
2453 Notebook.prototype.delete_checkpoint = function (checkpoint) {
2458 this.events.trigger('notebook_restoring.Notebook', checkpoint);
2454 this.events.trigger('notebook_restoring.Notebook', checkpoint);
2459 var that = this;
2455 var that = this;
2460 this.contents.delete_checkpoint(this.notebook_path,
2456 this.contents.delete_checkpoint(this.notebook_path, checkpoint).then(
2461 checkpoint, {
2457 $.proxy(this.delete_checkpoint_success, this),
2462 success: $.proxy(this.delete_checkpoint_success, this),
2458 function (error) {
2463 error: function (error) {
2464 that.events.trigger('checkpoint_delete_failed.Notebook', error);
2459 that.events.trigger('checkpoint_delete_failed.Notebook', error);
2465 }
2460 }
2466 });
2461 );
2467 };
2462 };
2468
2463
2469 /**
2464 /**
@@ -73,8 +73,9 b' define(['
73 *
73 *
74 * @method get
74 * @method get
75 * @param {String} path
75 * @param {String} path
76 * @param {Function} success
76 * @param {Object} options
77 * @param {Function} error
77 * type : 'notebook', 'file', or 'directory'
78 * format: 'text' or 'base64'; only relevant for type: 'file'
78 */
79 */
79 Contents.prototype.get = function (path, options) {
80 Contents.prototype.get = function (path, options) {
80 // We do the call with settings so we can set cache to false.
81 // We do the call with settings so we can set cache to false.
@@ -83,14 +84,12 b' define(['
83 cache : false,
84 cache : false,
84 type : "GET",
85 type : "GET",
85 dataType : "json",
86 dataType : "json",
86 success : options.success,
87 error : this.create_basic_error_handler(options.error)
88 };
87 };
89 var url = this.api_url(path);
88 var url = this.api_url(path);
90 params = {};
89 params = {};
91 if (options.type) { params.type = options.type; }
90 if (options.type) { params.type = options.type; }
92 if (options.format) { params.format = options.format; }
91 if (options.format) { params.format = options.format; }
93 $.ajax(url + '?' + $.param(params), settings);
92 return utils.promising_ajax(url + '?' + $.param(params), settings);
94 };
93 };
95
94
96
95
@@ -114,33 +113,31 b' define(['
114 type : "POST",
113 type : "POST",
115 data: data,
114 data: data,
116 dataType : "json",
115 dataType : "json",
117 success : options.success || function() {},
118 error : this.create_basic_error_handler(options.error)
119 };
116 };
120 $.ajax(this.api_url(path), settings);
117 return utils.promising_ajax(this.api_url(path), settings);
121 };
118 };
122
119
123 Contents.prototype.delete = function(path, options) {
120 Contents.prototype.delete = function(path) {
124 var error_callback = options.error || function() {};
125 var settings = {
121 var settings = {
126 processData : false,
122 processData : false,
127 type : "DELETE",
123 type : "DELETE",
128 dataType : "json",
124 dataType : "json",
129 success : options.success || function() {},
125 };
130 error : function(xhr, status, error) {
126 var url = this.api_url(path);
127 return utils.promising_ajax(url, settings).catch(
128 // Translate certain errors to more specific ones.
129 function(error) {
131 // TODO: update IPEP27 to specify errors more precisely, so
130 // TODO: update IPEP27 to specify errors more precisely, so
132 // that error types can be detected here with certainty.
131 // that error types can be detected here with certainty.
133 if (xhr.status === 400) {
132 if (error.xhr.status === 400) {
134 error_callback(new Contents.DirectoryNotEmptyError());
133 throw new Contents.DirectoryNotEmptyError();
135 }
134 }
136 error_callback(utils.wrap_ajax_error(xhr, status, error));
135 throw error;
137 }
136 }
138 };
137 );
139 var url = this.api_url(path);
140 $.ajax(url, settings);
141 };
138 };
142
139
143 Contents.prototype.rename = function(path, new_path, options) {
140 Contents.prototype.rename = function(path, new_path) {
144 var data = {path: new_path};
141 var data = {path: new_path};
145 var settings = {
142 var settings = {
146 processData : false,
143 processData : false,
@@ -148,28 +145,24 b' define(['
148 data : JSON.stringify(data),
145 data : JSON.stringify(data),
149 dataType: "json",
146 dataType: "json",
150 contentType: 'application/json',
147 contentType: 'application/json',
151 success : options.success || function() {},
152 error : this.create_basic_error_handler(options.error)
153 };
148 };
154 var url = this.api_url(path);
149 var url = this.api_url(path);
155 $.ajax(url, settings);
150 return utils.promising_ajax(url, settings);
156 };
151 };
157
152
158 Contents.prototype.save = function(path, model, options) {
153 Contents.prototype.save = function(path, model) {
159 // We do the call with settings so we can set cache to false.
154 // We do the call with settings so we can set cache to false.
160 var settings = {
155 var settings = {
161 processData : false,
156 processData : false,
162 type : "PUT",
157 type : "PUT",
163 data : JSON.stringify(model),
158 data : JSON.stringify(model),
164 contentType: 'application/json',
159 contentType: 'application/json',
165 success : options.success || function() {},
166 error : this.create_basic_error_handler(options.error)
167 };
160 };
168 var url = this.api_url(path);
161 var url = this.api_url(path);
169 $.ajax(url, settings);
162 return utils.promising_ajax(url, settings);
170 };
163 };
171
164
172 Contents.prototype.copy = function(from_file, to_dir, options) {
165 Contents.prototype.copy = function(from_file, to_dir) {
173 // Copy a file into a given directory via POST
166 // Copy a file into a given directory via POST
174 // The server will select the name of the copied file
167 // The server will select the name of the copied file
175 var url = this.api_url(to_dir);
168 var url = this.api_url(to_dir);
@@ -179,54 +172,47 b' define(['
179 type: "POST",
172 type: "POST",
180 data: JSON.stringify({copy_from: from_file}),
173 data: JSON.stringify({copy_from: from_file}),
181 dataType : "json",
174 dataType : "json",
182 success: options.success || function() {},
183 error: this.create_basic_error_handler(options.error)
184 };
175 };
185 $.ajax(url, settings);
176 return utils.promising_ajax(url, settings);
186 };
177 };
187
178
188 /**
179 /**
189 * Checkpointing Functions
180 * Checkpointing Functions
190 */
181 */
191
182
192 Contents.prototype.create_checkpoint = function(path, options) {
183 Contents.prototype.create_checkpoint = function(path) {
193 var url = this.api_url(path, 'checkpoints');
184 var url = this.api_url(path, 'checkpoints');
194 var settings = {
185 var settings = {
195 type : "POST",
186 type : "POST",
196 success: options.success || function() {},
187 dataType : "json",
197 error : this.create_basic_error_handler(options.error)
198 };
188 };
199 $.ajax(url, settings);
189 return utils.promising_ajax(url, settings);
200 };
190 };
201
191
202 Contents.prototype.list_checkpoints = function(path, options) {
192 Contents.prototype.list_checkpoints = function(path) {
203 var url = this.api_url(path, 'checkpoints');
193 var url = this.api_url(path, 'checkpoints');
204 var settings = {
194 var settings = {
205 type : "GET",
195 type : "GET",
206 success: options.success,
196 cache: false,
207 error : this.create_basic_error_handler(options.error)
197 dataType: "json",
208 };
198 };
209 $.ajax(url, settings);
199 return utils.promising_ajax(url, settings);
210 };
200 };
211
201
212 Contents.prototype.restore_checkpoint = function(path, checkpoint_id, options) {
202 Contents.prototype.restore_checkpoint = function(path, checkpoint_id) {
213 var url = this.api_url(path, 'checkpoints', checkpoint_id);
203 var url = this.api_url(path, 'checkpoints', checkpoint_id);
214 var settings = {
204 var settings = {
215 type : "POST",
205 type : "POST",
216 success: options.success || function() {},
217 error : this.create_basic_error_handler(options.error)
218 };
206 };
219 $.ajax(url, settings);
207 return utils.promising_ajax(url, settings);
220 };
208 };
221
209
222 Contents.prototype.delete_checkpoint = function(path, checkpoint_id, options) {
210 Contents.prototype.delete_checkpoint = function(path, checkpoint_id) {
223 var url = this.api_url(path, 'checkpoints', checkpoint_id);
211 var url = this.api_url(path, 'checkpoints', checkpoint_id);
224 var settings = {
212 var settings = {
225 type : "DELETE",
213 type : "DELETE",
226 success: options.success || function() {},
227 error : this.create_basic_error_handler(options.error)
228 };
214 };
229 $.ajax(url, settings);
215 return utils.promising_ajax(url, settings);
230 };
216 };
231
217
232 /**
218 /**
@@ -244,11 +230,9 b' define(['
244 * last_modified: last modified dat
230 * last_modified: last modified dat
245 * @method list_notebooks
231 * @method list_notebooks
246 * @param {String} path The path to list notebooks in
232 * @param {String} path The path to list notebooks in
247 * @param {Object} options including success and error callbacks
248 */
233 */
249 Contents.prototype.list_contents = function(path, options) {
234 Contents.prototype.list_contents = function(path) {
250 options.type = 'directory';
235 return this.get(path, {type: 'directory'});
251 this.get(path, options);
252 };
236 };
253
237
254
238
@@ -65,14 +65,13 b' require(['
65
65
66 $('#new_notebook').click(function (e) {
66 $('#new_notebook').click(function (e) {
67 var w = window.open();
67 var w = window.open();
68 contents.new_untitled(common_options.notebook_path, {
68 contents.new_untitled(common_options.notebook_path, {type: "notebook"}).then(
69 type: "notebook",
69 function (data) {
70 success: function (data) {
71 w.location = utils.url_join_encode(
70 w.location = utils.url_join_encode(
72 common_options.base_url, 'notebooks', data.path
71 common_options.base_url, 'notebooks', data.path
73 );
72 );
74 },
73 },
75 error: function(error) {
74 function(error) {
76 w.close();
75 w.close();
77 dialog.modal({
76 dialog.modal({
78 title : 'Creating Notebook Failed',
77 title : 'Creating Notebook Failed',
@@ -80,7 +79,7 b' require(['
80 buttons : {'OK' : {'class' : 'btn-primary'}}
79 buttons : {'OK' : {'class' : 'btn-primary'}}
81 });
80 });
82 }
81 }
83 });
82 );
84 });
83 });
85
84
86 var interval_id=0;
85 var interval_id=0;
@@ -142,12 +142,12 b' define(['
142
142
143 NotebookList.prototype.load_list = function () {
143 NotebookList.prototype.load_list = function () {
144 var that = this;
144 var that = this;
145 this.contents.list_contents(that.notebook_path, {
145 this.contents.list_contents(that.notebook_path).then(
146 success: $.proxy(this.draw_notebook_list, this),
146 $.proxy(this.draw_notebook_list, this),
147 error: function(error) {
147 function(error) {
148 that.draw_notebook_list({content: []}, "Server error: " + error.message);
148 that.draw_notebook_list({content: []}, "Server error: " + error.message);
149 }
149 }
150 });
150 );
151 };
151 };
152
152
153 /**
153 /**
@@ -328,11 +328,11 b' define(['
328 Delete : {
328 Delete : {
329 class: "btn-danger",
329 class: "btn-danger",
330 click: function() {
330 click: function() {
331 notebooklist.contents.delete(path, {
331 notebooklist.contents.delete(path).then(
332 success: function() {
332 function() {
333 notebooklist.notebook_deleted(path);
333 notebooklist.notebook_deleted(path);
334 }
334 }
335 });
335 );
336 }
336 }
337 },
337 },
338 Cancel : {}
338 Cancel : {}
@@ -414,13 +414,11 b' define(['
414 }
414 }
415 filedata = item.data('filedata');
415 filedata = item.data('filedata');
416
416
417 var settings = {
417 var on_success = function () {
418 success : function () {
418 item.removeClass('new-file');
419 item.removeClass('new-file');
419 that.add_link(model, item);
420 that.add_link(model, item);
420 that.add_delete_button(item);
421 that.add_delete_button(item);
421 that.session_list.load_sessions();
422 that.session_list.load_sessions();
423 },
424 };
422 };
425
423
426 var exists = false;
424 var exists = false;
@@ -436,8 +434,8 b' define(['
436 Overwrite : {
434 Overwrite : {
437 class: "btn-danger",
435 class: "btn-danger",
438 click: function () {
436 click: function () {
439 that.contents.save(path, model, settings);
437 that.contents.save(path, model).then(on_success);
440 }
438 }
441 },
439 },
442 Cancel : {
440 Cancel : {
443 click: function() { item.remove(); }
441 click: function() { item.remove(); }
@@ -445,7 +443,7 b' define(['
445 }
443 }
446 });
444 });
447 } else {
445 } else {
448 that.contents.save(path, model, settings);
446 that.contents.save(path, model).then(on_success);
449 }
447 }
450
448
451 return false;
449 return false;
@@ -14,6 +14,7 b''
14 <link rel="stylesheet" href="{{ static_url("style/style.min.css") }}" type="text/css"/>
14 <link rel="stylesheet" href="{{ static_url("style/style.min.css") }}" type="text/css"/>
15 {% endblock %}
15 {% endblock %}
16 <link rel="stylesheet" href="{{ static_url("custom/custom.css") }}" type="text/css" />
16 <link rel="stylesheet" href="{{ static_url("custom/custom.css") }}" type="text/css" />
17 <script src="{{static_url("components/es6-promise/promise.min.js")}}" type="text/javascript" charset="utf-8"></script>
17 <script src="{{static_url("components/requirejs/require.js") }}" type="text/javascript" charset="utf-8"></script>
18 <script src="{{static_url("components/requirejs/require.js") }}" type="text/javascript" charset="utf-8"></script>
18 <script>
19 <script>
19 require.config({
20 require.config({
@@ -150,6 +150,7 b' def find_package_data():'
150 pjoin(components, "bootstrap", "js", "bootstrap.min.js"),
150 pjoin(components, "bootstrap", "js", "bootstrap.min.js"),
151 pjoin(components, "bootstrap-tour", "build", "css", "bootstrap-tour.min.css"),
151 pjoin(components, "bootstrap-tour", "build", "css", "bootstrap-tour.min.css"),
152 pjoin(components, "bootstrap-tour", "build", "js", "bootstrap-tour.min.js"),
152 pjoin(components, "bootstrap-tour", "build", "js", "bootstrap-tour.min.js"),
153 pjoin(components, "es6-promise", "*.js"),
153 pjoin(components, "font-awesome", "fonts", "*.*"),
154 pjoin(components, "font-awesome", "fonts", "*.*"),
154 pjoin(components, "google-caja", "html-css-sanitizer-minified.js"),
155 pjoin(components, "google-caja", "html-css-sanitizer-minified.js"),
155 pjoin(components, "highlight.js", "build", "highlight.pack.js"),
156 pjoin(components, "highlight.js", "build", "highlight.pack.js"),
General Comments 0
You need to be logged in to leave comments. Login now