##// END OF EJS Templates
Better error messages with correct stack traces
Jason Grout -
Show More
@@ -1,688 +1,690 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 ], function(IPython, $, CodeMirror){
9 9 "use strict";
10 10
11 11 IPython.load_extensions = function () {
12 12 // load one or more IPython notebook extensions with requirejs
13 13
14 14 var extensions = [];
15 15 var extension_names = arguments;
16 16 for (var i = 0; i < extension_names.length; i++) {
17 17 extensions.push("nbextensions/" + arguments[i]);
18 18 }
19 19
20 20 require(extensions,
21 21 function () {
22 22 for (var i = 0; i < arguments.length; i++) {
23 23 var ext = arguments[i];
24 24 var ext_name = extension_names[i];
25 25 // success callback
26 26 console.log("Loaded extension: " + ext_name);
27 27 if (ext && ext.load_ipython_extension !== undefined) {
28 28 ext.load_ipython_extension();
29 29 }
30 30 }
31 31 },
32 32 function (err) {
33 33 // failure callback
34 34 console.log("Failed to load extension(s):", err.requireModules, err);
35 35 }
36 36 );
37 37 };
38 38
39 39 //============================================================================
40 40 // Cross-browser RegEx Split
41 41 //============================================================================
42 42
43 43 // This code has been MODIFIED from the code licensed below to not replace the
44 44 // default browser split. The license is reproduced here.
45 45
46 46 // see http://blog.stevenlevithan.com/archives/cross-browser-split for more info:
47 47 /*!
48 48 * Cross-Browser Split 1.1.1
49 49 * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
50 50 * Available under the MIT License
51 51 * ECMAScript compliant, uniform cross-browser split method
52 52 */
53 53
54 54 /**
55 55 * Splits a string into an array of strings using a regex or string
56 56 * separator. Matches of the separator are not included in the result array.
57 57 * However, if `separator` is a regex that contains capturing groups,
58 58 * backreferences are spliced into the result each time `separator` is
59 59 * matched. Fixes browser bugs compared to the native
60 60 * `String.prototype.split` and can be used reliably cross-browser.
61 61 * @param {String} str String to split.
62 62 * @param {RegExp|String} separator Regex or string to use for separating
63 63 * the string.
64 64 * @param {Number} [limit] Maximum number of items to include in the result
65 65 * array.
66 66 * @returns {Array} Array of substrings.
67 67 * @example
68 68 *
69 69 * // Basic use
70 70 * regex_split('a b c d', ' ');
71 71 * // -> ['a', 'b', 'c', 'd']
72 72 *
73 73 * // With limit
74 74 * regex_split('a b c d', ' ', 2);
75 75 * // -> ['a', 'b']
76 76 *
77 77 * // Backreferences in result array
78 78 * regex_split('..word1 word2..', /([a-z]+)(\d+)/i);
79 79 * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
80 80 */
81 81 var regex_split = function (str, separator, limit) {
82 82 // If `separator` is not a regex, use `split`
83 83 if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
84 84 return split.call(str, separator, limit);
85 85 }
86 86 var output = [],
87 87 flags = (separator.ignoreCase ? "i" : "") +
88 88 (separator.multiline ? "m" : "") +
89 89 (separator.extended ? "x" : "") + // Proposed for ES6
90 90 (separator.sticky ? "y" : ""), // Firefox 3+
91 91 lastLastIndex = 0,
92 92 // Make `global` and avoid `lastIndex` issues by working with a copy
93 93 separator = new RegExp(separator.source, flags + "g"),
94 94 separator2, match, lastIndex, lastLength;
95 95 str += ""; // Type-convert
96 96
97 97 var compliantExecNpcg = typeof(/()??/.exec("")[1]) === "undefined";
98 98 if (!compliantExecNpcg) {
99 99 // Doesn't need flags gy, but they don't hurt
100 100 separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
101 101 }
102 102 /* Values for `limit`, per the spec:
103 103 * If undefined: 4294967295 // Math.pow(2, 32) - 1
104 104 * If 0, Infinity, or NaN: 0
105 105 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
106 106 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
107 107 * If other: Type-convert, then use the above rules
108 108 */
109 109 limit = typeof(limit) === "undefined" ?
110 110 -1 >>> 0 : // Math.pow(2, 32) - 1
111 111 limit >>> 0; // ToUint32(limit)
112 112 while (match = separator.exec(str)) {
113 113 // `separator.lastIndex` is not reliable cross-browser
114 114 lastIndex = match.index + match[0].length;
115 115 if (lastIndex > lastLastIndex) {
116 116 output.push(str.slice(lastLastIndex, match.index));
117 117 // Fix browsers whose `exec` methods don't consistently return `undefined` for
118 118 // nonparticipating capturing groups
119 119 if (!compliantExecNpcg && match.length > 1) {
120 120 match[0].replace(separator2, function () {
121 121 for (var i = 1; i < arguments.length - 2; i++) {
122 122 if (typeof(arguments[i]) === "undefined") {
123 123 match[i] = undefined;
124 124 }
125 125 }
126 126 });
127 127 }
128 128 if (match.length > 1 && match.index < str.length) {
129 129 Array.prototype.push.apply(output, match.slice(1));
130 130 }
131 131 lastLength = match[0].length;
132 132 lastLastIndex = lastIndex;
133 133 if (output.length >= limit) {
134 134 break;
135 135 }
136 136 }
137 137 if (separator.lastIndex === match.index) {
138 138 separator.lastIndex++; // Avoid an infinite loop
139 139 }
140 140 }
141 141 if (lastLastIndex === str.length) {
142 142 if (lastLength || !separator.test("")) {
143 143 output.push("");
144 144 }
145 145 } else {
146 146 output.push(str.slice(lastLastIndex));
147 147 }
148 148 return output.length > limit ? output.slice(0, limit) : output;
149 149 };
150 150
151 151 //============================================================================
152 152 // End contributed Cross-browser RegEx Split
153 153 //============================================================================
154 154
155 155
156 156 var uuid = function () {
157 157 // http://www.ietf.org/rfc/rfc4122.txt
158 158 var s = [];
159 159 var hexDigits = "0123456789ABCDEF";
160 160 for (var i = 0; i < 32; i++) {
161 161 s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
162 162 }
163 163 s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
164 164 s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
165 165
166 166 var uuid = s.join("");
167 167 return uuid;
168 168 };
169 169
170 170
171 171 //Fix raw text to parse correctly in crazy XML
172 172 function xmlencode(string) {
173 173 return string.replace(/\&/g,'&'+'amp;')
174 174 .replace(/</g,'&'+'lt;')
175 175 .replace(/>/g,'&'+'gt;')
176 176 .replace(/\'/g,'&'+'apos;')
177 177 .replace(/\"/g,'&'+'quot;')
178 178 .replace(/`/g,'&'+'#96;');
179 179 }
180 180
181 181
182 182 //Map from terminal commands to CSS classes
183 183 var ansi_colormap = {
184 184 "01":"ansibold",
185 185
186 186 "30":"ansiblack",
187 187 "31":"ansired",
188 188 "32":"ansigreen",
189 189 "33":"ansiyellow",
190 190 "34":"ansiblue",
191 191 "35":"ansipurple",
192 192 "36":"ansicyan",
193 193 "37":"ansigray",
194 194
195 195 "40":"ansibgblack",
196 196 "41":"ansibgred",
197 197 "42":"ansibggreen",
198 198 "43":"ansibgyellow",
199 199 "44":"ansibgblue",
200 200 "45":"ansibgpurple",
201 201 "46":"ansibgcyan",
202 202 "47":"ansibggray"
203 203 };
204 204
205 205 function _process_numbers(attrs, numbers) {
206 206 // process ansi escapes
207 207 var n = numbers.shift();
208 208 if (ansi_colormap[n]) {
209 209 if ( ! attrs["class"] ) {
210 210 attrs["class"] = ansi_colormap[n];
211 211 } else {
212 212 attrs["class"] += " " + ansi_colormap[n];
213 213 }
214 214 } else if (n == "38" || n == "48") {
215 215 // VT100 256 color or 24 bit RGB
216 216 if (numbers.length < 2) {
217 217 console.log("Not enough fields for VT100 color", numbers);
218 218 return;
219 219 }
220 220
221 221 var index_or_rgb = numbers.shift();
222 222 var r,g,b;
223 223 if (index_or_rgb == "5") {
224 224 // 256 color
225 225 var idx = parseInt(numbers.shift());
226 226 if (idx < 16) {
227 227 // indexed ANSI
228 228 // ignore bright / non-bright distinction
229 229 idx = idx % 8;
230 230 var ansiclass = ansi_colormap[n[0] + (idx % 8).toString()];
231 231 if ( ! attrs["class"] ) {
232 232 attrs["class"] = ansiclass;
233 233 } else {
234 234 attrs["class"] += " " + ansiclass;
235 235 }
236 236 return;
237 237 } else if (idx < 232) {
238 238 // 216 color 6x6x6 RGB
239 239 idx = idx - 16;
240 240 b = idx % 6;
241 241 g = Math.floor(idx / 6) % 6;
242 242 r = Math.floor(idx / 36) % 6;
243 243 // convert to rgb
244 244 r = (r * 51);
245 245 g = (g * 51);
246 246 b = (b * 51);
247 247 } else {
248 248 // grayscale
249 249 idx = idx - 231;
250 250 // it's 1-24 and should *not* include black or white,
251 251 // so a 26 point scale
252 252 r = g = b = Math.floor(idx * 256 / 26);
253 253 }
254 254 } else if (index_or_rgb == "2") {
255 255 // Simple 24 bit RGB
256 256 if (numbers.length > 3) {
257 257 console.log("Not enough fields for RGB", numbers);
258 258 return;
259 259 }
260 260 r = numbers.shift();
261 261 g = numbers.shift();
262 262 b = numbers.shift();
263 263 } else {
264 264 console.log("unrecognized control", numbers);
265 265 return;
266 266 }
267 267 if (r !== undefined) {
268 268 // apply the rgb color
269 269 var line;
270 270 if (n == "38") {
271 271 line = "color: ";
272 272 } else {
273 273 line = "background-color: ";
274 274 }
275 275 line = line + "rgb(" + r + "," + g + "," + b + ");";
276 276 if ( !attrs.style ) {
277 277 attrs.style = line;
278 278 } else {
279 279 attrs.style += " " + line;
280 280 }
281 281 }
282 282 }
283 283 }
284 284
285 285 function ansispan(str) {
286 286 // ansispan function adapted from github.com/mmalecki/ansispan (MIT License)
287 287 // regular ansi escapes (using the table above)
288 288 var is_open = false;
289 289 return str.replace(/\033\[(0?[01]|22|39)?([;\d]+)?m/g, function(match, prefix, pattern) {
290 290 if (!pattern) {
291 291 // [(01|22|39|)m close spans
292 292 if (is_open) {
293 293 is_open = false;
294 294 return "</span>";
295 295 } else {
296 296 return "";
297 297 }
298 298 } else {
299 299 is_open = true;
300 300
301 301 // consume sequence of color escapes
302 302 var numbers = pattern.match(/\d+/g);
303 303 var attrs = {};
304 304 while (numbers.length > 0) {
305 305 _process_numbers(attrs, numbers);
306 306 }
307 307
308 308 var span = "<span ";
309 309 for (var attr in attrs) {
310 310 var value = attrs[attr];
311 311 span = span + " " + attr + '="' + attrs[attr] + '"';
312 312 }
313 313 return span + ">";
314 314 }
315 315 });
316 316 }
317 317
318 318 // Transform ANSI color escape codes into HTML <span> tags with css
319 319 // classes listed in the above ansi_colormap object. The actual color used
320 320 // are set in the css file.
321 321 function fixConsole(txt) {
322 322 txt = xmlencode(txt);
323 323 var re = /\033\[([\dA-Fa-f;]*?)m/;
324 324 var opened = false;
325 325 var cmds = [];
326 326 var opener = "";
327 327 var closer = "";
328 328
329 329 // Strip all ANSI codes that are not color related. Matches
330 330 // all ANSI codes that do not end with "m".
331 331 var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
332 332 txt = txt.replace(ignored_re, "");
333 333
334 334 // color ansi codes
335 335 txt = ansispan(txt);
336 336 return txt;
337 337 }
338 338
339 339 // Remove chunks that should be overridden by the effect of
340 340 // carriage return characters
341 341 function fixCarriageReturn(txt) {
342 342 var tmp = txt;
343 343 do {
344 344 txt = tmp;
345 345 tmp = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
346 346 tmp = tmp.replace(/^.*\r+/gm, ''); // Other \r --> clear line
347 347 } while (tmp.length < txt.length);
348 348 return txt;
349 349 }
350 350
351 351 // Locate any URLs and convert them to a anchor tag
352 352 function autoLinkUrls(txt) {
353 353 return txt.replace(/(^|\s)(https?|ftp)(:[^'">\s]+)/gi,
354 354 "$1<a target=\"_blank\" href=\"$2$3\">$2$3</a>");
355 355 }
356 356
357 357 var points_to_pixels = function (points) {
358 358 // A reasonably good way of converting between points and pixels.
359 359 var test = $('<div style="display: none; width: 10000pt; padding:0; border:0;"></div>');
360 360 $(body).append(test);
361 361 var pixel_per_point = test.width()/10000;
362 362 test.remove();
363 363 return Math.floor(points*pixel_per_point);
364 364 };
365 365
366 366 var always_new = function (constructor) {
367 367 // wrapper around contructor to avoid requiring `var a = new constructor()`
368 368 // useful for passing constructors as callbacks,
369 369 // not for programmer laziness.
370 370 // from http://programmers.stackexchange.com/questions/118798
371 371 return function () {
372 372 var obj = Object.create(constructor.prototype);
373 373 constructor.apply(obj, arguments);
374 374 return obj;
375 375 };
376 376 };
377 377
378 378 var url_path_join = function () {
379 379 // join a sequence of url components with '/'
380 380 var url = '';
381 381 for (var i = 0; i < arguments.length; i++) {
382 382 if (arguments[i] === '') {
383 383 continue;
384 384 }
385 385 if (url.length > 0 && url[url.length-1] != '/') {
386 386 url = url + '/' + arguments[i];
387 387 } else {
388 388 url = url + arguments[i];
389 389 }
390 390 }
391 391 url = url.replace(/\/\/+/, '/');
392 392 return url;
393 393 };
394 394
395 395 var url_path_split = function (path) {
396 396 // Like os.path.split for URLs.
397 397 // Always returns two strings, the directory path and the base filename
398 398
399 399 var idx = path.lastIndexOf('/');
400 400 if (idx === -1) {
401 401 return ['', path];
402 402 } else {
403 403 return [ path.slice(0, idx), path.slice(idx + 1) ];
404 404 }
405 405 };
406 406
407 407 var parse_url = function (url) {
408 408 // an `a` element with an href allows attr-access to the parsed segments of a URL
409 409 // a = parse_url("http://localhost:8888/path/name#hash")
410 410 // a.protocol = "http:"
411 411 // a.host = "localhost:8888"
412 412 // a.hostname = "localhost"
413 413 // a.port = 8888
414 414 // a.pathname = "/path/name"
415 415 // a.hash = "#hash"
416 416 var a = document.createElement("a");
417 417 a.href = url;
418 418 return a;
419 419 };
420 420
421 421 var encode_uri_components = function (uri) {
422 422 // encode just the components of a multi-segment uri,
423 423 // leaving '/' separators
424 424 return uri.split('/').map(encodeURIComponent).join('/');
425 425 };
426 426
427 427 var url_join_encode = function () {
428 428 // join a sequence of url components with '/',
429 429 // encoding each component with encodeURIComponent
430 430 return encode_uri_components(url_path_join.apply(null, arguments));
431 431 };
432 432
433 433
434 434 var splitext = function (filename) {
435 435 // mimic Python os.path.splitext
436 436 // Returns ['base', '.ext']
437 437 var idx = filename.lastIndexOf('.');
438 438 if (idx > 0) {
439 439 return [filename.slice(0, idx), filename.slice(idx)];
440 440 } else {
441 441 return [filename, ''];
442 442 }
443 443 };
444 444
445 445
446 446 var escape_html = function (text) {
447 447 // escape text to HTML
448 448 return $("<div/>").text(text).html();
449 449 };
450 450
451 451
452 452 var get_body_data = function(key) {
453 453 // get a url-encoded item from body.data and decode it
454 454 // we should never have any encoded URLs anywhere else in code
455 455 // until we are building an actual request
456 456 return decodeURIComponent($('body').data(key));
457 457 };
458 458
459 459 var to_absolute_cursor_pos = function (cm, cursor) {
460 460 // get the absolute cursor position from CodeMirror's col, ch
461 461 if (!cursor) {
462 462 cursor = cm.getCursor();
463 463 }
464 464 var cursor_pos = cursor.ch;
465 465 for (var i = 0; i < cursor.line; i++) {
466 466 cursor_pos += cm.getLine(i).length + 1;
467 467 }
468 468 return cursor_pos;
469 469 };
470 470
471 471 var from_absolute_cursor_pos = function (cm, cursor_pos) {
472 472 // turn absolute cursor postion into CodeMirror col, ch cursor
473 473 var i, line;
474 474 var offset = 0;
475 475 for (i = 0, line=cm.getLine(i); line !== undefined; i++, line=cm.getLine(i)) {
476 476 if (offset + line.length < cursor_pos) {
477 477 offset += line.length + 1;
478 478 } else {
479 479 return {
480 480 line : i,
481 481 ch : cursor_pos - offset,
482 482 };
483 483 }
484 484 }
485 485 // reached end, return endpoint
486 486 return {
487 487 ch : line.length - 1,
488 488 line : i - 1,
489 489 };
490 490 };
491 491
492 492 // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
493 493 var browser = (function() {
494 494 if (typeof navigator === 'undefined') {
495 495 // navigator undefined in node
496 496 return 'None';
497 497 }
498 498 var N= navigator.appName, ua= navigator.userAgent, tem;
499 499 var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
500 500 if (M && (tem= ua.match(/version\/([\.\d]+)/i)) !== null) M[2]= tem[1];
501 501 M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?'];
502 502 return M;
503 503 })();
504 504
505 505 // http://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
506 506 var platform = (function () {
507 507 if (typeof navigator === 'undefined') {
508 508 // navigator undefined in node
509 509 return 'None';
510 510 }
511 511 var OSName="None";
512 512 if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows";
513 513 if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS";
514 514 if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
515 515 if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
516 516 return OSName;
517 517 })();
518 518
519 519 var is_or_has = function (a, b) {
520 520 // Is b a child of a or a itself?
521 521 return a.has(b).length !==0 || a.is(b);
522 522 };
523 523
524 524 var is_focused = function (e) {
525 525 // Is element e, or one of its children focused?
526 526 e = $(e);
527 527 var target = $(document.activeElement);
528 528 if (target.length > 0) {
529 529 if (is_or_has(e, target)) {
530 530 return true;
531 531 } else {
532 532 return false;
533 533 }
534 534 } else {
535 535 return false;
536 536 }
537 537 };
538 538
539 539 var mergeopt = function(_class, options, overwrite){
540 540 options = options || {};
541 541 overwrite = overwrite || {};
542 542 return $.extend(true, {}, _class.options_default, options, overwrite);
543 543 };
544 544
545 545 var ajax_error_msg = function (jqXHR) {
546 546 // Return a JSON error message if there is one,
547 547 // otherwise the basic HTTP status text.
548 548 if (jqXHR.responseJSON && jqXHR.responseJSON.traceback) {
549 549 return jqXHR.responseJSON.traceback;
550 550 } else if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
551 551 return jqXHR.responseJSON.message;
552 552 } else {
553 553 return jqXHR.statusText;
554 554 }
555 555 };
556 556 var log_ajax_error = function (jqXHR, status, error) {
557 557 // log ajax failures with informative messages
558 558 var msg = "API request failed (" + jqXHR.status + "): ";
559 559 console.log(jqXHR);
560 560 msg += ajax_error_msg(jqXHR);
561 561 console.log(msg);
562 562 };
563 563
564 564 var requireCodeMirrorMode = function (mode, callback, errback) {
565 565 // load a mode with requirejs
566 566 if (typeof mode != "string") mode = mode.name;
567 567 if (CodeMirror.modes.hasOwnProperty(mode)) {
568 568 callback(CodeMirror.modes.mode);
569 569 return;
570 570 }
571 571 require([
572 572 // might want to use CodeMirror.modeURL here
573 573 ['codemirror/mode', mode, mode].join('/'),
574 574 ], callback, errback
575 575 );
576 576 };
577 577
578 578 /** Error type for wrapped XHR errors. */
579 579 var XHR_ERROR = 'XhrError';
580 580
581 581 /**
582 582 * Wraps an AJAX error as an Error object.
583 583 */
584 584 var wrap_ajax_error = function (jqXHR, status, error) {
585 585 var wrapped_error = new Error(ajax_error_msg(jqXHR));
586 586 wrapped_error.name = XHR_ERROR;
587 587 // provide xhr response
588 588 wrapped_error.xhr = jqXHR;
589 589 wrapped_error.xhr_status = status;
590 590 wrapped_error.xhr_error = error;
591 591 return wrapped_error;
592 592 };
593 593
594 594 var promising_ajax = function(url, settings) {
595 595 // Like $.ajax, but returning an ES6 promise. success and error settings
596 596 // will be ignored.
597 597 return new Promise(function(resolve, reject) {
598 598 settings.success = function(data, status, jqXHR) {
599 599 resolve(data);
600 600 };
601 601 settings.error = function(jqXHR, status, error) {
602 602 log_ajax_error(jqXHR, status, error);
603 603 reject(wrap_ajax_error(jqXHR, status, error));
604 604 };
605 605 $.ajax(url, settings);
606 606 });
607 607 };
608 608
609 609 var load = function(class_name, module_name, registry) {
610 610 // Tries to load a class
611 611 //
612 612 // Tries to load a class from a module using require.js, if a module
613 613 // is specified, otherwise tries to load a class from the global
614 614 // registry, if the global registry is provided.
615 615 return new Promise(function(resolve, reject) {
616 616
617 617 // Try loading the view module using require.js
618 618 if (module_name) {
619 619 require([module_name], function(module) {
620 620 if (module[class_name] === undefined) {
621 reject(new Error('Class not found in module.'));
621 console.error('Class '+class_name+' not found in module '+module_name)
622 reject();
622 623 } else {
623 624 resolve(module[class_name]);
624 625 }
625 626 }, reject);
626 627 } else {
627 628 if (registry && registry[class_name]) {
628 629 resolve(registry[class_name]);
629 630 } else {
630 reject(new Error('Class not found in registry.'));
631 console.error('Class '+class_name+' not found in registry ', registry);
632 reject();
631 633 }
632 634 }
633 635 });
634 636 };
635 637
636 638 var resolve_dict = function(d) {
637 639 var keys = Object.keys(d);
638 640 var values = [];
639 641 keys.forEach(function(key) {
640 642 values.push(key);
641 643 });
642 644 return Promise.all(values).then(function(v) {
643 645 d = {};
644 646 for(var i=0; i<keys.length; i++) {
645 647 d[keys[i]] = v[i];
646 648 }
647 649 return d;
648 650 });
649 651 };
650 652
651 653 var utils = {
652 654 regex_split : regex_split,
653 655 uuid : uuid,
654 656 fixConsole : fixConsole,
655 657 fixCarriageReturn : fixCarriageReturn,
656 658 autoLinkUrls : autoLinkUrls,
657 659 points_to_pixels : points_to_pixels,
658 660 get_body_data : get_body_data,
659 661 parse_url : parse_url,
660 662 url_path_split : url_path_split,
661 663 url_path_join : url_path_join,
662 664 url_join_encode : url_join_encode,
663 665 encode_uri_components : encode_uri_components,
664 666 splitext : splitext,
665 667 escape_html : escape_html,
666 668 always_new : always_new,
667 669 to_absolute_cursor_pos : to_absolute_cursor_pos,
668 670 from_absolute_cursor_pos : from_absolute_cursor_pos,
669 671 browser : browser,
670 672 platform: platform,
671 673 is_or_has : is_or_has,
672 674 is_focused : is_focused,
673 675 mergeopt: mergeopt,
674 676 ajax_error_msg : ajax_error_msg,
675 677 log_ajax_error : log_ajax_error,
676 678 requireCodeMirrorMode : requireCodeMirrorMode,
677 679 XHR_ERROR : XHR_ERROR,
678 680 wrap_ajax_error : wrap_ajax_error,
679 681 promising_ajax : promising_ajax,
680 682 load: load,
681 683 resolve_dict: resolve_dict,
682 684 };
683 685
684 686 // Backwards compatability.
685 687 IPython.utils = utils;
686 688
687 689 return utils;
688 690 });
General Comments 0
You need to be logged in to leave comments. Login now