##// END OF EJS Templates
removing monkeypatch, importing rest of codemirror default theme
Nicholas Bollweg (Nick) -
Show More
@@ -0,0 +1,5 b''
1 /* load the codemirror defaults as LESS so that highlight.less
2 can load default theme declarations by reference without pulling in the
3 nasty positioning
4 */
5 @import (less) "../../components/codemirror/lib/codemirror.css";
@@ -1,873 +1,862 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 'base/js/namespace',
6 6 'jquery',
7 7 'codemirror/lib/codemirror',
8 8 // silently upgrades CodeMirror
9 9 'codemirror/mode/meta',
10 10 ], function(IPython, $, CodeMirror){
11 11 "use strict";
12 12
13 13 IPython.load_extensions = function () {
14 14 // load one or more IPython notebook extensions with requirejs
15 15
16 16 var extensions = [];
17 17 var extension_names = arguments;
18 18 for (var i = 0; i < extension_names.length; i++) {
19 19 extensions.push("nbextensions/" + arguments[i]);
20 20 }
21 21
22 22 require(extensions,
23 23 function () {
24 24 for (var i = 0; i < arguments.length; i++) {
25 25 var ext = arguments[i];
26 26 var ext_name = extension_names[i];
27 27 // success callback
28 28 console.log("Loaded extension: " + ext_name);
29 29 if (ext && ext.load_ipython_extension !== undefined) {
30 30 ext.load_ipython_extension();
31 31 }
32 32 }
33 33 },
34 34 function (err) {
35 35 // failure callback
36 36 console.log("Failed to load extension(s):", err.requireModules, err);
37 37 }
38 38 );
39 39 };
40 40
41 41 //============================================================================
42 42 // Cross-browser RegEx Split
43 43 //============================================================================
44 44
45 45 // This code has been MODIFIED from the code licensed below to not replace the
46 46 // default browser split. The license is reproduced here.
47 47
48 48 // see http://blog.stevenlevithan.com/archives/cross-browser-split for more info:
49 49 /*!
50 50 * Cross-Browser Split 1.1.1
51 51 * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
52 52 * Available under the MIT License
53 53 * ECMAScript compliant, uniform cross-browser split method
54 54 */
55 55
56 56 /**
57 57 * Splits a string into an array of strings using a regex or string
58 58 * separator. Matches of the separator are not included in the result array.
59 59 * However, if `separator` is a regex that contains capturing groups,
60 60 * backreferences are spliced into the result each time `separator` is
61 61 * matched. Fixes browser bugs compared to the native
62 62 * `String.prototype.split` and can be used reliably cross-browser.
63 63 * @param {String} str String to split.
64 64 * @param {RegExp|String} separator Regex or string to use for separating
65 65 * the string.
66 66 * @param {Number} [limit] Maximum number of items to include in the result
67 67 * array.
68 68 * @returns {Array} Array of substrings.
69 69 * @example
70 70 *
71 71 * // Basic use
72 72 * regex_split('a b c d', ' ');
73 73 * // -> ['a', 'b', 'c', 'd']
74 74 *
75 75 * // With limit
76 76 * regex_split('a b c d', ' ', 2);
77 77 * // -> ['a', 'b']
78 78 *
79 79 * // Backreferences in result array
80 80 * regex_split('..word1 word2..', /([a-z]+)(\d+)/i);
81 81 * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
82 82 */
83 83 var regex_split = function (str, separator, limit) {
84 84 // If `separator` is not a regex, use `split`
85 85 if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
86 86 return split.call(str, separator, limit);
87 87 }
88 88 var output = [],
89 89 flags = (separator.ignoreCase ? "i" : "") +
90 90 (separator.multiline ? "m" : "") +
91 91 (separator.extended ? "x" : "") + // Proposed for ES6
92 92 (separator.sticky ? "y" : ""), // Firefox 3+
93 93 lastLastIndex = 0,
94 94 // Make `global` and avoid `lastIndex` issues by working with a copy
95 95 separator = new RegExp(separator.source, flags + "g"),
96 96 separator2, match, lastIndex, lastLength;
97 97 str += ""; // Type-convert
98 98
99 99 var compliantExecNpcg = typeof(/()??/.exec("")[1]) === "undefined";
100 100 if (!compliantExecNpcg) {
101 101 // Doesn't need flags gy, but they don't hurt
102 102 separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
103 103 }
104 104 /* Values for `limit`, per the spec:
105 105 * If undefined: 4294967295 // Math.pow(2, 32) - 1
106 106 * If 0, Infinity, or NaN: 0
107 107 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
108 108 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
109 109 * If other: Type-convert, then use the above rules
110 110 */
111 111 limit = typeof(limit) === "undefined" ?
112 112 -1 >>> 0 : // Math.pow(2, 32) - 1
113 113 limit >>> 0; // ToUint32(limit)
114 114 while (match = separator.exec(str)) {
115 115 // `separator.lastIndex` is not reliable cross-browser
116 116 lastIndex = match.index + match[0].length;
117 117 if (lastIndex > lastLastIndex) {
118 118 output.push(str.slice(lastLastIndex, match.index));
119 119 // Fix browsers whose `exec` methods don't consistently return `undefined` for
120 120 // nonparticipating capturing groups
121 121 if (!compliantExecNpcg && match.length > 1) {
122 122 match[0].replace(separator2, function () {
123 123 for (var i = 1; i < arguments.length - 2; i++) {
124 124 if (typeof(arguments[i]) === "undefined") {
125 125 match[i] = undefined;
126 126 }
127 127 }
128 128 });
129 129 }
130 130 if (match.length > 1 && match.index < str.length) {
131 131 Array.prototype.push.apply(output, match.slice(1));
132 132 }
133 133 lastLength = match[0].length;
134 134 lastLastIndex = lastIndex;
135 135 if (output.length >= limit) {
136 136 break;
137 137 }
138 138 }
139 139 if (separator.lastIndex === match.index) {
140 140 separator.lastIndex++; // Avoid an infinite loop
141 141 }
142 142 }
143 143 if (lastLastIndex === str.length) {
144 144 if (lastLength || !separator.test("")) {
145 145 output.push("");
146 146 }
147 147 } else {
148 148 output.push(str.slice(lastLastIndex));
149 149 }
150 150 return output.length > limit ? output.slice(0, limit) : output;
151 151 };
152 152
153 153 //============================================================================
154 154 // End contributed Cross-browser RegEx Split
155 155 //============================================================================
156 156
157 157
158 158 var uuid = function () {
159 159 /**
160 160 * http://www.ietf.org/rfc/rfc4122.txt
161 161 */
162 162 var s = [];
163 163 var hexDigits = "0123456789ABCDEF";
164 164 for (var i = 0; i < 32; i++) {
165 165 s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
166 166 }
167 167 s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
168 168 s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
169 169
170 170 var uuid = s.join("");
171 171 return uuid;
172 172 };
173 173
174 174
175 175 //Fix raw text to parse correctly in crazy XML
176 176 function xmlencode(string) {
177 177 return string.replace(/\&/g,'&'+'amp;')
178 178 .replace(/</g,'&'+'lt;')
179 179 .replace(/>/g,'&'+'gt;')
180 180 .replace(/\'/g,'&'+'apos;')
181 181 .replace(/\"/g,'&'+'quot;')
182 182 .replace(/`/g,'&'+'#96;');
183 183 }
184 184
185 185
186 186 //Map from terminal commands to CSS classes
187 187 var ansi_colormap = {
188 188 "01":"ansibold",
189 189
190 190 "30":"ansiblack",
191 191 "31":"ansired",
192 192 "32":"ansigreen",
193 193 "33":"ansiyellow",
194 194 "34":"ansiblue",
195 195 "35":"ansipurple",
196 196 "36":"ansicyan",
197 197 "37":"ansigray",
198 198
199 199 "40":"ansibgblack",
200 200 "41":"ansibgred",
201 201 "42":"ansibggreen",
202 202 "43":"ansibgyellow",
203 203 "44":"ansibgblue",
204 204 "45":"ansibgpurple",
205 205 "46":"ansibgcyan",
206 206 "47":"ansibggray"
207 207 };
208 208
209 209 function _process_numbers(attrs, numbers) {
210 210 // process ansi escapes
211 211 var n = numbers.shift();
212 212 if (ansi_colormap[n]) {
213 213 if ( ! attrs["class"] ) {
214 214 attrs["class"] = ansi_colormap[n];
215 215 } else {
216 216 attrs["class"] += " " + ansi_colormap[n];
217 217 }
218 218 } else if (n == "38" || n == "48") {
219 219 // VT100 256 color or 24 bit RGB
220 220 if (numbers.length < 2) {
221 221 console.log("Not enough fields for VT100 color", numbers);
222 222 return;
223 223 }
224 224
225 225 var index_or_rgb = numbers.shift();
226 226 var r,g,b;
227 227 if (index_or_rgb == "5") {
228 228 // 256 color
229 229 var idx = parseInt(numbers.shift());
230 230 if (idx < 16) {
231 231 // indexed ANSI
232 232 // ignore bright / non-bright distinction
233 233 idx = idx % 8;
234 234 var ansiclass = ansi_colormap[n[0] + (idx % 8).toString()];
235 235 if ( ! attrs["class"] ) {
236 236 attrs["class"] = ansiclass;
237 237 } else {
238 238 attrs["class"] += " " + ansiclass;
239 239 }
240 240 return;
241 241 } else if (idx < 232) {
242 242 // 216 color 6x6x6 RGB
243 243 idx = idx - 16;
244 244 b = idx % 6;
245 245 g = Math.floor(idx / 6) % 6;
246 246 r = Math.floor(idx / 36) % 6;
247 247 // convert to rgb
248 248 r = (r * 51);
249 249 g = (g * 51);
250 250 b = (b * 51);
251 251 } else {
252 252 // grayscale
253 253 idx = idx - 231;
254 254 // it's 1-24 and should *not* include black or white,
255 255 // so a 26 point scale
256 256 r = g = b = Math.floor(idx * 256 / 26);
257 257 }
258 258 } else if (index_or_rgb == "2") {
259 259 // Simple 24 bit RGB
260 260 if (numbers.length > 3) {
261 261 console.log("Not enough fields for RGB", numbers);
262 262 return;
263 263 }
264 264 r = numbers.shift();
265 265 g = numbers.shift();
266 266 b = numbers.shift();
267 267 } else {
268 268 console.log("unrecognized control", numbers);
269 269 return;
270 270 }
271 271 if (r !== undefined) {
272 272 // apply the rgb color
273 273 var line;
274 274 if (n == "38") {
275 275 line = "color: ";
276 276 } else {
277 277 line = "background-color: ";
278 278 }
279 279 line = line + "rgb(" + r + "," + g + "," + b + ");";
280 280 if ( !attrs.style ) {
281 281 attrs.style = line;
282 282 } else {
283 283 attrs.style += " " + line;
284 284 }
285 285 }
286 286 }
287 287 }
288 288
289 289 function ansispan(str) {
290 290 // ansispan function adapted from github.com/mmalecki/ansispan (MIT License)
291 291 // regular ansi escapes (using the table above)
292 292 var is_open = false;
293 293 return str.replace(/\033\[(0?[01]|22|39)?([;\d]+)?m/g, function(match, prefix, pattern) {
294 294 if (!pattern) {
295 295 // [(01|22|39|)m close spans
296 296 if (is_open) {
297 297 is_open = false;
298 298 return "</span>";
299 299 } else {
300 300 return "";
301 301 }
302 302 } else {
303 303 is_open = true;
304 304
305 305 // consume sequence of color escapes
306 306 var numbers = pattern.match(/\d+/g);
307 307 var attrs = {};
308 308 while (numbers.length > 0) {
309 309 _process_numbers(attrs, numbers);
310 310 }
311 311
312 312 var span = "<span ";
313 313 for (var attr in attrs) {
314 314 var value = attrs[attr];
315 315 span = span + " " + attr + '="' + attrs[attr] + '"';
316 316 }
317 317 return span + ">";
318 318 }
319 319 });
320 320 }
321 321
322 322 // Transform ANSI color escape codes into HTML <span> tags with css
323 323 // classes listed in the above ansi_colormap object. The actual color used
324 324 // are set in the css file.
325 325 function fixConsole(txt) {
326 326 txt = xmlencode(txt);
327 327 var re = /\033\[([\dA-Fa-f;]*?)m/;
328 328 var opened = false;
329 329 var cmds = [];
330 330 var opener = "";
331 331 var closer = "";
332 332
333 333 // Strip all ANSI codes that are not color related. Matches
334 334 // all ANSI codes that do not end with "m".
335 335 var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
336 336 txt = txt.replace(ignored_re, "");
337 337
338 338 // color ansi codes
339 339 txt = ansispan(txt);
340 340 return txt;
341 341 }
342 342
343 343 // Remove chunks that should be overridden by the effect of
344 344 // carriage return characters
345 345 function fixCarriageReturn(txt) {
346 346 var tmp = txt;
347 347 do {
348 348 txt = tmp;
349 349 tmp = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
350 350 tmp = tmp.replace(/^.*\r+/gm, ''); // Other \r --> clear line
351 351 } while (tmp.length < txt.length);
352 352 return txt;
353 353 }
354 354
355 355 // Locate any URLs and convert them to a anchor tag
356 356 function autoLinkUrls(txt) {
357 357 return txt.replace(/(^|\s)(https?|ftp)(:[^'">\s]+)/gi,
358 358 "$1<a target=\"_blank\" href=\"$2$3\">$2$3</a>");
359 359 }
360 360
361 361 var points_to_pixels = function (points) {
362 362 /**
363 363 * A reasonably good way of converting between points and pixels.
364 364 */
365 365 var test = $('<div style="display: none; width: 10000pt; padding:0; border:0;"></div>');
366 366 $(body).append(test);
367 367 var pixel_per_point = test.width()/10000;
368 368 test.remove();
369 369 return Math.floor(points*pixel_per_point);
370 370 };
371 371
372 372 var always_new = function (constructor) {
373 373 /**
374 374 * wrapper around contructor to avoid requiring `var a = new constructor()`
375 375 * useful for passing constructors as callbacks,
376 376 * not for programmer laziness.
377 377 * from http://programmers.stackexchange.com/questions/118798
378 378 */
379 379 return function () {
380 380 var obj = Object.create(constructor.prototype);
381 381 constructor.apply(obj, arguments);
382 382 return obj;
383 383 };
384 384 };
385 385
386 386 var url_path_join = function () {
387 387 /**
388 388 * join a sequence of url components with '/'
389 389 */
390 390 var url = '';
391 391 for (var i = 0; i < arguments.length; i++) {
392 392 if (arguments[i] === '') {
393 393 continue;
394 394 }
395 395 if (url.length > 0 && url[url.length-1] != '/') {
396 396 url = url + '/' + arguments[i];
397 397 } else {
398 398 url = url + arguments[i];
399 399 }
400 400 }
401 401 url = url.replace(/\/\/+/, '/');
402 402 return url;
403 403 };
404 404
405 405 var url_path_split = function (path) {
406 406 /**
407 407 * Like os.path.split for URLs.
408 408 * Always returns two strings, the directory path and the base filename
409 409 */
410 410
411 411 var idx = path.lastIndexOf('/');
412 412 if (idx === -1) {
413 413 return ['', path];
414 414 } else {
415 415 return [ path.slice(0, idx), path.slice(idx + 1) ];
416 416 }
417 417 };
418 418
419 419 var parse_url = function (url) {
420 420 /**
421 421 * an `a` element with an href allows attr-access to the parsed segments of a URL
422 422 * a = parse_url("http://localhost:8888/path/name#hash")
423 423 * a.protocol = "http:"
424 424 * a.host = "localhost:8888"
425 425 * a.hostname = "localhost"
426 426 * a.port = 8888
427 427 * a.pathname = "/path/name"
428 428 * a.hash = "#hash"
429 429 */
430 430 var a = document.createElement("a");
431 431 a.href = url;
432 432 return a;
433 433 };
434 434
435 435 var encode_uri_components = function (uri) {
436 436 /**
437 437 * encode just the components of a multi-segment uri,
438 438 * leaving '/' separators
439 439 */
440 440 return uri.split('/').map(encodeURIComponent).join('/');
441 441 };
442 442
443 443 var url_join_encode = function () {
444 444 /**
445 445 * join a sequence of url components with '/',
446 446 * encoding each component with encodeURIComponent
447 447 */
448 448 return encode_uri_components(url_path_join.apply(null, arguments));
449 449 };
450 450
451 451
452 452 var splitext = function (filename) {
453 453 /**
454 454 * mimic Python os.path.splitext
455 455 * Returns ['base', '.ext']
456 456 */
457 457 var idx = filename.lastIndexOf('.');
458 458 if (idx > 0) {
459 459 return [filename.slice(0, idx), filename.slice(idx)];
460 460 } else {
461 461 return [filename, ''];
462 462 }
463 463 };
464 464
465 465
466 466 var escape_html = function (text) {
467 467 /**
468 468 * escape text to HTML
469 469 */
470 470 return $("<div/>").text(text).html();
471 471 };
472 472
473 473
474 474 var get_body_data = function(key) {
475 475 /**
476 476 * get a url-encoded item from body.data and decode it
477 477 * we should never have any encoded URLs anywhere else in code
478 478 * until we are building an actual request
479 479 */
480 480 return decodeURIComponent($('body').data(key));
481 481 };
482 482
483 483 var to_absolute_cursor_pos = function (cm, cursor) {
484 484 /**
485 485 * get the absolute cursor position from CodeMirror's col, ch
486 486 */
487 487 if (!cursor) {
488 488 cursor = cm.getCursor();
489 489 }
490 490 var cursor_pos = cursor.ch;
491 491 for (var i = 0; i < cursor.line; i++) {
492 492 cursor_pos += cm.getLine(i).length + 1;
493 493 }
494 494 return cursor_pos;
495 495 };
496 496
497 497 var from_absolute_cursor_pos = function (cm, cursor_pos) {
498 498 /**
499 499 * turn absolute cursor postion into CodeMirror col, ch cursor
500 500 */
501 501 var i, line;
502 502 var offset = 0;
503 503 for (i = 0, line=cm.getLine(i); line !== undefined; i++, line=cm.getLine(i)) {
504 504 if (offset + line.length < cursor_pos) {
505 505 offset += line.length + 1;
506 506 } else {
507 507 return {
508 508 line : i,
509 509 ch : cursor_pos - offset,
510 510 };
511 511 }
512 512 }
513 513 // reached end, return endpoint
514 514 return {
515 515 ch : line.length - 1,
516 516 line : i - 1,
517 517 };
518 518 };
519 519
520 520 // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
521 521 var browser = (function() {
522 522 if (typeof navigator === 'undefined') {
523 523 // navigator undefined in node
524 524 return 'None';
525 525 }
526 526 var N= navigator.appName, ua= navigator.userAgent, tem;
527 527 var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
528 528 if (M && (tem= ua.match(/version\/([\.\d]+)/i)) !== null) M[2]= tem[1];
529 529 M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?'];
530 530 return M;
531 531 })();
532 532
533 533 // http://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
534 534 var platform = (function () {
535 535 if (typeof navigator === 'undefined') {
536 536 // navigator undefined in node
537 537 return 'None';
538 538 }
539 539 var OSName="None";
540 540 if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows";
541 541 if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS";
542 542 if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
543 543 if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
544 544 return OSName;
545 545 })();
546 546
547 547 var get_url_param = function (name) {
548 548 // get a URL parameter. I cannot believe we actually need this.
549 549 // Based on http://stackoverflow.com/a/25359264/938949
550 550 var match = new RegExp('[\?&]' + name + '=([^&]*)').exec(window.location.search);
551 551 if (match){
552 552 return decodeURIComponent(match[1] || '');
553 553 }
554 554 };
555 555
556 556 var is_or_has = function (a, b) {
557 557 /**
558 558 * Is b a child of a or a itself?
559 559 */
560 560 return a.has(b).length !==0 || a.is(b);
561 561 };
562 562
563 563 var is_focused = function (e) {
564 564 /**
565 565 * Is element e, or one of its children focused?
566 566 */
567 567 e = $(e);
568 568 var target = $(document.activeElement);
569 569 if (target.length > 0) {
570 570 if (is_or_has(e, target)) {
571 571 return true;
572 572 } else {
573 573 return false;
574 574 }
575 575 } else {
576 576 return false;
577 577 }
578 578 };
579 579
580 580 var mergeopt = function(_class, options, overwrite){
581 581 options = options || {};
582 582 overwrite = overwrite || {};
583 583 return $.extend(true, {}, _class.options_default, options, overwrite);
584 584 };
585 585
586 586 var ajax_error_msg = function (jqXHR) {
587 587 /**
588 588 * Return a JSON error message if there is one,
589 589 * otherwise the basic HTTP status text.
590 590 */
591 591 if (jqXHR.responseJSON && jqXHR.responseJSON.traceback) {
592 592 return jqXHR.responseJSON.traceback;
593 593 } else if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
594 594 return jqXHR.responseJSON.message;
595 595 } else {
596 596 return jqXHR.statusText;
597 597 }
598 598 };
599 599 var log_ajax_error = function (jqXHR, status, error) {
600 600 /**
601 601 * log ajax failures with informative messages
602 602 */
603 603 var msg = "API request failed (" + jqXHR.status + "): ";
604 604 console.log(jqXHR);
605 605 msg += ajax_error_msg(jqXHR);
606 606 console.log(msg);
607 607 };
608
609 // monkeypatch from CM4.7+... will be available soon, along with aliases!
610 CodeMirror.findModeByName = CodeMirror.findModeByName || function(name) {
611 name = name.toLowerCase();
612 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
613 var info = CodeMirror.modeInfo[i];
614 if (info.name.toLowerCase() == name) return info;
615 if (info.alias) for (var j = 0; j < info.alias.length; j++)
616 if (info.alias[j].toLowerCase() == name) return info;
617 }
618 };
619 608
620 609 var requireCodeMirrorMode = function (mode, callback, errback) {
621 610 /**
622 611 * find a predefined mode or detect from CM metadata then
623 612 * require and callback with the resolveable mode string: mime or
624 613 * custom name
625 614 */
626 615 if (typeof mode != "string") mode = mode.name;
627 616
628 617 if (CodeMirror.modes.hasOwnProperty(mode)) {
629 618 callback(mode);
630 619 return;
631 620 }
632 621
633 622 var info = CodeMirror.findModeByName(mode) ||
634 623 CodeMirror.findModeByExtension(mode.split(".").slice(-1)) ||
635 624 CodeMirror.findModeByMIME(mode);
636 625
637 626 if(!info){
638 627 errback && errback();
639 628 return;
640 629 }
641 630
642 631 require([
643 632 // might want to use CodeMirror.modeURL here
644 633 ['codemirror/mode', info.mode, info.mode].join('/'),
645 634 ], function() { callback(info.mime); }, errback
646 635 );
647 636 };
648 637
649 638 /** Error type for wrapped XHR errors. */
650 639 var XHR_ERROR = 'XhrError';
651 640
652 641 /**
653 642 * Wraps an AJAX error as an Error object.
654 643 */
655 644 var wrap_ajax_error = function (jqXHR, status, error) {
656 645 var wrapped_error = new Error(ajax_error_msg(jqXHR));
657 646 wrapped_error.name = XHR_ERROR;
658 647 // provide xhr response
659 648 wrapped_error.xhr = jqXHR;
660 649 wrapped_error.xhr_status = status;
661 650 wrapped_error.xhr_error = error;
662 651 return wrapped_error;
663 652 };
664 653
665 654 var promising_ajax = function(url, settings) {
666 655 /**
667 656 * Like $.ajax, but returning an ES6 promise. success and error settings
668 657 * will be ignored.
669 658 */
670 659 settings = settings || {};
671 660 return new Promise(function(resolve, reject) {
672 661 settings.success = function(data, status, jqXHR) {
673 662 resolve(data);
674 663 };
675 664 settings.error = function(jqXHR, status, error) {
676 665 log_ajax_error(jqXHR, status, error);
677 666 reject(wrap_ajax_error(jqXHR, status, error));
678 667 };
679 668 $.ajax(url, settings);
680 669 });
681 670 };
682 671
683 672 var WrappedError = function(message, error){
684 673 /**
685 674 * Wrappable Error class
686 675 *
687 676 * The Error class doesn't actually act on `this`. Instead it always
688 677 * returns a new instance of Error. Here we capture that instance so we
689 678 * can apply it's properties to `this`.
690 679 */
691 680 var tmp = Error.apply(this, [message]);
692 681
693 682 // Copy the properties of the error over to this.
694 683 var properties = Object.getOwnPropertyNames(tmp);
695 684 for (var i = 0; i < properties.length; i++) {
696 685 this[properties[i]] = tmp[properties[i]];
697 686 }
698 687
699 688 // Keep a stack of the original error messages.
700 689 if (error instanceof WrappedError) {
701 690 this.error_stack = error.error_stack;
702 691 } else {
703 692 this.error_stack = [error];
704 693 }
705 694 this.error_stack.push(tmp);
706 695
707 696 return this;
708 697 };
709 698
710 699 WrappedError.prototype = Object.create(Error.prototype, {});
711 700
712 701
713 702 var load_class = function(class_name, module_name, registry) {
714 703 /**
715 704 * Tries to load a class
716 705 *
717 706 * Tries to load a class from a module using require.js, if a module
718 707 * is specified, otherwise tries to load a class from the global
719 708 * registry, if the global registry is provided.
720 709 */
721 710 return new Promise(function(resolve, reject) {
722 711
723 712 // Try loading the view module using require.js
724 713 if (module_name) {
725 714 require([module_name], function(module) {
726 715 if (module[class_name] === undefined) {
727 716 reject(new Error('Class '+class_name+' not found in module '+module_name));
728 717 } else {
729 718 resolve(module[class_name]);
730 719 }
731 720 }, reject);
732 721 } else {
733 722 if (registry && registry[class_name]) {
734 723 resolve(registry[class_name]);
735 724 } else {
736 725 reject(new Error('Class '+class_name+' not found in registry '));
737 726 }
738 727 }
739 728 });
740 729 };
741 730
742 731 var resolve_promises_dict = function(d) {
743 732 /**
744 733 * Resolve a promiseful dictionary.
745 734 * Returns a single Promise.
746 735 */
747 736 var keys = Object.keys(d);
748 737 var values = [];
749 738 keys.forEach(function(key) {
750 739 values.push(d[key]);
751 740 });
752 741 return Promise.all(values).then(function(v) {
753 742 d = {};
754 743 for(var i=0; i<keys.length; i++) {
755 744 d[keys[i]] = v[i];
756 745 }
757 746 return d;
758 747 });
759 748 };
760 749
761 750 var WrappedError = function(message, error){
762 751 /**
763 752 * Wrappable Error class
764 753 *
765 754 * The Error class doesn't actually act on `this`. Instead it always
766 755 * returns a new instance of Error. Here we capture that instance so we
767 756 * can apply it's properties to `this`.
768 757 */
769 758 var tmp = Error.apply(this, [message]);
770 759
771 760 // Copy the properties of the error over to this.
772 761 var properties = Object.getOwnPropertyNames(tmp);
773 762 for (var i = 0; i < properties.length; i++) {
774 763 this[properties[i]] = tmp[properties[i]];
775 764 }
776 765
777 766 // Keep a stack of the original error messages.
778 767 if (error instanceof WrappedError) {
779 768 this.error_stack = error.error_stack;
780 769 } else {
781 770 this.error_stack = [error];
782 771 }
783 772 this.error_stack.push(tmp);
784 773
785 774 return this;
786 775 };
787 776
788 777 WrappedError.prototype = Object.create(Error.prototype, {});
789 778
790 779 var reject = function(message, log) {
791 780 /**
792 781 * Creates a wrappable Promise rejection function.
793 782 *
794 783 * Creates a function that returns a Promise.reject with a new WrappedError
795 784 * that has the provided message and wraps the original error that
796 785 * caused the promise to reject.
797 786 */
798 787 return function(error) {
799 788 var wrapped_error = new WrappedError(message, error);
800 789 if (log) console.error(wrapped_error);
801 790 return Promise.reject(wrapped_error);
802 791 };
803 792 };
804 793
805 794 var typeset = function(element, text) {
806 795 /**
807 796 * Apply MathJax rendering to an element, and optionally set its text
808 797 *
809 798 * If MathJax is not available, make no changes.
810 799 *
811 800 * Returns the output any number of typeset elements, or undefined if
812 801 * MathJax was not available.
813 802 *
814 803 * Parameters
815 804 * ----------
816 805 * element: Node, NodeList, or jQuery selection
817 806 * text: option string
818 807 */
819 808 if(!window.MathJax){
820 809 return;
821 810 }
822 811 var $el = element.jquery ? element : $(element);
823 812 if(arguments.length > 1){
824 813 $el.text(text);
825 814 }
826 815 return $el.map(function(){
827 816 // MathJax takes a DOM node: $.map makes `this` the context
828 817 return MathJax.Hub.Queue(["Typeset", MathJax.Hub, this]);
829 818 });
830 819 };
831 820
832 821 var utils = {
833 822 regex_split : regex_split,
834 823 uuid : uuid,
835 824 fixConsole : fixConsole,
836 825 fixCarriageReturn : fixCarriageReturn,
837 826 autoLinkUrls : autoLinkUrls,
838 827 points_to_pixels : points_to_pixels,
839 828 get_body_data : get_body_data,
840 829 parse_url : parse_url,
841 830 url_path_split : url_path_split,
842 831 url_path_join : url_path_join,
843 832 url_join_encode : url_join_encode,
844 833 encode_uri_components : encode_uri_components,
845 834 splitext : splitext,
846 835 escape_html : escape_html,
847 836 always_new : always_new,
848 837 to_absolute_cursor_pos : to_absolute_cursor_pos,
849 838 from_absolute_cursor_pos : from_absolute_cursor_pos,
850 839 browser : browser,
851 840 platform: platform,
852 841 get_url_param: get_url_param,
853 842 is_or_has : is_or_has,
854 843 is_focused : is_focused,
855 844 mergeopt: mergeopt,
856 845 ajax_error_msg : ajax_error_msg,
857 846 log_ajax_error : log_ajax_error,
858 847 requireCodeMirrorMode : requireCodeMirrorMode,
859 848 XHR_ERROR : XHR_ERROR,
860 849 wrap_ajax_error : wrap_ajax_error,
861 850 promising_ajax : promising_ajax,
862 851 WrappedError: WrappedError,
863 852 load_class: load_class,
864 853 resolve_promises_dict: resolve_promises_dict,
865 854 reject: reject,
866 855 typeset: typeset,
867 856 };
868 857
869 858 // Backwards compatability.
870 859 IPython.utils = utils;
871 860
872 861 return utils;
873 862 });
@@ -1,164 +1,112 b''
1 1 /*
2 2
3 3 Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
4 4 Adapted from GitHub theme
5 5
6 6 */
7 7
8 pre code {
9 display: block;
10 padding: 0.5em;
8 @import (reference) "highlight-refs.less";
9
10 @highlight-base: #000;
11
12 .highlight-base{
13 color: @highlight-base;
14 }
15
16 .highlight-variable{
17 .highlight-base();
18 }
19
20 .highlight-variable-2{
21 color: lighten(@highlight-base, 10%);
11 22 }
12 23
13 .highlight-base,
14 pre code,
15 pre .subst,
16 pre .tag .title,
17 pre .lisp .title,
18 pre .clojure .built_in,
19 pre .nginx .title {
20 color: black;
24 .highlight-variable-3{
25 color: lighten(@highlight-base, 20%);
21 26 }
22 27
23 .highlight-string,
24 pre .string,
25 pre .constant,
26 pre .parent,
27 pre .tag .value,
28 pre .rules .value,
29 pre .rules .value .number,
30 pre .preprocessor,
31 pre .ruby .symbol,
32 pre .ruby .symbol .string,
33 pre .aggregate,
34 pre .template_tag,
35 pre .django .variable,
36 pre .smalltalk .class,
37 pre .addition,
38 pre .flow,
39 pre .stream,
40 pre .bash .variable,
41 pre .apache .tag,
42 pre .apache .cbracket,
43 pre .tex .command,
44 pre .tex .special,
45 pre .erlang_repl .function_or_atom,
46 pre .markdown .header {
28 .highlight-string{
47 29 color: #BA2121;
48 30 }
49 31
50 .highlight-comment,
51 pre .comment,
52 pre .annotation,
53 pre .template_comment,
54 pre .diff .header,
55 pre .chunk,
56 pre .markdown .blockquote {
32 .highlight-comment{
57 33 color: #408080;
58 34 font-style: italic;
59 35 }
60 36
61 .highlight-number,
62 pre .number,
63 pre .date,
64 pre .regexp,
65 pre .literal,
66 pre .smalltalk .symbol,
67 pre .smalltalk .char,
68 pre .go .constant,
69 pre .change,
70 pre .markdown .bullet,
71 pre .markdown .link_url {
37 .highlight-number{
72 38 color: #080;
73 39 }
74 40
75 pre .label,
76 pre .javadoc,
77 pre .ruby .string,
78 pre .decorator,
79 pre .filter .argument,
80 pre .localvars,
81 pre .array,
82 pre .attr_selector,
83 pre .important,
84 pre .pseudo,
85 pre .pi,
86 pre .doctype,
87 pre .deletion,
88 pre .envvar,
89 pre .shebang,
90 pre .apache .sqbracket,
91 pre .nginx .built_in,
92 pre .tex .formula,
93 pre .erlang_repl .reserved,
94 pre .prompt,
95 pre .markdown .link_label,
96 pre .vhdl .attribute,
97 pre .clojure .attribute,
98 pre .coffeescript .property {
99 color: #88F
41 .highlight-atom{
42 color: #88F;
100 43 }
101 44
102 .highlight-keyword,
103 pre .keyword,
104 pre .id,
105 pre .phpdoc,
106 pre .aggregate,
107 pre .css .tag,
108 pre .javadoctag,
109 pre .phpdoc,
110 pre .yardoctag,
111 pre .smalltalk .class,
112 pre .winutils,
113 pre .bash .variable,
114 pre .apache .tag,
115 pre .go .typename,
116 pre .tex .command,
117 pre .markdown .strong,
118 pre .request,
119 pre .status {
45 .highlight-keyword{
120 46 color: #008000;
121 47 font-weight: bold;
122 48 }
123 49
124 .highlight-builtin,
125 pre .built_in {
50 .highlight-builtin{
126 51 color: #008000;
127 52 }
128 53
129 pre .markdown .emphasis {
130 font-style: italic;
54 .highlight-error{
55 color: #f00;
131 56 }
132 57
133 pre .nginx .built_in {
134 font-weight: normal;
58 .highlight-operator{
59 color: #AA22FF;
60 font-weight: bold;
135 61 }
136 62
137 pre .coffeescript .javascript,
138 pre .javascript .xml,
139 pre .tex .formula,
140 pre .xml .javascript,
141 pre .xml .vbscript,
142 pre .xml .css,
143 pre .xml .cdata {
144 opacity: 0.5;
63 .highlight-meta{
64 color: #AA22FF;
145 65 }
146 66
67 /* previously not defined, copying from default codemirror */
68 .highlight-def{ .cm-s-default.cm-def() }
69 .highlight-punctuation{ .cm-s-default.cm-punctuation() }
70 .highlight-property{ .cm-s-default.cm-property() }
71 .highlight-string-2{ .cm-s-default.cm-string-2() }
72 .highlight-qualifier{ .cm-s-default.cm-qualifier() }
73 .highlight-bracket{ .cm-s-default.cm-bracket() }
74 .highlight-tag{ .cm-s-default.cm-tag() }
75 .highlight-attribute{ .cm-s-default.cm-attribute() }
76 .highlight-header{ .cm-s-default.cm-header() }
77 .highlight-quote{ .cm-s-default.cm-quote() }
78 .highlight-link{ .cm-s-default.cm-link() }
79
80
147 81 /* apply the same style to codemirror */
148 .cm-s-ipython {
149 span.cm-variable { .highlight-base()}
150 span.cm-keyword { .highlight-keyword() }
151 span.cm-number { .highlight-number() }
152 span.cm-comment { .highlight-comment() }
153 span.cm-string { .highlight-string()}
154 span.cm-builtin { .highlight-builtin() }
155 span.cm-error { color: #f00; }
156 span.cm-operator {color: #AA22FF; font-weight: bold;}
157 span.cm-meta {color: #AA22FF;}
158
159 span.cm-tab {
160 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
161 background-position: right;
162 background-repeat: no-repeat;
163 }
82 .cm-s-ipython span {
83 &.cm-keyword { .highlight-keyword() }
84 &.cm-atom { .highlight-atom() }
85 &.cm-number { .highlight-number() }
86 &.cm-def { .highlight-def() }
87 &.cm-variable { .highlight-variable() }
88 &.cm-punctuation { .highlight-punctuation() }
89 &.cm-property { .highlight-property() }
90 &.cm-operator { .highlight-operator() }
91 &.cm-variable-2 { .highlight-variable-2() }
92 &.cm-variable-3 { .highlight-variable-3() }
93 &.cm-comment { .highlight-comment() }
94 &.cm-string { .highlight-string() }
95 &.cm-string-2 { .highlight-string-2() }
96 &.cm-meta { .highlight-meta() }
97 &.cm-qualifier { .highlight-qualifier() }
98 &.cm-builtin { .highlight-builtin() }
99 &.cm-bracket { .highlight-bracket() }
100 &.cm-tag { .highlight-tag() }
101 &.cm-attribute { .highlight-attribute() }
102 &.cm-header { .highlight-header() }
103 &.cm-quote { .highlight-quote() }
104 &.cm-link { .highlight-link() }
105 &.cm-error { .highlight-error() }
106
107 &.cm-tab {
108 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
109 background-position: right;
110 background-repeat: no-repeat;
111 }
164 112 }
@@ -1,58 +1,58 b''
1 1 casper.notebook_test(function () {
2 2 this.on('remote.callback', function(data){
3 3 if(data.error_expected){
4 4 that.test.assertEquals(
5 5 data.error,
6 6 data.expected,
7 7 "!highlight: " + data.provided + " errors " + data.expected
8 8 );
9 9 }else{
10 10 that.test.assertEquals(
11 11 data.observed,
12 12 data.expected,
13 13 "highlight: " + data.provided + " as " + data.expected
14 14 );
15 15 }
16 16 });
17 17
18 18 var that = this;
19 19 // syntax highlighting
20 20 [
21 21 {to: "gfm"},
22 22 {to: "python"},
23 23 {to: "ipython"},
24 24 {to: "ipythongfm"},
25 25 {to: "text/x-markdown", from: [".md"]},
26 26 {to: "text/x-python", from: [".py", "Python"]},
27 27 {to: "application/json", from: ["json", "JSON"]},
28 28 {to: "text/x-ruby", from: [".rb", "ruby", "Ruby"]},
29 29 {to: "application/ld+json", from: ["json-ld", "JSON-LD"]},
30 30 {from: [".pyc"], error: true},
31 31 {from: ["../"], error: true},
32 32 {from: ["//"], error: true},
33 33 ].map(function (mode) {
34 [mode.to].concat(mode.from || []).map(function(from){
34 mode.from.concat(mode.to || []).map(function(from){
35 35 casper.evaluate(function(from, expected, error_expected){
36 36 IPython.utils.requireCodeMirrorMode(from, function(observed){
37 37 window.callPhantom({
38 38 provided: from,
39 39 expected: expected,
40 40 observed: observed,
41 41 error_expected: error_expected
42 42 });
43 43 }, function(error){
44 44 window.callPhantom({
45 45 provided: from,
46 46 expected: expected,
47 47 error: error,
48 48 error_expected: error_expected
49 49 });
50 50 });
51 51 }, {
52 52 from: from,
53 53 expected: mode.to,
54 54 error_expected: mode.error
55 55 });
56 56 });
57 57 });
58 58 }); No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now