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