##// END OF EJS Templates
Merge pull request #7096 from jdfreder/jsdoc...
Jonathan Frederic -
r19178:0a43431f merge
parent child Browse files
Show More
@@ -92,8 +92,10 b' define(['
92 };
92 };
93
93
94 var kernel_modal = function (options) {
94 var kernel_modal = function (options) {
95 // only one kernel dialog should be open at a time -- but
95 /**
96 // other modal dialogs can still be open
96 * only one kernel dialog should be open at a time -- but
97 * other modal dialogs can still be open
98 */
97 $('.kernel-modal').modal('hide');
99 $('.kernel-modal').modal('hide');
98 var dialog = modal(options);
100 var dialog = modal(options);
99 dialog.addClass('kernel-modal');
101 dialog.addClass('kernel-modal');
@@ -140,7 +142,9 b' define(['
140 buttons: {
142 buttons: {
141 OK: { class : "btn-primary",
143 OK: { class : "btn-primary",
142 click: function() {
144 click: function() {
143 // validate json and set it
145 /**
146 * validate json and set it
147 */
144 var new_md;
148 var new_md;
145 try {
149 try {
146 new_md = JSON.parse(editor.getValue());
150 new_md = JSON.parse(editor.getValue());
@@ -15,23 +15,29 b' define(['
15 };
15 };
16
16
17 Page.prototype.show = function () {
17 Page.prototype.show = function () {
18 // The header and site divs start out hidden to prevent FLOUC.
18 /**
19 // Main scripts should call this method after styling everything.
19 * The header and site divs start out hidden to prevent FLOUC.
20 * Main scripts should call this method after styling everything.
21 */
20 this.show_header();
22 this.show_header();
21 this.show_site();
23 this.show_site();
22 };
24 };
23
25
24 Page.prototype.show_header = function () {
26 Page.prototype.show_header = function () {
25 // The header and site divs start out hidden to prevent FLOUC.
27 /**
26 // Main scripts should call this method after styling everything.
28 * The header and site divs start out hidden to prevent FLOUC.
27 // TODO: selector are hardcoded, pass as constructor argument
29 * Main scripts should call this method after styling everything.
30 * TODO: selector are hardcoded, pass as constructor argument
31 */
28 $('div#header').css('display','block');
32 $('div#header').css('display','block');
29 };
33 };
30
34
31 Page.prototype.show_site = function () {
35 Page.prototype.show_site = function () {
32 // The header and site divs start out hidden to prevent FLOUC.
36 /**
33 // Main scripts should call this method after styling everything.
37 * The header and site divs start out hidden to prevent FLOUC.
34 // TODO: selector are hardcoded, pass as constructor argument
38 * Main scripts should call this method after styling everything.
39 * TODO: selector are hardcoded, pass as constructor argument
40 */
35 $('div#site').css('display','block');
41 $('div#site').css('display','block');
36 };
42 };
37
43
@@ -18,8 +18,10 b' define(['
18 }
18 }
19
19
20 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
20 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
21 // add trusting data-attributes to the default sanitizeAttribs from caja
21 /**
22 // this function is mostly copied from the caja source
22 * add trusting data-attributes to the default sanitizeAttribs from caja
23 * this function is mostly copied from the caja source
24 */
23 var ATTRIBS = caja.html4.ATTRIBS;
25 var ATTRIBS = caja.html4.ATTRIBS;
24 for (var i = 0; i < attribs.length; i += 2) {
26 for (var i = 0; i < attribs.length; i += 2) {
25 var attribName = attribs[i];
27 var attribName = attribs[i];
@@ -34,9 +36,11 b' define(['
34 };
36 };
35
37
36 var sanitize_css = function (css, tagPolicy) {
38 var sanitize_css = function (css, tagPolicy) {
37 // sanitize CSS
39 /**
38 // like sanitize_html, but for CSS
40 * sanitize CSS
39 // called by sanitize_stylesheets
41 * like sanitize_html, but for CSS
42 * called by sanitize_stylesheets
43 */
40 return caja.sanitizeStylesheet(
44 return caja.sanitizeStylesheet(
41 window.location.pathname,
45 window.location.pathname,
42 css,
46 css,
@@ -51,8 +55,10 b' define(['
51 };
55 };
52
56
53 var sanitize_stylesheets = function (html, tagPolicy) {
57 var sanitize_stylesheets = function (html, tagPolicy) {
54 // sanitize just the css in style tags in a block of html
58 /**
55 // called by sanitize_html, if allow_css is true
59 * sanitize just the css in style tags in a block of html
60 * called by sanitize_html, if allow_css is true
61 */
56 var h = $("<div/>").append(html);
62 var h = $("<div/>").append(html);
57 var style_tags = h.find("style");
63 var style_tags = h.find("style");
58 if (!style_tags.length) {
64 if (!style_tags.length) {
@@ -66,9 +72,11 b' define(['
66 };
72 };
67
73
68 var sanitize_html = function (html, allow_css) {
74 var sanitize_html = function (html, allow_css) {
69 // sanitize HTML
75 /**
70 // if allow_css is true (default: false), CSS is sanitized as well.
76 * sanitize HTML
71 // otherwise, CSS elements and attributes are simply removed.
77 * if allow_css is true (default: false), CSS is sanitized as well.
78 * otherwise, CSS elements and attributes are simply removed.
79 */
72 var html4 = caja.html4;
80 var html4 = caja.html4;
73
81
74 if (allow_css) {
82 if (allow_css) {
@@ -154,7 +154,9 b' define(['
154
154
155
155
156 var uuid = function () {
156 var uuid = function () {
157 // http://www.ietf.org/rfc/rfc4122.txt
157 /**
158 * http://www.ietf.org/rfc/rfc4122.txt
159 */
158 var s = [];
160 var s = [];
159 var hexDigits = "0123456789ABCDEF";
161 var hexDigits = "0123456789ABCDEF";
160 for (var i = 0; i < 32; i++) {
162 for (var i = 0; i < 32; i++) {
@@ -355,7 +357,9 b' define(['
355 }
357 }
356
358
357 var points_to_pixels = function (points) {
359 var points_to_pixels = function (points) {
358 // A reasonably good way of converting between points and pixels.
360 /**
361 * A reasonably good way of converting between points and pixels.
362 */
359 var test = $('<div style="display: none; width: 10000pt; padding:0; border:0;"></div>');
363 var test = $('<div style="display: none; width: 10000pt; padding:0; border:0;"></div>');
360 $(body).append(test);
364 $(body).append(test);
361 var pixel_per_point = test.width()/10000;
365 var pixel_per_point = test.width()/10000;
@@ -364,10 +368,12 b' define(['
364 };
368 };
365
369
366 var always_new = function (constructor) {
370 var always_new = function (constructor) {
367 // wrapper around contructor to avoid requiring `var a = new constructor()`
371 /**
368 // useful for passing constructors as callbacks,
372 * wrapper around contructor to avoid requiring `var a = new constructor()`
369 // not for programmer laziness.
373 * useful for passing constructors as callbacks,
370 // from http://programmers.stackexchange.com/questions/118798
374 * not for programmer laziness.
375 * from http://programmers.stackexchange.com/questions/118798
376 */
371 return function () {
377 return function () {
372 var obj = Object.create(constructor.prototype);
378 var obj = Object.create(constructor.prototype);
373 constructor.apply(obj, arguments);
379 constructor.apply(obj, arguments);
@@ -376,7 +382,9 b' define(['
376 };
382 };
377
383
378 var url_path_join = function () {
384 var url_path_join = function () {
379 // join a sequence of url components with '/'
385 /**
386 * join a sequence of url components with '/'
387 */
380 var url = '';
388 var url = '';
381 for (var i = 0; i < arguments.length; i++) {
389 for (var i = 0; i < arguments.length; i++) {
382 if (arguments[i] === '') {
390 if (arguments[i] === '') {
@@ -393,8 +401,10 b' define(['
393 };
401 };
394
402
395 var url_path_split = function (path) {
403 var url_path_split = function (path) {
396 // Like os.path.split for URLs.
404 /**
397 // Always returns two strings, the directory path and the base filename
405 * Like os.path.split for URLs.
406 * Always returns two strings, the directory path and the base filename
407 */
398
408
399 var idx = path.lastIndexOf('/');
409 var idx = path.lastIndexOf('/');
400 if (idx === -1) {
410 if (idx === -1) {
@@ -405,35 +415,43 b' define(['
405 };
415 };
406
416
407 var parse_url = function (url) {
417 var parse_url = function (url) {
408 // an `a` element with an href allows attr-access to the parsed segments of a URL
418 /**
409 // a = parse_url("http://localhost:8888/path/name#hash")
419 * an `a` element with an href allows attr-access to the parsed segments of a URL
410 // a.protocol = "http:"
420 * a = parse_url("http://localhost:8888/path/name#hash")
411 // a.host = "localhost:8888"
421 * a.protocol = "http:"
412 // a.hostname = "localhost"
422 * a.host = "localhost:8888"
413 // a.port = 8888
423 * a.hostname = "localhost"
414 // a.pathname = "/path/name"
424 * a.port = 8888
415 // a.hash = "#hash"
425 * a.pathname = "/path/name"
426 * a.hash = "#hash"
427 */
416 var a = document.createElement("a");
428 var a = document.createElement("a");
417 a.href = url;
429 a.href = url;
418 return a;
430 return a;
419 };
431 };
420
432
421 var encode_uri_components = function (uri) {
433 var encode_uri_components = function (uri) {
422 // encode just the components of a multi-segment uri,
434 /**
423 // leaving '/' separators
435 * encode just the components of a multi-segment uri,
436 * leaving '/' separators
437 */
424 return uri.split('/').map(encodeURIComponent).join('/');
438 return uri.split('/').map(encodeURIComponent).join('/');
425 };
439 };
426
440
427 var url_join_encode = function () {
441 var url_join_encode = function () {
428 // join a sequence of url components with '/',
442 /**
429 // encoding each component with encodeURIComponent
443 * join a sequence of url components with '/',
444 * encoding each component with encodeURIComponent
445 */
430 return encode_uri_components(url_path_join.apply(null, arguments));
446 return encode_uri_components(url_path_join.apply(null, arguments));
431 };
447 };
432
448
433
449
434 var splitext = function (filename) {
450 var splitext = function (filename) {
435 // mimic Python os.path.splitext
451 /**
436 // Returns ['base', '.ext']
452 * mimic Python os.path.splitext
453 * Returns ['base', '.ext']
454 */
437 var idx = filename.lastIndexOf('.');
455 var idx = filename.lastIndexOf('.');
438 if (idx > 0) {
456 if (idx > 0) {
439 return [filename.slice(0, idx), filename.slice(idx)];
457 return [filename.slice(0, idx), filename.slice(idx)];
@@ -444,20 +462,26 b' define(['
444
462
445
463
446 var escape_html = function (text) {
464 var escape_html = function (text) {
447 // escape text to HTML
465 /**
466 * escape text to HTML
467 */
448 return $("<div/>").text(text).html();
468 return $("<div/>").text(text).html();
449 };
469 };
450
470
451
471
452 var get_body_data = function(key) {
472 var get_body_data = function(key) {
453 // get a url-encoded item from body.data and decode it
473 /**
454 // we should never have any encoded URLs anywhere else in code
474 * get a url-encoded item from body.data and decode it
455 // until we are building an actual request
475 * we should never have any encoded URLs anywhere else in code
476 * until we are building an actual request
477 */
456 return decodeURIComponent($('body').data(key));
478 return decodeURIComponent($('body').data(key));
457 };
479 };
458
480
459 var to_absolute_cursor_pos = function (cm, cursor) {
481 var to_absolute_cursor_pos = function (cm, cursor) {
460 // get the absolute cursor position from CodeMirror's col, ch
482 /**
483 * get the absolute cursor position from CodeMirror's col, ch
484 */
461 if (!cursor) {
485 if (!cursor) {
462 cursor = cm.getCursor();
486 cursor = cm.getCursor();
463 }
487 }
@@ -469,7 +493,9 b' define(['
469 };
493 };
470
494
471 var from_absolute_cursor_pos = function (cm, cursor_pos) {
495 var from_absolute_cursor_pos = function (cm, cursor_pos) {
472 // turn absolute cursor postion into CodeMirror col, ch cursor
496 /**
497 * turn absolute cursor postion into CodeMirror col, ch cursor
498 */
473 var i, line;
499 var i, line;
474 var offset = 0;
500 var offset = 0;
475 for (i = 0, line=cm.getLine(i); line !== undefined; i++, line=cm.getLine(i)) {
501 for (i = 0, line=cm.getLine(i); line !== undefined; i++, line=cm.getLine(i)) {
@@ -517,12 +543,16 b' define(['
517 })();
543 })();
518
544
519 var is_or_has = function (a, b) {
545 var is_or_has = function (a, b) {
520 // Is b a child of a or a itself?
546 /**
547 * Is b a child of a or a itself?
548 */
521 return a.has(b).length !==0 || a.is(b);
549 return a.has(b).length !==0 || a.is(b);
522 };
550 };
523
551
524 var is_focused = function (e) {
552 var is_focused = function (e) {
525 // Is element e, or one of its children focused?
553 /**
554 * Is element e, or one of its children focused?
555 */
526 e = $(e);
556 e = $(e);
527 var target = $(document.activeElement);
557 var target = $(document.activeElement);
528 if (target.length > 0) {
558 if (target.length > 0) {
@@ -543,8 +573,10 b' define(['
543 };
573 };
544
574
545 var ajax_error_msg = function (jqXHR) {
575 var ajax_error_msg = function (jqXHR) {
546 // Return a JSON error message if there is one,
576 /**
547 // otherwise the basic HTTP status text.
577 * Return a JSON error message if there is one,
578 * otherwise the basic HTTP status text.
579 */
548 if (jqXHR.responseJSON && jqXHR.responseJSON.traceback) {
580 if (jqXHR.responseJSON && jqXHR.responseJSON.traceback) {
549 return jqXHR.responseJSON.traceback;
581 return jqXHR.responseJSON.traceback;
550 } else if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
582 } else if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
@@ -554,7 +586,9 b' define(['
554 }
586 }
555 };
587 };
556 var log_ajax_error = function (jqXHR, status, error) {
588 var log_ajax_error = function (jqXHR, status, error) {
557 // log ajax failures with informative messages
589 /**
590 * log ajax failures with informative messages
591 */
558 var msg = "API request failed (" + jqXHR.status + "): ";
592 var msg = "API request failed (" + jqXHR.status + "): ";
559 console.log(jqXHR);
593 console.log(jqXHR);
560 msg += ajax_error_msg(jqXHR);
594 msg += ajax_error_msg(jqXHR);
@@ -562,7 +596,9 b' define(['
562 };
596 };
563
597
564 var requireCodeMirrorMode = function (mode, callback, errback) {
598 var requireCodeMirrorMode = function (mode, callback, errback) {
565 // load a mode with requirejs
599 /**
600 * load a mode with requirejs
601 */
566 if (typeof mode != "string") mode = mode.name;
602 if (typeof mode != "string") mode = mode.name;
567 if (CodeMirror.modes.hasOwnProperty(mode)) {
603 if (CodeMirror.modes.hasOwnProperty(mode)) {
568 callback(CodeMirror.modes.mode);
604 callback(CodeMirror.modes.mode);
@@ -592,8 +628,10 b' define(['
592 };
628 };
593
629
594 var promising_ajax = function(url, settings) {
630 var promising_ajax = function(url, settings) {
595 // Like $.ajax, but returning an ES6 promise. success and error settings
631 /**
596 // will be ignored.
632 * Like $.ajax, but returning an ES6 promise. success and error settings
633 * will be ignored.
634 */
597 return new Promise(function(resolve, reject) {
635 return new Promise(function(resolve, reject) {
598 settings.success = function(data, status, jqXHR) {
636 settings.success = function(data, status, jqXHR) {
599 resolve(data);
637 resolve(data);
@@ -607,11 +645,13 b' define(['
607 };
645 };
608
646
609 var WrappedError = function(message, error){
647 var WrappedError = function(message, error){
610 // Wrappable Error class
648 /**
611
649 * Wrappable Error class
612 // The Error class doesn't actually act on `this`. Instead it always
650 *
613 // returns a new instance of Error. Here we capture that instance so we
651 * The Error class doesn't actually act on `this`. Instead it always
614 // can apply it's properties to `this`.
652 * returns a new instance of Error. Here we capture that instance so we
653 * can apply it's properties to `this`.
654 */
615 var tmp = Error.apply(this, [message]);
655 var tmp = Error.apply(this, [message]);
616
656
617 // Copy the properties of the error over to this.
657 // Copy the properties of the error over to this.
@@ -635,11 +675,13 b' define(['
635
675
636
676
637 var load_class = function(class_name, module_name, registry) {
677 var load_class = function(class_name, module_name, registry) {
638 // Tries to load a class
678 /**
639 //
679 * Tries to load a class
640 // Tries to load a class from a module using require.js, if a module
680 *
641 // is specified, otherwise tries to load a class from the global
681 * Tries to load a class from a module using require.js, if a module
642 // registry, if the global registry is provided.
682 * is specified, otherwise tries to load a class from the global
683 * registry, if the global registry is provided.
684 */
643 return new Promise(function(resolve, reject) {
685 return new Promise(function(resolve, reject) {
644
686
645 // Try loading the view module using require.js
687 // Try loading the view module using require.js
@@ -662,8 +704,10 b' define(['
662 };
704 };
663
705
664 var resolve_promises_dict = function(d) {
706 var resolve_promises_dict = function(d) {
665 // Resolve a promiseful dictionary.
707 /**
666 // Returns a single Promise.
708 * Resolve a promiseful dictionary.
709 * Returns a single Promise.
710 */
667 var keys = Object.keys(d);
711 var keys = Object.keys(d);
668 var values = [];
712 var values = [];
669 keys.forEach(function(key) {
713 keys.forEach(function(key) {
@@ -679,11 +723,13 b' define(['
679 };
723 };
680
724
681 var WrappedError = function(message, error){
725 var WrappedError = function(message, error){
682 // Wrappable Error class
726 /**
683
727 * Wrappable Error class
684 // The Error class doesn't actually act on `this`. Instead it always
728 *
685 // returns a new instance of Error. Here we capture that instance so we
729 * The Error class doesn't actually act on `this`. Instead it always
686 // can apply it's properties to `this`.
730 * returns a new instance of Error. Here we capture that instance so we
731 * can apply it's properties to `this`.
732 */
687 var tmp = Error.apply(this, [message]);
733 var tmp = Error.apply(this, [message]);
688
734
689 // Copy the properties of the error over to this.
735 // Copy the properties of the error over to this.
@@ -706,11 +752,13 b' define(['
706 WrappedError.prototype = Object.create(Error.prototype, {});
752 WrappedError.prototype = Object.create(Error.prototype, {});
707
753
708 var reject = function(message, log) {
754 var reject = function(message, log) {
709 // Creates a wrappable Promise rejection function.
755 /**
710 //
756 * Creates a wrappable Promise rejection function.
711 // Creates a function that returns a Promise.reject with a new WrappedError
757 *
712 // that has the provided message and wraps the original error that
758 * Creates a function that returns a Promise.reject with a new WrappedError
713 // caused the promise to reject.
759 * that has the provided message and wraps the original error that
760 * caused the promise to reject.
761 */
714 return function(error) {
762 return function(error) {
715 var wrapped_error = new WrappedError(message, error);
763 var wrapped_error = new WrappedError(message, error);
716 if (log) console.error(wrapped_error);
764 if (log) console.error(wrapped_error);
@@ -10,19 +10,21 b' define(['
10 "use strict";
10 "use strict";
11
11
12 var MenuBar = function (selector, options) {
12 var MenuBar = function (selector, options) {
13 // Constructor
13 /**
14 //
14 * Constructor
15 // A MenuBar Class to generate the menubar of IPython notebook
15 *
16 //
16 * A MenuBar Class to generate the menubar of IPython notebook
17 // Parameters:
17 *
18 // selector: string
18 * Parameters:
19 // options: dictionary
19 * selector: string
20 // Dictionary of keyword arguments.
20 * options: dictionary
21 // codemirror: CodeMirror instance
21 * Dictionary of keyword arguments.
22 // contents: ContentManager instance
22 * codemirror: CodeMirror instance
23 // events: $(Events) instance
23 * contents: ContentManager instance
24 // base_url : string
24 * events: $(Events) instance
25 // file_path : string
25 * base_url : string
26 * file_path : string
27 */
26 options = options || {};
28 options = options || {};
27 this.base_url = options.base_url || utils.get_body_data("baseUrl");
29 this.base_url = options.base_url || utils.get_body_data("baseUrl");
28 this.selector = selector;
30 this.selector = selector;
@@ -35,7 +37,9 b' define(['
35 };
37 };
36
38
37 MenuBar.prototype.bind_events = function () {
39 MenuBar.prototype.bind_events = function () {
38 // File
40 /**
41 * File
42 */
39 var that = this;
43 var that = this;
40 this.element.find('#save_file').click(function () {
44 this.element.find('#save_file').click(function () {
41 that.editor.save();
45 that.editor.save();
@@ -112,8 +112,10 b' define(['
112 };
112 };
113
113
114 Cell.prototype.init_classes = function () {
114 Cell.prototype.init_classes = function () {
115 // Call after this.element exists to initialize the css classes
115 /**
116 // related to selected, rendered and mode.
116 * Call after this.element exists to initialize the css classes
117 * related to selected, rendered and mode.
118 */
117 if (this.selected) {
119 if (this.selected) {
118 this.element.addClass('selected');
120 this.element.addClass('selected');
119 } else {
121 } else {
@@ -534,7 +536,9 b' define(['
534 * @param {String|object|undefined} - CodeMirror mode | 'auto'
536 * @param {String|object|undefined} - CodeMirror mode | 'auto'
535 **/
537 **/
536 Cell.prototype._auto_highlight = function (modes) {
538 Cell.prototype._auto_highlight = function (modes) {
537 //Here we handle manually selected modes
539 /**
540 *Here we handle manually selected modes
541 */
538 var that = this;
542 var that = this;
539 var mode;
543 var mode;
540 if( this.user_highlight !== undefined && this.user_highlight != 'auto' )
544 if( this.user_highlight !== undefined && this.user_highlight != 'auto' )
@@ -625,7 +629,9 b' define(['
625 };
629 };
626
630
627 UnrecognizedCell.prototype.toJSON = function () {
631 UnrecognizedCell.prototype.toJSON = function () {
628 // deepcopy the metadata so copied cells don't share the same object
632 /**
633 * deepcopy the metadata so copied cells don't share the same object
634 */
629 return JSON.parse(JSON.stringify(this.data));
635 return JSON.parse(JSON.stringify(this.data));
630 };
636 };
631
637
@@ -9,17 +9,19 b' define(['
9 "use strict";
9 "use strict";
10
10
11 var CellToolbar = function (options) {
11 var CellToolbar = function (options) {
12 // Constructor
12 /**
13 //
13 * Constructor
14 // Parameters:
14 *
15 // options: dictionary
15 * Parameters:
16 // Dictionary of keyword arguments.
16 * options: dictionary
17 // events: $(Events) instance
17 * Dictionary of keyword arguments.
18 // cell: Cell instance
18 * events: $(Events) instance
19 // notebook: Notebook instance
19 * cell: Cell instance
20 //
20 * notebook: Notebook instance
21 // TODO: This leaks, when cell are deleted
21 *
22 // There is still a reference to each celltoolbars.
22 * TODO: This leaks, when cell are deleted
23 * There is still a reference to each celltoolbars.
24 */
23 CellToolbar._instances.push(this);
25 CellToolbar._instances.push(this);
24 this.notebook = options.notebook;
26 this.notebook = options.notebook;
25 this.cell = options.cell;
27 this.cell = options.cell;
@@ -248,9 +250,11 b' define(['
248 * @method rebuild
250 * @method rebuild
249 */
251 */
250 CellToolbar.prototype.rebuild = function(){
252 CellToolbar.prototype.rebuild = function(){
251 // strip evrything from the div
253 /**
252 // which is probably inner_element
254 * strip evrything from the div
253 // or this.element.
255 * which is probably inner_element
256 * or this.element.
257 */
254 this.inner_element.empty();
258 this.inner_element.empty();
255 this.ui_controls_list = [];
259 this.ui_controls_list = [];
256
260
@@ -119,7 +119,9 b' define(['
119 width: 650,
119 width: 650,
120 modal: true,
120 modal: true,
121 close: function() {
121 close: function() {
122 //cleanup on close
122 /**
123 *cleanup on close
124 */
123 $(this).remove();
125 $(this).remove();
124 }
126 }
125 });
127 });
@@ -53,21 +53,23 b' define(['
53 var keycodes = keyboard.keycodes;
53 var keycodes = keyboard.keycodes;
54
54
55 var CodeCell = function (kernel, options) {
55 var CodeCell = function (kernel, options) {
56 // Constructor
56 /**
57 //
57 * Constructor
58 // A Cell conceived to write code.
58 *
59 //
59 * A Cell conceived to write code.
60 // Parameters:
60 *
61 // kernel: Kernel instance
61 * Parameters:
62 // The kernel doesn't have to be set at creation time, in that case
62 * kernel: Kernel instance
63 // it will be null and set_kernel has to be called later.
63 * The kernel doesn't have to be set at creation time, in that case
64 // options: dictionary
64 * it will be null and set_kernel has to be called later.
65 // Dictionary of keyword arguments.
65 * options: dictionary
66 // events: $(Events) instance
66 * Dictionary of keyword arguments.
67 // config: dictionary
67 * events: $(Events) instance
68 // keyboard_manager: KeyboardManager instance
68 * config: dictionary
69 // notebook: Notebook instance
69 * keyboard_manager: KeyboardManager instance
70 // tooltip: Tooltip instance
70 * notebook: Notebook instance
71 * tooltip: Tooltip instance
72 */
71 this.kernel = kernel || null;
73 this.kernel = kernel || null;
72 this.notebook = options.notebook;
74 this.notebook = options.notebook;
73 this.collapsed = false;
75 this.collapsed = false;
@@ -92,8 +92,10 b' define(['
92 };
92 };
93
93
94 Completer.prototype.startCompletion = function () {
94 Completer.prototype.startCompletion = function () {
95 // call for a 'first' completion, that will set the editor and do some
95 /**
96 // special behavior like autopicking if only one completion available.
96 * call for a 'first' completion, that will set the editor and do some
97 * special behavior like autopicking if only one completion available.
98 */
97 if (this.editor.somethingSelected()|| this.editor.getSelections().length > 1) return;
99 if (this.editor.somethingSelected()|| this.editor.getSelections().length > 1) return;
98 this.done = false;
100 this.done = false;
99 // use to get focus back on opera
101 // use to get focus back on opera
@@ -119,9 +121,11 b' define(['
119 * shared start
121 * shared start
120 **/
122 **/
121 Completer.prototype.carry_on_completion = function (first_invocation) {
123 Completer.prototype.carry_on_completion = function (first_invocation) {
122 // Pass true as parameter if you want the completer to autopick when
124 /**
123 // only one completion. This function is automatically reinvoked at
125 * Pass true as parameter if you want the completer to autopick when
124 // each keystroke with first_invocation = false
126 * only one completion. This function is automatically reinvoked at
127 * each keystroke with first_invocation = false
128 */
125 var cur = this.editor.getCursor();
129 var cur = this.editor.getCursor();
126 var line = this.editor.getLine(cur.line);
130 var line = this.editor.getLine(cur.line);
127 var pre_cursor = this.editor.getRange({
131 var pre_cursor = this.editor.getRange({
@@ -164,8 +168,10 b' define(['
164 };
168 };
165
169
166 Completer.prototype.finish_completing = function (msg) {
170 Completer.prototype.finish_completing = function (msg) {
167 // let's build a function that wrap all that stuff into what is needed
171 /**
168 // for the new completer:
172 * let's build a function that wrap all that stuff into what is needed
173 * for the new completer:
174 */
169 var content = msg.content;
175 var content = msg.content;
170 var start = content.cursor_start;
176 var start = content.cursor_start;
171 var end = content.cursor_end;
177 var end = content.cursor_end;
@@ -376,11 +382,13 b' define(['
376 };
382 };
377
383
378 Completer.prototype.keypress = function (event) {
384 Completer.prototype.keypress = function (event) {
379 // FIXME: This is a band-aid.
385 /**
380 // on keypress, trigger insertion of a single character.
386 * FIXME: This is a band-aid.
381 // This simulates the old behavior of completion as you type,
387 * on keypress, trigger insertion of a single character.
382 // before events were disconnected and CodeMirror stopped
388 * This simulates the old behavior of completion as you type,
383 // receiving events while the completer is focused.
389 * before events were disconnected and CodeMirror stopped
390 * receiving events while the completer is focused.
391 */
384
392
385 var that = this;
393 var that = this;
386 var code = event.keyCode;
394 var code = event.keyCode;
@@ -10,14 +10,16 b' define(['
10 "use strict";
10 "use strict";
11
11
12 var MainToolBar = function (selector, options) {
12 var MainToolBar = function (selector, options) {
13 // Constructor
13 /**
14 //
14 * Constructor
15 // Parameters:
15 *
16 // selector: string
16 * Parameters:
17 // options: dictionary
17 * selector: string
18 // Dictionary of keyword arguments.
18 * options: dictionary
19 // events: $(Events) instance
19 * Dictionary of keyword arguments.
20 // notebook: Notebook instance
20 * events: $(Events) instance
21 * notebook: Notebook instance
22 */
21 toolbar.ToolBar.apply(this, arguments);
23 toolbar.ToolBar.apply(this, arguments);
22 this.events = options.events;
24 this.events = options.events;
23 this.notebook = options.notebook;
25 this.notebook = options.notebook;
@@ -108,7 +110,9 b' define(['
108 label : 'Run Cell',
110 label : 'Run Cell',
109 icon : 'fa-play',
111 icon : 'fa-play',
110 callback : function () {
112 callback : function () {
111 // emulate default shift-enter behavior
113 /**
114 * emulate default shift-enter behavior
115 */
112 that.notebook.execute_cell_and_select_below();
116 that.notebook.execute_cell_and_select_below();
113 }
117 }
114 },
118 },
@@ -13,23 +13,25 b' define(['
13 "use strict";
13 "use strict";
14
14
15 var MenuBar = function (selector, options) {
15 var MenuBar = function (selector, options) {
16 // Constructor
16 /**
17 //
17 * Constructor
18 // A MenuBar Class to generate the menubar of IPython notebook
18 *
19 //
19 * A MenuBar Class to generate the menubar of IPython notebook
20 // Parameters:
20 *
21 // selector: string
21 * Parameters:
22 // options: dictionary
22 * selector: string
23 // Dictionary of keyword arguments.
23 * options: dictionary
24 // notebook: Notebook instance
24 * Dictionary of keyword arguments.
25 // contents: ContentManager instance
25 * notebook: Notebook instance
26 // layout_manager: LayoutManager instance
26 * contents: ContentManager instance
27 // events: $(Events) instance
27 * layout_manager: LayoutManager instance
28 // save_widget: SaveWidget instance
28 * events: $(Events) instance
29 // quick_help: QuickHelp instance
29 * save_widget: SaveWidget instance
30 // base_url : string
30 * quick_help: QuickHelp instance
31 // notebook_path : string
31 * base_url : string
32 // notebook_name : string
32 * notebook_path : string
33 * notebook_name : string
34 */
33 options = options || {};
35 options = options || {};
34 this.base_url = options.base_url || utils.get_body_data("baseUrl");
36 this.base_url = options.base_url || utils.get_body_data("baseUrl");
35 this.selector = selector;
37 this.selector = selector;
@@ -87,7 +89,9 b' define(['
87 };
89 };
88
90
89 MenuBar.prototype.bind_events = function () {
91 MenuBar.prototype.bind_events = function () {
90 // File
92 /**
93 * File
94 */
91 var that = this;
95 var that = this;
92 this.element.find('#new_notebook').click(function () {
96 this.element.find('#new_notebook').click(function () {
93 var w = window.open();
97 var w = window.open();
@@ -169,7 +173,9 b' define(['
169 });
173 });
170 this.element.find('#kill_and_exit').click(function () {
174 this.element.find('#kill_and_exit').click(function () {
171 var close_window = function () {
175 var close_window = function () {
172 // allow closing of new tabs in Chromium, impossible in FF
176 /**
177 * allow closing of new tabs in Chromium, impossible in FF
178 */
173 window.open('', '_self', '');
179 window.open('', '_self', '');
174 window.close();
180 window.close();
175 };
181 };
@@ -352,7 +358,9 b' define(['
352 };
358 };
353
359
354 MenuBar.prototype.update_nbconvert_script = function(langinfo) {
360 MenuBar.prototype.update_nbconvert_script = function(langinfo) {
355 // Set the 'Download as foo' menu option for the relevant language.
361 /**
362 * Set the 'Download as foo' menu option for the relevant language.
363 */
356 var el = this.element.find('#download_script');
364 var el = this.element.find('#download_script');
357 var that = this;
365 var that = this;
358
366
@@ -45,22 +45,24 b' define(['
45 "use strict";
45 "use strict";
46
46
47 var Notebook = function (selector, options) {
47 var Notebook = function (selector, options) {
48 // Constructor
48 /**
49 //
49 * Constructor
50 // A notebook contains and manages cells.
50 *
51 //
51 * A notebook contains and manages cells.
52 // Parameters:
52 *
53 // selector: string
53 * Parameters:
54 // options: dictionary
54 * selector: string
55 // Dictionary of keyword arguments.
55 * options: dictionary
56 // events: $(Events) instance
56 * Dictionary of keyword arguments.
57 // keyboard_manager: KeyboardManager instance
57 * events: $(Events) instance
58 // contents: Contents instance
58 * keyboard_manager: KeyboardManager instance
59 // save_widget: SaveWidget instance
59 * contents: Contents instance
60 // config: dictionary
60 * save_widget: SaveWidget instance
61 // base_url : string
61 * config: dictionary
62 // notebook_path : string
62 * base_url : string
63 // notebook_name : string
63 * notebook_path : string
64 * notebook_name : string
65 */
64 this.config = utils.mergeopt(Notebook, options.config);
66 this.config = utils.mergeopt(Notebook, options.config);
65 this.base_url = options.base_url;
67 this.base_url = options.base_url;
66 this.notebook_path = options.notebook_path;
68 this.notebook_path = options.notebook_path;
@@ -314,7 +316,9 b' define(['
314 };
316 };
315
317
316 Notebook.prototype.warn_nbformat_minor = function (event) {
318 Notebook.prototype.warn_nbformat_minor = function (event) {
317 // trigger a warning dialog about missing functionality from newer minor versions
319 /**
320 * trigger a warning dialog about missing functionality from newer minor versions
321 */
318 var v = 'v' + this.nbformat + '.';
322 var v = 'v' + this.nbformat + '.';
319 var orig_vs = v + this.nbformat_minor;
323 var orig_vs = v + this.nbformat_minor;
320 var this_vs = v + this.current_nbformat_minor;
324 var this_vs = v + this.current_nbformat_minor;
@@ -1141,7 +1145,9 b' define(['
1141 };
1145 };
1142
1146
1143 Notebook.prototype._warn_heading = function () {
1147 Notebook.prototype._warn_heading = function () {
1144 // warn about heading cells being removed
1148 /**
1149 * warn about heading cells being removed
1150 */
1145 dialog.modal({
1151 dialog.modal({
1146 notebook: this,
1152 notebook: this,
1147 keyboard_manager: this.keyboard_manager,
1153 keyboard_manager: this.keyboard_manager,
@@ -1677,7 +1683,9 b' define(['
1677 * @method execute_cell
1683 * @method execute_cell
1678 */
1684 */
1679 Notebook.prototype.execute_cell = function () {
1685 Notebook.prototype.execute_cell = function () {
1680 // mode = shift, ctrl, alt
1686 /**
1687 * mode = shift, ctrl, alt
1688 */
1681 var cell = this.get_selected_cell();
1689 var cell = this.get_selected_cell();
1682
1690
1683 cell.execute();
1691 cell.execute();
@@ -1888,7 +1896,9 b' define(['
1888 * @return {Object} A JSON-friendly representation of this notebook.
1896 * @return {Object} A JSON-friendly representation of this notebook.
1889 */
1897 */
1890 Notebook.prototype.toJSON = function () {
1898 Notebook.prototype.toJSON = function () {
1891 // remove the conversion indicator, which only belongs in-memory
1899 /**
1900 * remove the conversion indicator, which only belongs in-memory
1901 */
1892 delete this.metadata.orig_nbformat;
1902 delete this.metadata.orig_nbformat;
1893 delete this.metadata.orig_nbformat_minor;
1903 delete this.metadata.orig_nbformat_minor;
1894
1904
@@ -246,7 +246,9 b' define(['
246 ];
246 ];
247
247
248 OutputArea.prototype.validate_mimebundle = function (json) {
248 OutputArea.prototype.validate_mimebundle = function (json) {
249 // scrub invalid outputs
249 /**
250 * scrub invalid outputs
251 */
250 var data = json.data;
252 var data = json.data;
251 $.map(OutputArea.output_types, function(key){
253 $.map(OutputArea.output_types, function(key){
252 if (key !== 'application/json' &&
254 if (key !== 'application/json' &&
@@ -297,8 +299,10 b' define(['
297 // available.
299 // available.
298 var that = this;
300 var that = this;
299 var handle_appended = function ($el) {
301 var handle_appended = function ($el) {
300 // Only reset the height to automatic if the height is currently
302 /**
301 // fixed (done by wait=True flag on clear_output).
303 * Only reset the height to automatic if the height is currently
304 * fixed (done by wait=True flag on clear_output).
305 */
302 if (needs_height_reset) {
306 if (needs_height_reset) {
303 that.element.height('');
307 that.element.height('');
304 }
308 }
@@ -380,7 +384,9 b' define(['
380
384
381
385
382 OutputArea.prototype._append_javascript_error = function (err, element) {
386 OutputArea.prototype._append_javascript_error = function (err, element) {
383 // display a message when a javascript error occurs in display output
387 /**
388 * display a message when a javascript error occurs in display output
389 */
384 var msg = "Javascript error adding output!";
390 var msg = "Javascript error adding output!";
385 if ( element === undefined ) return;
391 if ( element === undefined ) return;
386 element
392 element
@@ -390,10 +396,12 b' define(['
390 };
396 };
391
397
392 OutputArea.prototype._safe_append = function (toinsert) {
398 OutputArea.prototype._safe_append = function (toinsert) {
393 // safely append an item to the document
399 /**
394 // this is an object created by user code,
400 * safely append an item to the document
395 // and may have errors, which should not be raised
401 * this is an object created by user code,
396 // under any circumstances.
402 * and may have errors, which should not be raised
403 * under any circumstances.
404 */
397 try {
405 try {
398 this.element.append(toinsert);
406 this.element.append(toinsert);
399 } catch(err) {
407 } catch(err) {
@@ -588,7 +596,9 b' define(['
588
596
589
597
590 var append_javascript = function (js, md, element) {
598 var append_javascript = function (js, md, element) {
591 // We just eval the JS code, element appears in the local scope.
599 /**
600 * We just eval the JS code, element appears in the local scope.
601 */
592 var type = 'application/javascript';
602 var type = 'application/javascript';
593 var toinsert = this.create_output_subarea(md, "output_javascript", type);
603 var toinsert = this.create_output_subarea(md, "output_javascript", type);
594 this.keyboard_manager.register_events(toinsert);
604 this.keyboard_manager.register_events(toinsert);
@@ -652,14 +662,16 b' define(['
652 };
662 };
653
663
654 OutputArea.prototype._dblclick_to_reset_size = function (img, immediately, resize_parent) {
664 OutputArea.prototype._dblclick_to_reset_size = function (img, immediately, resize_parent) {
655 // Add a resize handler to an element
665 /**
656 //
666 * Add a resize handler to an element
657 // img: jQuery element
667 *
658 // immediately: bool=False
668 * img: jQuery element
659 // Wait for the element to load before creating the handle.
669 * immediately: bool=False
660 // resize_parent: bool=True
670 * Wait for the element to load before creating the handle.
661 // Should the parent of the element be resized when the element is
671 * resize_parent: bool=True
662 // reset (by double click).
672 * Should the parent of the element be resized when the element is
673 * reset (by double click).
674 */
663 var callback = function (){
675 var callback = function (){
664 var h0 = img.height();
676 var h0 = img.height();
665 var w0 = img.width();
677 var w0 = img.width();
@@ -690,7 +702,9 b' define(['
690 };
702 };
691
703
692 var set_width_height = function (img, md, mime) {
704 var set_width_height = function (img, md, mime) {
693 // set width and height of an img element from metadata
705 /**
706 * set width and height of an img element from metadata
707 */
694 var height = _get_metadata_key(md, 'height', mime);
708 var height = _get_metadata_key(md, 'height', mime);
695 if (height !== undefined) img.attr('height', height);
709 if (height !== undefined) img.attr('height', height);
696 var width = _get_metadata_key(md, 'width', mime);
710 var width = _get_metadata_key(md, 'width', mime);
@@ -745,8 +759,10 b' define(['
745 };
759 };
746
760
747 var append_latex = function (latex, md, element) {
761 var append_latex = function (latex, md, element) {
748 // This method cannot do the typesetting because the latex first has to
762 /**
749 // be on the page.
763 * This method cannot do the typesetting because the latex first has to
764 * be on the page.
765 */
750 var type = 'text/latex';
766 var type = 'text/latex';
751 var toinsert = this.create_output_subarea(md, "output_latex", type);
767 var toinsert = this.create_output_subarea(md, "output_latex", type);
752 toinsert.append(latex);
768 toinsert.append(latex);
@@ -825,11 +841,13 b' define(['
825
841
826
842
827 OutputArea.prototype.handle_clear_output = function (msg) {
843 OutputArea.prototype.handle_clear_output = function (msg) {
828 // msg spec v4 had stdout, stderr, display keys
844 /**
829 // v4.1 replaced these with just wait
845 * msg spec v4 had stdout, stderr, display keys
830 // The default behavior is the same (stdout=stderr=display=True, wait=False),
846 * v4.1 replaced these with just wait
831 // so v4 messages will still be properly handled,
847 * The default behavior is the same (stdout=stderr=display=True, wait=False),
832 // except for the rarely used clearing less than all output.
848 * so v4 messages will still be properly handled,
849 * except for the rarely used clearing less than all output.
850 */
833 this.clear_output(msg.content.wait || false);
851 this.clear_output(msg.content.wait || false);
834 };
852 };
835
853
@@ -9,15 +9,17 b' define(['
9 "use strict";
9 "use strict";
10
10
11 var Pager = function (pager_selector, pager_splitter_selector, options) {
11 var Pager = function (pager_selector, pager_splitter_selector, options) {
12 // Constructor
12 /**
13 //
13 * Constructor
14 // Parameters:
14 *
15 // pager_selector: string
15 * Parameters:
16 // pager_splitter_selector: string
16 * pager_selector: string
17 // options: dictionary
17 * pager_splitter_selector: string
18 // Dictionary of keyword arguments.
18 * options: dictionary
19 // events: $(Events) instance
19 * Dictionary of keyword arguments.
20 // layout_manager: LayoutManager instance
20 * events: $(Events) instance
21 * layout_manager: LayoutManager instance
22 */
21 this.events = options.events;
23 this.events = options.events;
22 this.pager_element = $(pager_selector);
24 this.pager_element = $(pager_selector);
23 this.pager_button_area = $('#pager_button_area');
25 this.pager_button_area = $('#pager_button_area');
@@ -30,7 +32,9 b' define(['
30 axis:'y',
32 axis:'y',
31 helper: null ,
33 helper: null ,
32 drag: function(event, ui) {
34 drag: function(event, ui) {
33 // recalculate the amount of space the pager should take
35 /**
36 * recalculate the amount of space the pager should take
37 */
34 var pheight = ($(document.body).height()-event.clientY-4);
38 var pheight = ($(document.body).height()-event.clientY-4);
35 var downprct = pheight/options.layout_manager.app_height();
39 var downprct = pheight/options.layout_manager.app_height();
36 downprct = Math.min(0.9, downprct);
40 downprct = Math.min(0.9, downprct);
@@ -173,8 +177,10 b' define(['
173 };
177 };
174
178
175 Pager.prototype.append_text = function (text) {
179 Pager.prototype.append_text = function (text) {
176 // The only user content injected with this HTML call is escaped by
180 /**
177 // the fixConsole() method.
181 * The only user content injected with this HTML call is escaped by
182 * the fixConsole() method.
183 */
178 this.pager_element.find(".container").append($('<pre/>').html(utils.fixCarriageReturn(utils.fixConsole(text))));
184 this.pager_element.find(".container").append($('<pre/>').html(utils.fixCarriageReturn(utils.fixConsole(text))));
179 };
185 };
180
186
@@ -11,14 +11,16 b' define(['
11 var platform = utils.platform;
11 var platform = utils.platform;
12
12
13 var QuickHelp = function (options) {
13 var QuickHelp = function (options) {
14 // Constructor
14 /**
15 //
15 * Constructor
16 // Parameters:
16 *
17 // options: dictionary
17 * Parameters:
18 // Dictionary of keyword arguments.
18 * options: dictionary
19 // events: $(Events) instance
19 * Dictionary of keyword arguments.
20 // keyboard_manager: KeyboardManager instance
20 * events: $(Events) instance
21 // notebook: Notebook instance
21 * keyboard_manager: KeyboardManager instance
22 * notebook: Notebook instance
23 */
22 this.keyboard_manager = options.keyboard_manager;
24 this.keyboard_manager = options.keyboard_manager;
23 this.notebook = options.notebook;
25 this.notebook = options.notebook;
24 this.keyboard_manager.quick_help = this;
26 this.keyboard_manager.quick_help = this;
@@ -66,7 +68,9 b' define(['
66
68
67
69
68 QuickHelp.prototype.show_keyboard_shortcuts = function () {
70 QuickHelp.prototype.show_keyboard_shortcuts = function () {
69 // toggles display of keyboard shortcut dialog
71 /**
72 * toggles display of keyboard shortcut dialog
73 */
70 var that = this;
74 var that = this;
71 if ( this.force_rebuild ) {
75 if ( this.force_rebuild ) {
72 this.shortcut_dialog.remove();
76 this.shortcut_dialog.remove();
@@ -12,7 +12,9 b' define(['
12 "use strict";
12 "use strict";
13
13
14 var SaveWidget = function (selector, options) {
14 var SaveWidget = function (selector, options) {
15 // TODO: Remove circular ref.
15 /**
16 * TODO: Remove circular ref.
17 */
16 this.notebook = undefined;
18 this.notebook = undefined;
17 this.selector = selector;
19 this.selector = selector;
18 this.events = options.events;
20 this.events = options.events;
@@ -111,7 +113,9 b' define(['
111 "Cancel": {}
113 "Cancel": {}
112 },
114 },
113 open : function () {
115 open : function () {
114 // Upon ENTER, click the OK button.
116 /**
117 * Upon ENTER, click the OK button.
118 */
115 d.find('input[type="text"]').keydown(function (event) {
119 d.find('input[type="text"]').keydown(function (event) {
116 if (event.which === keyboard.keycodes.enter) {
120 if (event.which === keyboard.keycodes.enter) {
117 d.find('.btn-primary').first().click();
121 d.find('.btn-primary').first().click();
@@ -206,8 +210,10 b' define(['
206
210
207 var that = this;
211 var that = this;
208 var recall = function(t){
212 var recall = function(t){
209 // recall slightly later (1s) as long timeout in js might be imprecise,
213 /**
210 // and you want to be call **after** the change of formatting should happend.
214 * recall slightly later (1s) as long timeout in js might be imprecise,
215 * and you want to be call **after** the change of formatting should happend.
216 */
211 return setTimeout(
217 return setTimeout(
212 $.proxy(that._regularly_update_checkpoint_date, that),
218 $.proxy(that._regularly_update_checkpoint_date, that),
213 t + 1000
219 t + 1000
@@ -4,47 +4,57 b" define(['jquery'], function($){"
4 "use strict";
4 "use strict";
5
5
6 var ScrollManager = function(notebook, options) {
6 var ScrollManager = function(notebook, options) {
7 // Public constructor.
7 /**
8 * Public constructor.
9 */
8 this.notebook = notebook;
10 this.notebook = notebook;
9 options = options || {};
11 options = options || {};
10 this.animation_speed = options.animation_speed || 250; //ms
12 this.animation_speed = options.animation_speed || 250; //ms
11 };
13 };
12
14
13 ScrollManager.prototype.scroll = function (delta) {
15 ScrollManager.prototype.scroll = function (delta) {
14 // Scroll the document.
16 /**
15 //
17 * Scroll the document.
16 // Parameters
18 *
17 // ----------
19 * Parameters
18 // delta: integer
20 * ----------
19 // direction to scroll the document. Positive is downwards.
21 * delta: integer
20 // Unit is one page length.
22 * direction to scroll the document. Positive is downwards.
23 * Unit is one page length.
24 */
21 this.scroll_some(delta);
25 this.scroll_some(delta);
22 return false;
26 return false;
23 };
27 };
24
28
25 ScrollManager.prototype.scroll_to = function(selector) {
29 ScrollManager.prototype.scroll_to = function(selector) {
26 // Scroll to an element in the notebook.
30 /**
31 * Scroll to an element in the notebook.
32 */
27 $('#notebook').animate({'scrollTop': $(selector).offset().top + $('#notebook').scrollTop() - $('#notebook').offset().top}, this.animation_speed);
33 $('#notebook').animate({'scrollTop': $(selector).offset().top + $('#notebook').scrollTop() - $('#notebook').offset().top}, this.animation_speed);
28 };
34 };
29
35
30 ScrollManager.prototype.scroll_some = function(pages) {
36 ScrollManager.prototype.scroll_some = function(pages) {
31 // Scroll up or down a given number of pages.
37 /**
32 //
38 * Scroll up or down a given number of pages.
33 // Parameters
39 *
34 // ----------
40 * Parameters
35 // pages: integer
41 * ----------
36 // number of pages to scroll the document, may be positive or negative.
42 * pages: integer
43 * number of pages to scroll the document, may be positive or negative.
44 */
37 $('#notebook').animate({'scrollTop': $('#notebook').scrollTop() + pages * $('#notebook').height()}, this.animation_speed);
45 $('#notebook').animate({'scrollTop': $('#notebook').scrollTop() + pages * $('#notebook').height()}, this.animation_speed);
38 };
46 };
39
47
40 ScrollManager.prototype.get_first_visible_cell = function() {
48 ScrollManager.prototype.get_first_visible_cell = function() {
41 // Gets the index of the first visible cell in the document.
49 /**
42
50 * Gets the index of the first visible cell in the document.
43 // First, attempt to be smart by guessing the index of the cell we are
51 *
44 // scrolled to. Then, walk from there up or down until the right cell
52 * First, attempt to be smart by guessing the index of the cell we are
45 // is found. To guess the index, get the top of the last cell, and
53 * scrolled to. Then, walk from there up or down until the right cell
46 // divide that by the number of cells to get an average cell height.
54 * is found. To guess the index, get the top of the last cell, and
47 // Then divide the scroll height by the average cell height.
55 * divide that by the number of cells to get an average cell height.
56 * Then divide the scroll height by the average cell height.
57 */
48 var cell_count = this.notebook.ncells();
58 var cell_count = this.notebook.ncells();
49 var first_cell_top = this.notebook.get_cell(0).element.offset().top;
59 var first_cell_top = this.notebook.get_cell(0).element.offset().top;
50 var last_cell_top = this.notebook.get_cell(cell_count-1).element.offset().top;
60 var last_cell_top = this.notebook.get_cell(cell_count-1).element.offset().top;
@@ -65,34 +75,40 b" define(['jquery'], function($){"
65
75
66
76
67 var TargetScrollManager = function(notebook, options) {
77 var TargetScrollManager = function(notebook, options) {
68 // Public constructor.
78 /**
79 * Public constructor.
80 */
69 ScrollManager.apply(this, [notebook, options]);
81 ScrollManager.apply(this, [notebook, options]);
70 };
82 };
71 TargetScrollManager.prototype = Object.create(ScrollManager.prototype);
83 TargetScrollManager.prototype = Object.create(ScrollManager.prototype);
72
84
73 TargetScrollManager.prototype.is_target = function (index) {
85 TargetScrollManager.prototype.is_target = function (index) {
74 // Check if a cell should be a scroll stop.
86 /**
75 //
87 * Check if a cell should be a scroll stop.
76 // Returns `true` if the cell is a cell that the scroll manager
88 *
77 // should scroll to. Otherwise, false is returned.
89 * Returns `true` if the cell is a cell that the scroll manager
78 //
90 * should scroll to. Otherwise, false is returned.
79 // Parameters
91 *
80 // ----------
92 * Parameters
81 // index: integer
93 * ----------
82 // index of the cell to test.
94 * index: integer
95 * index of the cell to test.
96 */
83 return false;
97 return false;
84 };
98 };
85
99
86 TargetScrollManager.prototype.scroll = function (delta) {
100 TargetScrollManager.prototype.scroll = function (delta) {
87 // Scroll the document.
101 /**
88 //
102 * Scroll the document.
89 // Parameters
103 *
90 // ----------
104 * Parameters
91 // delta: integer
105 * ----------
92 // direction to scroll the document. Positive is downwards.
106 * delta: integer
93 // Units are targets.
107 * direction to scroll the document. Positive is downwards.
94
108 * Units are targets.
95 // Try to scroll to the next slide.
109 *
110 * Try to scroll to the next slide.
111 */
96 var cell_count = this.notebook.ncells();
112 var cell_count = this.notebook.ncells();
97 var selected_index = this.get_first_visible_cell() + delta;
113 var selected_index = this.get_first_visible_cell() + delta;
98 while (0 <= selected_index && selected_index < cell_count && !this.is_target(selected_index)) {
114 while (0 <= selected_index && selected_index < cell_count && !this.is_target(selected_index)) {
@@ -111,7 +127,9 b" define(['jquery'], function($){"
111
127
112
128
113 var SlideScrollManager = function(notebook, options) {
129 var SlideScrollManager = function(notebook, options) {
114 // Public constructor.
130 /**
131 * Public constructor.
132 */
115 TargetScrollManager.apply(this, [notebook, options]);
133 TargetScrollManager.apply(this, [notebook, options]);
116 };
134 };
117 SlideScrollManager.prototype = Object.create(TargetScrollManager.prototype);
135 SlideScrollManager.prototype = Object.create(TargetScrollManager.prototype);
@@ -126,7 +144,9 b" define(['jquery'], function($){"
126
144
127
145
128 var HeadingScrollManager = function(notebook, options) {
146 var HeadingScrollManager = function(notebook, options) {
129 // Public constructor.
147 /**
148 * Public constructor.
149 */
130 ScrollManager.apply(this, [notebook, options]);
150 ScrollManager.apply(this, [notebook, options]);
131 options = options || {};
151 options = options || {};
132 this._level = options.heading_level || 1;
152 this._level = options.heading_level || 1;
@@ -134,16 +154,18 b" define(['jquery'], function($){"
134 HeadingScrollManager.prototype = Object.create(ScrollManager.prototype)
154 HeadingScrollManager.prototype = Object.create(ScrollManager.prototype)
135
155
136 HeadingScrollManager.prototype.scroll = function (delta) {
156 HeadingScrollManager.prototype.scroll = function (delta) {
137 // Scroll the document.
157 /**
138 //
158 * Scroll the document.
139 // Parameters
159 *
140 // ----------
160 * Parameters
141 // delta: integer
161 * ----------
142 // direction to scroll the document. Positive is downwards.
162 * delta: integer
143 // Units are headers.
163 * direction to scroll the document. Positive is downwards.
144
164 * Units are headers.
145 // Get all of the header elements that match the heading level or are of
165 *
146 // greater magnitude (a smaller header number).
166 * Get all of the header elements that match the heading level or are of
167 * greater magnitude (a smaller header number).
168 */
147 var headers = $();
169 var headers = $();
148 var i;
170 var i;
149 for (i = 1; i <= this._level; i++) {
171 for (i = 1; i <= this._level; i++) {
@@ -18,18 +18,20 b' define(['
18 var Cell = cell.Cell;
18 var Cell = cell.Cell;
19
19
20 var TextCell = function (options) {
20 var TextCell = function (options) {
21 // Constructor
21 /**
22 //
22 * Constructor
23 // Construct a new TextCell, codemirror mode is by default 'htmlmixed',
23 *
24 // and cell type is 'text' cell start as not redered.
24 * Construct a new TextCell, codemirror mode is by default 'htmlmixed',
25 //
25 * and cell type is 'text' cell start as not redered.
26 // Parameters:
26 *
27 // options: dictionary
27 * Parameters:
28 // Dictionary of keyword arguments.
28 * options: dictionary
29 // events: $(Events) instance
29 * Dictionary of keyword arguments.
30 // config: dictionary
30 * events: $(Events) instance
31 // keyboard_manager: KeyboardManager instance
31 * config: dictionary
32 // notebook: Notebook instance
32 * keyboard_manager: KeyboardManager instance
33 * notebook: Notebook instance
34 */
33 options = options || {};
35 options = options || {};
34
36
35 // in all TextCell/Cell subclasses
37 // in all TextCell/Cell subclasses
@@ -195,15 +197,17 b' define(['
195
197
196
198
197 var MarkdownCell = function (options) {
199 var MarkdownCell = function (options) {
198 // Constructor
200 /**
199 //
201 * Constructor
200 // Parameters:
202 *
201 // options: dictionary
203 * Parameters:
202 // Dictionary of keyword arguments.
204 * options: dictionary
203 // events: $(Events) instance
205 * Dictionary of keyword arguments.
204 // config: dictionary
206 * events: $(Events) instance
205 // keyboard_manager: KeyboardManager instance
207 * config: dictionary
206 // notebook: Notebook instance
208 * keyboard_manager: KeyboardManager instance
209 * notebook: Notebook instance
210 */
207 options = options || {};
211 options = options || {};
208 var config = utils.mergeopt(MarkdownCell, options.config);
212 var config = utils.mergeopt(MarkdownCell, options.config);
209 TextCell.apply(this, [$.extend({}, options, {config: config})]);
213 TextCell.apply(this, [$.extend({}, options, {config: config})]);
@@ -221,7 +225,9 b' define(['
221 MarkdownCell.prototype = Object.create(TextCell.prototype);
225 MarkdownCell.prototype = Object.create(TextCell.prototype);
222
226
223 MarkdownCell.prototype.set_heading_level = function (level) {
227 MarkdownCell.prototype.set_heading_level = function (level) {
224 // make a markdown cell a heading
228 /**
229 * make a markdown cell a heading
230 */
225 level = level || 1;
231 level = level || 1;
226 var source = this.get_text();
232 var source = this.get_text();
227 source = source.replace(/^(#*)\s?/,
233 source = source.replace(/^(#*)\s?/,
@@ -274,15 +280,17 b' define(['
274
280
275
281
276 var RawCell = function (options) {
282 var RawCell = function (options) {
277 // Constructor
283 /**
278 //
284 * Constructor
279 // Parameters:
285 *
280 // options: dictionary
286 * Parameters:
281 // Dictionary of keyword arguments.
287 * options: dictionary
282 // events: $(Events) instance
288 * Dictionary of keyword arguments.
283 // config: dictionary
289 * events: $(Events) instance
284 // keyboard_manager: KeyboardManager instance
290 * config: dictionary
285 // notebook: Notebook instance
291 * keyboard_manager: KeyboardManager instance
292 * notebook: Notebook instance
293 */
286 options = options || {};
294 options = options || {};
287 var config = utils.mergeopt(RawCell, options.config);
295 var config = utils.mergeopt(RawCell, options.config);
288 TextCell.apply(this, [$.extend({}, options, {config: config})]);
296 TextCell.apply(this, [$.extend({}, options, {config: config})]);
@@ -116,7 +116,9 b' define(['
116 };
116 };
117
117
118 Tooltip.prototype.showInPager = function (cell) {
118 Tooltip.prototype.showInPager = function (cell) {
119 // reexecute last call in pager by appending ? to show back in pager
119 /**
120 * reexecute last call in pager by appending ? to show back in pager
121 */
120 this.events.trigger('open_with_text.Pager', this._reply.content);
122 this.events.trigger('open_with_text.Pager', this._reply.content);
121 this.remove_and_cancel_tooltip();
123 this.remove_and_cancel_tooltip();
122 };
124 };
@@ -144,9 +146,11 b' define(['
144 // return true on successfully removing a visible tooltip; otherwise return
146 // return true on successfully removing a visible tooltip; otherwise return
145 // false.
147 // false.
146 Tooltip.prototype.remove_and_cancel_tooltip = function (force) {
148 Tooltip.prototype.remove_and_cancel_tooltip = function (force) {
147 // note that we don't handle closing directly inside the calltip
149 /**
148 // as in the completer, because it is not focusable, so won't
150 * note that we don't handle closing directly inside the calltip
149 // get the event.
151 * as in the completer, because it is not focusable, so won't
152 * get the event.
153 */
150 this.cancel_pending();
154 this.cancel_pending();
151 if (!this._hidden) {
155 if (!this._hidden) {
152 if (force || !this._sticky) {
156 if (force || !this._sticky) {
@@ -186,9 +190,11 b' define(['
186
190
187 // make an immediate completion request
191 // make an immediate completion request
188 Tooltip.prototype.request = function (cell, hide_if_no_docstring) {
192 Tooltip.prototype.request = function (cell, hide_if_no_docstring) {
189 // request(codecell)
193 /**
190 // Deal with extracting the text from the cell and counting
194 * request(codecell)
191 // call in a row
195 * Deal with extracting the text from the cell and counting
196 * call in a row
197 */
192 this.cancel_pending();
198 this.cancel_pending();
193 var editor = cell.code_mirror;
199 var editor = cell.code_mirror;
194 var cursor = editor.getCursor();
200 var cursor = editor.getCursor();
@@ -250,8 +256,10 b' define(['
250
256
251 // should be called with the kernel reply to actually show the tooltip
257 // should be called with the kernel reply to actually show the tooltip
252 Tooltip.prototype._show = function (reply) {
258 Tooltip.prototype._show = function (reply) {
253 // move the bubble if it is not hidden
259 /**
254 // otherwise fade it
260 * move the bubble if it is not hidden
261 * otherwise fade it
262 */
255 this._reply = reply;
263 this._reply = reply;
256 var content = reply.content;
264 var content = reply.content;
257 if (!content.found) {
265 if (!content.found) {
@@ -7,16 +7,18 b' define(['
7 'base/js/utils',
7 'base/js/utils',
8 ], function(IPython, $, utils) {
8 ], function(IPython, $, utils) {
9 var Contents = function(options) {
9 var Contents = function(options) {
10 // Constructor
10 /**
11 //
11 * Constructor
12 // A contents handles passing file operations
12 *
13 // to the back-end. This includes checkpointing
13 * A contents handles passing file operations
14 // with the normal file operations.
14 * to the back-end. This includes checkpointing
15 //
15 * with the normal file operations.
16 // Parameters:
16 *
17 // options: dictionary
17 * Parameters:
18 // Dictionary of keyword arguments.
18 * options: dictionary
19 // base_url: string
19 * Dictionary of keyword arguments.
20 * base_url: string
21 */
20 this.base_url = options.base_url;
22 this.base_url = options.base_url;
21 };
23 };
22
24
@@ -78,7 +80,9 b' define(['
78 * format: 'text' or 'base64'; only relevant for type: 'file'
80 * format: 'text' or 'base64'; only relevant for type: 'file'
79 */
81 */
80 Contents.prototype.get = function (path, options) {
82 Contents.prototype.get = function (path, options) {
81 // We do the call with settings so we can set cache to false.
83 /**
84 * We do the call with settings so we can set cache to false.
85 */
82 var settings = {
86 var settings = {
83 processData : false,
87 processData : false,
84 cache : false,
88 cache : false,
@@ -151,7 +155,9 b' define(['
151 };
155 };
152
156
153 Contents.prototype.save = function(path, model) {
157 Contents.prototype.save = function(path, model) {
154 // We do the call with settings so we can set cache to false.
158 /**
159 * We do the call with settings so we can set cache to false.
160 */
155 var settings = {
161 var settings = {
156 processData : false,
162 processData : false,
157 type : "PUT",
163 type : "PUT",
@@ -163,8 +169,10 b' define(['
163 };
169 };
164
170
165 Contents.prototype.copy = function(from_file, to_dir) {
171 Contents.prototype.copy = function(from_file, to_dir) {
166 // Copy a file into a given directory via POST
172 /**
167 // The server will select the name of the copied file
173 * Copy a file into a given directory via POST
174 * The server will select the name of the copied file
175 */
168 var url = this.api_url(to_dir);
176 var url = this.api_url(to_dir);
169
177
170 var settings = {
178 var settings = {
@@ -21,7 +21,9 b' define(['
21 };
21 };
22
22
23 CommManager.prototype.init_kernel = function (kernel) {
23 CommManager.prototype.init_kernel = function (kernel) {
24 // connect the kernel, and register message handlers
24 /**
25 * connect the kernel, and register message handlers
26 */
25 this.kernel = kernel;
27 this.kernel = kernel;
26 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
28 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
27 for (var i = 0; i < msg_types.length; i++) {
29 for (var i = 0; i < msg_types.length; i++) {
@@ -31,8 +33,10 b' define(['
31 };
33 };
32
34
33 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
35 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
34 // Create a new Comm, register it, and open its Kernel-side counterpart
36 /**
35 // Mimics the auto-registration in `Comm.__init__` in the IPython Comm
37 * Create a new Comm, register it, and open its Kernel-side counterpart
38 * Mimics the auto-registration in `Comm.__init__` in the IPython Comm
39 */
36 var comm = new Comm(target_name);
40 var comm = new Comm(target_name);
37 this.register_comm(comm);
41 this.register_comm(comm);
38 comm.open(data, callbacks, metadata);
42 comm.open(data, callbacks, metadata);
@@ -40,24 +44,32 b' define(['
40 };
44 };
41
45
42 CommManager.prototype.register_target = function (target_name, f) {
46 CommManager.prototype.register_target = function (target_name, f) {
43 // Register a target function for a given target name
47 /**
48 * Register a target function for a given target name
49 */
44 this.targets[target_name] = f;
50 this.targets[target_name] = f;
45 };
51 };
46
52
47 CommManager.prototype.unregister_target = function (target_name, f) {
53 CommManager.prototype.unregister_target = function (target_name, f) {
48 // Unregister a target function for a given target name
54 /**
55 * Unregister a target function for a given target name
56 */
49 delete this.targets[target_name];
57 delete this.targets[target_name];
50 };
58 };
51
59
52 CommManager.prototype.register_comm = function (comm) {
60 CommManager.prototype.register_comm = function (comm) {
53 // Register a comm in the mapping
61 /**
62 * Register a comm in the mapping
63 */
54 this.comms[comm.comm_id] = Promise.resolve(comm);
64 this.comms[comm.comm_id] = Promise.resolve(comm);
55 comm.kernel = this.kernel;
65 comm.kernel = this.kernel;
56 return comm.comm_id;
66 return comm.comm_id;
57 };
67 };
58
68
59 CommManager.prototype.unregister_comm = function (comm) {
69 CommManager.prototype.unregister_comm = function (comm) {
60 // Remove a comm from the mapping
70 /**
71 * Remove a comm from the mapping
72 */
61 delete this.comms[comm.comm_id];
73 delete this.comms[comm.comm_id];
62 };
74 };
63
75
@@ -266,7 +266,9 b' define(['
266
266
267 var that = this;
267 var that = this;
268 var on_success = function (data, status, xhr) {
268 var on_success = function (data, status, xhr) {
269 // get kernel info so we know what state the kernel is in
269 /**
270 * get kernel info so we know what state the kernel is in
271 */
270 that.kernel_info();
272 that.kernel_info();
271 if (success) {
273 if (success) {
272 success(data, status, xhr);
274 success(data, status, xhr);
@@ -538,8 +540,10 b' define(['
538 };
540 };
539
541
540 Kernel.prototype._schedule_reconnect = function () {
542 Kernel.prototype._schedule_reconnect = function () {
541 // function to call when kernel connection is lost
543 /**
542 // schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
544 * function to call when kernel connection is lost
545 * schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
546 */
543 if (this._reconnect_attempt < this.reconnect_limit) {
547 if (this._reconnect_attempt < this.reconnect_limit) {
544 var timeout = Math.pow(2, this._reconnect_attempt);
548 var timeout = Math.pow(2, this._reconnect_attempt);
545 console.log("Connection lost, reconnecting in " + timeout + " seconds.");
549 console.log("Connection lost, reconnecting in " + timeout + " seconds.");
@@ -31,9 +31,11 b' define(['
31 };
31 };
32
32
33 var _deserialize_binary = function(data, callback) {
33 var _deserialize_binary = function(data, callback) {
34 // deserialize the binary message format
34 /**
35 // callback will be called with a message whose buffers attribute
35 * deserialize the binary message format
36 // will be an array of DataViews.
36 * callback will be called with a message whose buffers attribute
37 * will be an array of DataViews.
38 */
37 if (data instanceof Blob) {
39 if (data instanceof Blob) {
38 // data is Blob, have to deserialize from ArrayBuffer in reader callback
40 // data is Blob, have to deserialize from ArrayBuffer in reader callback
39 var reader = new FileReader();
41 var reader = new FileReader();
@@ -50,7 +52,9 b' define(['
50 };
52 };
51
53
52 var deserialize = function (data, callback) {
54 var deserialize = function (data, callback) {
53 // deserialize a message and pass the unpacked message object to callback
55 /**
56 * deserialize a message and pass the unpacked message object to callback
57 */
54 if (typeof data === "string") {
58 if (typeof data === "string") {
55 // text JSON message
59 // text JSON message
56 callback(JSON.parse(data));
60 callback(JSON.parse(data));
@@ -61,8 +65,10 b' define(['
61 };
65 };
62
66
63 var _serialize_binary = function (msg) {
67 var _serialize_binary = function (msg) {
64 // implement the binary serialization protocol
68 /**
65 // serializes JSON message to ArrayBuffer
69 * implement the binary serialization protocol
70 * serializes JSON message to ArrayBuffer
71 */
66 msg = _.clone(msg);
72 msg = _.clone(msg);
67 var offsets = [];
73 var offsets = [];
68 var buffers = [];
74 var buffers = [];
@@ -9,15 +9,17 b' define(['
9 "use strict";
9 "use strict";
10
10
11 var KernelList = function (selector, options) {
11 var KernelList = function (selector, options) {
12 // Constructor
12 /**
13 //
13 * Constructor
14 // Parameters:
14 *
15 // selector: string
15 * Parameters:
16 // options: dictionary
16 * selector: string
17 // Dictionary of keyword arguments.
17 * options: dictionary
18 // session_list: SessionList instance
18 * Dictionary of keyword arguments.
19 // base_url: string
19 * session_list: SessionList instance
20 // notebook_path: string
20 * base_url: string
21 * notebook_path: string
22 */
21 notebooklist.NotebookList.call(this, selector, $.extend({
23 notebooklist.NotebookList.call(this, selector, $.extend({
22 element_name: 'running'},
24 element_name: 'running'},
23 options));
25 options));
@@ -26,7 +28,9 b' define(['
26 KernelList.prototype = Object.create(notebooklist.NotebookList.prototype);
28 KernelList.prototype = Object.create(notebooklist.NotebookList.prototype);
27
29
28 KernelList.prototype.add_duplicate_button = function () {
30 KernelList.prototype.add_duplicate_button = function () {
29 // do nothing
31 /**
32 * do nothing
33 */
30 };
34 };
31
35
32 KernelList.prototype.sessions_loaded = function (d) {
36 KernelList.prototype.sessions_loaded = function (d) {
@@ -88,7 +88,9 b' require(['
88 var time_refresh = 60; // in sec
88 var time_refresh = 60; // in sec
89
89
90 var enable_autorefresh = function(){
90 var enable_autorefresh = function(){
91 //refresh immediately , then start interval
91 /**
92 *refresh immediately , then start interval
93 */
92 session_list.load_sessions();
94 session_list.load_sessions();
93 cluster_list.load_list();
95 cluster_list.load_list();
94 if (terminal_list) {
96 if (terminal_list) {
@@ -11,17 +11,19 b' define(['
11 "use strict";
11 "use strict";
12
12
13 var NotebookList = function (selector, options) {
13 var NotebookList = function (selector, options) {
14 // Constructor
14 /**
15 //
15 * Constructor
16 // Parameters:
16 *
17 // selector: string
17 * Parameters:
18 // options: dictionary
18 * selector: string
19 // Dictionary of keyword arguments.
19 * options: dictionary
20 // session_list: SessionList instance
20 * Dictionary of keyword arguments.
21 // element_name: string
21 * session_list: SessionList instance
22 // base_url: string
22 * element_name: string
23 // notebook_path: string
23 * base_url: string
24 // contents: Contents instance
24 * notebook_path: string
25 * contents: Contents instance
26 */
25 var that = this;
27 var that = this;
26 this.session_list = options.session_list;
28 this.session_list = options.session_list;
27 // allow code re-use by just changing element_name in kernellist.js
29 // allow code re-use by just changing element_name in kernellist.js
@@ -119,11 +121,13 b' define(['
119 };
121 };
120
122
121 NotebookList.prototype.clear_list = function (remove_uploads) {
123 NotebookList.prototype.clear_list = function (remove_uploads) {
122 // Clears the navigation tree.
124 /**
123 //
125 * Clears the navigation tree.
124 // Parameters
126 *
125 // remove_uploads: bool=False
127 * Parameters
126 // Should upload prompts also be removed from the tree.
128 * remove_uploads: bool=False
129 * Should upload prompts also be removed from the tree.
130 */
127 if (remove_uploads) {
131 if (remove_uploads) {
128 this.element.children('.list_item').remove();
132 this.element.children('.list_item').remove();
129 } else {
133 } else {
@@ -378,7 +382,9 b' define(['
378 };
382 };
379
383
380 NotebookList.prototype.notebook_deleted = function(path) {
384 NotebookList.prototype.notebook_deleted = function(path) {
381 // Remove the deleted notebook.
385 /**
386 * Remove the deleted notebook.
387 */
382 $( ":data(path)" ).each(function() {
388 $( ":data(path)" ).each(function() {
383 var element = $(this);
389 var element = $(this);
384 if (element.data("path") == path) {
390 if (element.data("path") == path) {
@@ -9,13 +9,15 b' define(['
9 "use strict";
9 "use strict";
10
10
11 var SesssionList = function (options) {
11 var SesssionList = function (options) {
12 // Constructor
12 /**
13 //
13 * Constructor
14 // Parameters:
14 *
15 // options: dictionary
15 * Parameters:
16 // Dictionary of keyword arguments.
16 * options: dictionary
17 // events: $(Events) instance
17 * Dictionary of keyword arguments.
18 // base_url : string
18 * events: $(Events) instance
19 * base_url : string
20 */
19 this.events = options.events;
21 this.events = options.events;
20 this.sessions = {};
22 this.sessions = {};
21 this.base_url = options.base_url || utils.get_body_data("baseUrl");
23 this.base_url = options.base_url || utils.get_body_data("baseUrl");
@@ -10,13 +10,15 b' define(['
10 "use strict";
10 "use strict";
11
11
12 var TerminalList = function (selector, options) {
12 var TerminalList = function (selector, options) {
13 // Constructor
13 /**
14 //
14 * Constructor
15 // Parameters:
15 *
16 // selector: string
16 * Parameters:
17 // options: dictionary
17 * selector: string
18 // Dictionary of keyword arguments.
18 * options: dictionary
19 // base_url: string
19 * Dictionary of keyword arguments.
20 * base_url: string
21 */
20 this.base_url = options.base_url || utils.get_body_data("baseUrl");
22 this.base_url = options.base_url || utils.get_body_data("baseUrl");
21 this.element_name = options.element_name || 'terminal';
23 this.element_name = options.element_name || 'terminal';
22 this.selector = selector;
24 this.selector = selector;
@@ -13,7 +13,9 b' define(['
13 // WidgetManager class
13 // WidgetManager class
14 //--------------------------------------------------------------------
14 //--------------------------------------------------------------------
15 var WidgetManager = function (comm_manager, notebook) {
15 var WidgetManager = function (comm_manager, notebook) {
16 // Public constructor
16 /**
17 * Public constructor
18 */
17 WidgetManager._managers.push(this);
19 WidgetManager._managers.push(this);
18
20
19 // Attach a comm manager to the
21 // Attach a comm manager to the
@@ -47,7 +49,9 b' define(['
47 // Instance level
49 // Instance level
48 //--------------------------------------------------------------------
50 //--------------------------------------------------------------------
49 WidgetManager.prototype.display_view = function(msg, model) {
51 WidgetManager.prototype.display_view = function(msg, model) {
50 // Displays a view for a particular model.
52 /**
53 * Displays a view for a particular model.
54 */
51 var that = this;
55 var that = this;
52 var cell = this.get_msg_cell(msg.parent_header.msg_id);
56 var cell = this.get_msg_cell(msg.parent_header.msg_id);
53 if (cell === null) {
57 if (cell === null) {
@@ -67,9 +71,11 b' define(['
67 };
71 };
68
72
69 WidgetManager.prototype._handle_display_view = function (view) {
73 WidgetManager.prototype._handle_display_view = function (view) {
70 // Have the IPython keyboard manager disable its event
74 /**
71 // handling so the widget can capture keyboard input.
75 * Have the IPython keyboard manager disable its event
72 // Note, this is only done on the outer most widgets.
76 * handling so the widget can capture keyboard input.
77 * Note, this is only done on the outer most widgets.
78 */
73 if (this.keyboard_manager) {
79 if (this.keyboard_manager) {
74 this.keyboard_manager.register_events(view.$el);
80 this.keyboard_manager.register_events(view.$el);
75
81
@@ -82,10 +88,12 b' define(['
82 };
88 };
83
89
84 WidgetManager.prototype.create_view = function(model, options) {
90 WidgetManager.prototype.create_view = function(model, options) {
85 // Creates a promise for a view of a given model
91 /**
86
92 * Creates a promise for a view of a given model
87 // Make sure the view creation is not out of order with
93 *
88 // any state updates.
94 * Make sure the view creation is not out of order with
95 * any state updates.
96 */
89 model.state_change = model.state_change.then(function() {
97 model.state_change = model.state_change.then(function() {
90
98
91 return utils.load_class(model.get('_view_name'), model.get('_view_module'),
99 return utils.load_class(model.get('_view_name'), model.get('_view_module'),
@@ -135,7 +143,9 b' define(['
135 };
143 };
136
144
137 WidgetManager.prototype.callbacks = function (view) {
145 WidgetManager.prototype.callbacks = function (view) {
138 // callback handlers specific a view
146 /**
147 * callback handlers specific a view
148 */
139 var callbacks = {};
149 var callbacks = {};
140 if (view && view.options.cell) {
150 if (view && view.options.cell) {
141
151
@@ -168,12 +178,16 b' define(['
168 };
178 };
169
179
170 WidgetManager.prototype.get_model = function (model_id) {
180 WidgetManager.prototype.get_model = function (model_id) {
171 // Get a promise for a model by model id.
181 /**
182 * Get a promise for a model by model id.
183 */
172 return this._models[model_id];
184 return this._models[model_id];
173 };
185 };
174
186
175 WidgetManager.prototype._handle_comm_open = function (comm, msg) {
187 WidgetManager.prototype._handle_comm_open = function (comm, msg) {
176 // Handle when a comm is opened.
188 /**
189 * Handle when a comm is opened.
190 */
177 return this.create_model({
191 return this.create_model({
178 model_name: msg.content.data.model_name,
192 model_name: msg.content.data.model_name,
179 model_module: msg.content.data.model_module,
193 model_module: msg.content.data.model_module,
@@ -181,33 +195,35 b' define(['
181 };
195 };
182
196
183 WidgetManager.prototype.create_model = function (options) {
197 WidgetManager.prototype.create_model = function (options) {
184 // Create and return a promise for a new widget model
198 /**
185 //
199 * Create and return a promise for a new widget model
186 // Minimally, one must provide the model_name and widget_class
200 *
187 // parameters to create a model from Javascript.
201 * Minimally, one must provide the model_name and widget_class
188 //
202 * parameters to create a model from Javascript.
189 // Example
203 *
190 // --------
204 * Example
191 // JS:
205 * --------
192 // IPython.notebook.kernel.widget_manager.create_model({
206 * JS:
193 // model_name: 'WidgetModel',
207 * IPython.notebook.kernel.widget_manager.create_model({
194 // widget_class: 'IPython.html.widgets.widget_int.IntSlider'})
208 * model_name: 'WidgetModel',
195 // .then(function(model) { console.log('Create success!', model); },
209 * widget_class: 'IPython.html.widgets.widget_int.IntSlider'})
196 // $.proxy(console.error, console));
210 * .then(function(model) { console.log('Create success!', model); },
197 //
211 * $.proxy(console.error, console));
198 // Parameters
212 *
199 // ----------
213 * Parameters
200 // options: dictionary
214 * ----------
201 // Dictionary of options with the following contents:
215 * options: dictionary
202 // model_name: string
216 * Dictionary of options with the following contents:
203 // Target name of the widget model to create.
217 * model_name: string
204 // model_module: (optional) string
218 * Target name of the widget model to create.
205 // Module name of the widget model to create.
219 * model_module: (optional) string
206 // widget_class: (optional) string
220 * Module name of the widget model to create.
207 // Target name of the widget in the back-end.
221 * widget_class: (optional) string
208 // comm: (optional) Comm
222 * Target name of the widget in the back-end.
209
223 * comm: (optional) Comm
210 // Create a comm if it wasn't provided.
224 *
225 * Create a comm if it wasn't provided.
226 */
211 var comm = options.comm;
227 var comm = options.comm;
212 if (!comm) {
228 if (!comm) {
213 comm = this.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
229 comm = this.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
@@ -11,16 +11,18 b' define(["widgets/js/manager",'
11
11
12 var WidgetModel = Backbone.Model.extend({
12 var WidgetModel = Backbone.Model.extend({
13 constructor: function (widget_manager, model_id, comm) {
13 constructor: function (widget_manager, model_id, comm) {
14 // Constructor
14 /**
15 //
15 * Constructor
16 // Creates a WidgetModel instance.
16 *
17 //
17 * Creates a WidgetModel instance.
18 // Parameters
18 *
19 // ----------
19 * Parameters
20 // widget_manager : WidgetManager instance
20 * ----------
21 // model_id : string
21 * widget_manager : WidgetManager instance
22 // An ID unique to this model.
22 * model_id : string
23 // comm : Comm instance (optional)
23 * An ID unique to this model.
24 * comm : Comm instance (optional)
25 */
24 this.widget_manager = widget_manager;
26 this.widget_manager = widget_manager;
25 this.state_change = Promise.resolve();
27 this.state_change = Promise.resolve();
26 this._buffered_state_diff = {};
28 this._buffered_state_diff = {};
@@ -43,7 +45,9 b' define(["widgets/js/manager",'
43 },
45 },
44
46
45 send: function (content, callbacks) {
47 send: function (content, callbacks) {
46 // Send a custom msg over the comm.
48 /**
49 * Send a custom msg over the comm.
50 */
47 if (this.comm !== undefined) {
51 if (this.comm !== undefined) {
48 var data = {method: 'custom', content: content};
52 var data = {method: 'custom', content: content};
49 this.comm.send(data, callbacks);
53 this.comm.send(data, callbacks);
@@ -52,7 +56,9 b' define(["widgets/js/manager",'
52 },
56 },
53
57
54 _handle_comm_closed: function (msg) {
58 _handle_comm_closed: function (msg) {
55 // Handle when a widget is closed.
59 /**
60 * Handle when a widget is closed.
61 */
56 this.trigger('comm:close');
62 this.trigger('comm:close');
57 this.stopListening();
63 this.stopListening();
58 this.trigger('destroy', this);
64 this.trigger('destroy', this);
@@ -67,7 +73,9 b' define(["widgets/js/manager",'
67 },
73 },
68
74
69 _handle_comm_msg: function (msg) {
75 _handle_comm_msg: function (msg) {
70 // Handle incoming comm msg.
76 /**
77 * Handle incoming comm msg.
78 */
71 var method = msg.content.data.method;
79 var method = msg.content.data.method;
72 var that = this;
80 var that = this;
73 switch (method) {
81 switch (method) {
@@ -99,9 +107,11 b' define(["widgets/js/manager",'
99 },
107 },
100
108
101 _handle_status: function (msg, callbacks) {
109 _handle_status: function (msg, callbacks) {
102 // Handle status msgs.
110 /**
103
111 * Handle status msgs.
104 // execution_state : ('busy', 'idle', 'starting')
112 *
113 * execution_state : ('busy', 'idle', 'starting')
114 */
105 if (this.comm !== undefined) {
115 if (this.comm !== undefined) {
106 if (msg.content.execution_state ==='idle') {
116 if (msg.content.execution_state ==='idle') {
107 // Send buffer if this message caused another message to be
117 // Send buffer if this message caused another message to be
@@ -119,7 +129,9 b' define(["widgets/js/manager",'
119 },
129 },
120
130
121 callbacks: function(view) {
131 callbacks: function(view) {
122 // Create msg callbacks for a comm msg.
132 /**
133 * Create msg callbacks for a comm msg.
134 */
123 var callbacks = this.widget_manager.callbacks(view);
135 var callbacks = this.widget_manager.callbacks(view);
124
136
125 if (callbacks.iopub === undefined) {
137 if (callbacks.iopub === undefined) {
@@ -134,7 +146,9 b' define(["widgets/js/manager",'
134 },
146 },
135
147
136 set: function(key, val, options) {
148 set: function(key, val, options) {
137 // Set a value.
149 /**
150 * Set a value.
151 */
138 var return_value = WidgetModel.__super__.set.apply(this, arguments);
152 var return_value = WidgetModel.__super__.set.apply(this, arguments);
139
153
140 // Backbone only remembers the diff of the most recent set()
154 // Backbone only remembers the diff of the most recent set()
@@ -145,9 +159,11 b' define(["widgets/js/manager",'
145 },
159 },
146
160
147 sync: function (method, model, options) {
161 sync: function (method, model, options) {
148 // Handle sync to the back-end. Called when a model.save() is called.
162 /**
149
163 * Handle sync to the back-end. Called when a model.save() is called.
150 // Make sure a comm exists.
164 *
165 * Make sure a comm exists.
166 */
151 var error = options.error || function() {
167 var error = options.error || function() {
152 console.error('Backbone sync error:', arguments);
168 console.error('Backbone sync error:', arguments);
153 };
169 };
@@ -213,14 +229,18 b' define(["widgets/js/manager",'
213 },
229 },
214
230
215 save_changes: function(callbacks) {
231 save_changes: function(callbacks) {
216 // Push this model's state to the back-end
232 /**
217 //
233 * Push this model's state to the back-end
218 // This invokes a Backbone.Sync.
234 *
235 * This invokes a Backbone.Sync.
236 */
219 this.save(this._buffered_state_diff, {patch: true, callbacks: callbacks});
237 this.save(this._buffered_state_diff, {patch: true, callbacks: callbacks});
220 },
238 },
221
239
222 _pack_models: function(value) {
240 _pack_models: function(value) {
223 // Replace models with model ids recursively.
241 /**
242 * Replace models with model ids recursively.
243 */
224 var that = this;
244 var that = this;
225 var packed;
245 var packed;
226 if (value instanceof Backbone.Model) {
246 if (value instanceof Backbone.Model) {
@@ -247,7 +267,9 b' define(["widgets/js/manager",'
247 },
267 },
248
268
249 _unpack_models: function(value) {
269 _unpack_models: function(value) {
250 // Replace model ids with models recursively.
270 /**
271 * Replace model ids with models recursively.
272 */
251 var that = this;
273 var that = this;
252 var unpacked;
274 var unpacked;
253 if ($.isArray(value)) {
275 if ($.isArray(value)) {
@@ -271,11 +293,13 b' define(["widgets/js/manager",'
271 },
293 },
272
294
273 on_some_change: function(keys, callback, context) {
295 on_some_change: function(keys, callback, context) {
274 // on_some_change(["key1", "key2"], foo, context) differs from
296 /**
275 // on("change:key1 change:key2", foo, context).
297 * on_some_change(["key1", "key2"], foo, context) differs from
276 // If the widget attributes key1 and key2 are both modified,
298 * on("change:key1 change:key2", foo, context).
277 // the second form will result in foo being called twice
299 * If the widget attributes key1 and key2 are both modified,
278 // while the first will call foo only once.
300 * the second form will result in foo being called twice
301 * while the first will call foo only once.
302 */
279 this.on('change', function() {
303 this.on('change', function() {
280 if (keys.some(this.hasChanged, this)) {
304 if (keys.some(this.hasChanged, this)) {
281 callback.apply(context);
305 callback.apply(context);
@@ -289,7 +313,9 b' define(["widgets/js/manager",'
289
313
290 var WidgetView = Backbone.View.extend({
314 var WidgetView = Backbone.View.extend({
291 initialize: function(parameters) {
315 initialize: function(parameters) {
292 // Public constructor.
316 /**
317 * Public constructor.
318 */
293 this.model.on('change',this.update,this);
319 this.model.on('change',this.update,this);
294 this.options = parameters.options;
320 this.options = parameters.options;
295 this.id = this.id || utils.uuid();
321 this.id = this.id || utils.uuid();
@@ -300,31 +326,41 b' define(["widgets/js/manager",'
300 },
326 },
301
327
302 update: function(){
328 update: function(){
303 // Triggered on model change.
329 /**
304 //
330 * Triggered on model change.
305 // Update view to be consistent with this.model
331 *
332 * Update view to be consistent with this.model
333 */
306 },
334 },
307
335
308 create_child_view: function(child_model, options) {
336 create_child_view: function(child_model, options) {
309 // Create and promise that resolves to a child view of a given model
337 /**
338 * Create and promise that resolves to a child view of a given model
339 */
310 var that = this;
340 var that = this;
311 options = $.extend({ parent: this }, options || {});
341 options = $.extend({ parent: this }, options || {});
312 return this.model.widget_manager.create_view(child_model, options).catch(utils.reject("Couldn't create child view"), true);
342 return this.model.widget_manager.create_view(child_model, options).catch(utils.reject("Couldn't create child view"), true);
313 },
343 },
314
344
315 callbacks: function(){
345 callbacks: function(){
316 // Create msg callbacks for a comm msg.
346 /**
347 * Create msg callbacks for a comm msg.
348 */
317 return this.model.callbacks(this);
349 return this.model.callbacks(this);
318 },
350 },
319
351
320 render: function(){
352 render: function(){
321 // Render the view.
353 /**
322 //
354 * Render the view.
323 // By default, this is only called the first time the view is created
355 *
356 * By default, this is only called the first time the view is created
357 */
324 },
358 },
325
359
326 show: function(){
360 show: function(){
327 // Show the widget-area
361 /**
362 * Show the widget-area
363 */
328 if (this.options && this.options.cell &&
364 if (this.options && this.options.cell &&
329 this.options.cell.widget_area !== undefined) {
365 this.options.cell.widget_area !== undefined) {
330 this.options.cell.widget_area.show();
366 this.options.cell.widget_area.show();
@@ -332,7 +368,9 b' define(["widgets/js/manager",'
332 },
368 },
333
369
334 send: function (content) {
370 send: function (content) {
335 // Send a custom msg associated with this view.
371 /**
372 * Send a custom msg associated with this view.
373 */
336 this.model.send(content, this.callbacks());
374 this.model.send(content, this.callbacks());
337 },
375 },
338
376
@@ -341,8 +379,10 b' define(["widgets/js/manager",'
341 },
379 },
342
380
343 after_displayed: function (callback, context) {
381 after_displayed: function (callback, context) {
344 // Calls the callback right away is the view is already displayed
382 /**
345 // otherwise, register the callback to the 'displayed' event.
383 * Calls the callback right away is the view is already displayed
384 * otherwise, register the callback to the 'displayed' event.
385 */
346 if (this.is_displayed) {
386 if (this.is_displayed) {
347 callback.apply(context);
387 callback.apply(context);
348 } else {
388 } else {
@@ -354,7 +394,9 b' define(["widgets/js/manager",'
354
394
355 var DOMWidgetView = WidgetView.extend({
395 var DOMWidgetView = WidgetView.extend({
356 initialize: function (parameters) {
396 initialize: function (parameters) {
357 // Public constructor
397 /**
398 * Public constructor
399 */
358 DOMWidgetView.__super__.initialize.apply(this, [parameters]);
400 DOMWidgetView.__super__.initialize.apply(this, [parameters]);
359 this.on('displayed', this.show, this);
401 this.on('displayed', this.show, this);
360 this.model.on('change:visible', this.update_visible, this);
402 this.model.on('change:visible', this.update_visible, this);
@@ -431,7 +473,9 b' define(["widgets/js/manager",'
431 },
473 },
432
474
433 _default_px: function(value) {
475 _default_px: function(value) {
434 // Makes browser interpret a numerical string as a pixel value.
476 /**
477 * Makes browser interpret a numerical string as a pixel value.
478 */
435 if (/^\d+\.?(\d+)?$/.test(value.trim())) {
479 if (/^\d+\.?(\d+)?$/.test(value.trim())) {
436 return value.trim() + 'px';
480 return value.trim() + 'px';
437 }
481 }
@@ -439,17 +483,23 b' define(["widgets/js/manager",'
439 },
483 },
440
484
441 update_attr: function(name, value) {
485 update_attr: function(name, value) {
442 // Set a css attr of the widget view.
486 /**
487 * Set a css attr of the widget view.
488 */
443 this.$el.css(name, value);
489 this.$el.css(name, value);
444 },
490 },
445
491
446 update_visible: function(model, value) {
492 update_visible: function(model, value) {
447 // Update visibility
493 /**
494 * Update visibility
495 */
448 this.$el.toggle(value);
496 this.$el.toggle(value);
449 },
497 },
450
498
451 update_css: function (model, css) {
499 update_css: function (model, css) {
452 // Update the css styling of this view.
500 /**
501 * Update the css styling of this view.
502 */
453 var e = this.$el;
503 var e = this.$el;
454 if (css === undefined) {return;}
504 if (css === undefined) {return;}
455 for (var i = 0; i < css.length; i++) {
505 for (var i = 0; i < css.length; i++) {
@@ -465,7 +515,9 b' define(["widgets/js/manager",'
465 },
515 },
466
516
467 update_classes: function (old_classes, new_classes, $el) {
517 update_classes: function (old_classes, new_classes, $el) {
468 // Update the DOM classes applied to an element, default to this.$el.
518 /**
519 * Update the DOM classes applied to an element, default to this.$el.
520 */
469 if ($el===undefined) {
521 if ($el===undefined) {
470 $el = this.$el;
522 $el = this.$el;
471 }
523 }
@@ -474,30 +526,32 b' define(["widgets/js/manager",'
474 },
526 },
475
527
476 update_mapped_classes: function(class_map, trait_name, previous_trait_value, $el) {
528 update_mapped_classes: function(class_map, trait_name, previous_trait_value, $el) {
477 // Update the DOM classes applied to the widget based on a single
529 /**
478 // trait's value.
530 * Update the DOM classes applied to the widget based on a single
479 //
531 * trait's value.
480 // Given a trait value classes map, this function automatically
532 *
481 // handles applying the appropriate classes to the widget element
533 * Given a trait value classes map, this function automatically
482 // and removing classes that are no longer valid.
534 * handles applying the appropriate classes to the widget element
483 //
535 * and removing classes that are no longer valid.
484 // Parameters
536 *
485 // ----------
537 * Parameters
486 // class_map: dictionary
538 * ----------
487 // Dictionary of trait values to class lists.
539 * class_map: dictionary
488 // Example:
540 * Dictionary of trait values to class lists.
489 // {
541 * Example:
490 // success: ['alert', 'alert-success'],
542 * {
491 // info: ['alert', 'alert-info'],
543 * success: ['alert', 'alert-success'],
492 // warning: ['alert', 'alert-warning'],
544 * info: ['alert', 'alert-info'],
493 // danger: ['alert', 'alert-danger']
545 * warning: ['alert', 'alert-warning'],
494 // };
546 * danger: ['alert', 'alert-danger']
495 // trait_name: string
547 * };
496 // Name of the trait to check the value of.
548 * trait_name: string
497 // previous_trait_value: optional string, default ''
549 * Name of the trait to check the value of.
498 // Last trait value
550 * previous_trait_value: optional string, default ''
499 // $el: optional jQuery element handle, defaults to this.$el
551 * Last trait value
500 // Element that the classes are applied to.
552 * $el: optional jQuery element handle, defaults to this.$el
553 * Element that the classes are applied to.
554 */
501 var key = previous_trait_value;
555 var key = previous_trait_value;
502 if (key === undefined) {
556 if (key === undefined) {
503 key = this.model.previous(trait_name);
557 key = this.model.previous(trait_name);
@@ -510,7 +564,9 b' define(["widgets/js/manager",'
510 },
564 },
511
565
512 _get_selector_element: function (selector) {
566 _get_selector_element: function (selector) {
513 // Get the elements via the css selector.
567 /**
568 * Get the elements via the css selector.
569 */
514 var elements;
570 var elements;
515 if (!selector) {
571 if (!selector) {
516 elements = this.$el;
572 elements = this.$el;
@@ -523,16 +579,18 b' define(["widgets/js/manager",'
523
579
524
580
525 var ViewList = function(create_view, remove_view, context) {
581 var ViewList = function(create_view, remove_view, context) {
526 // * create_view and remove_view are default functions called when adding or removing views
582 /**
527 // * create_view takes a model and returns a view or a promise for a view for that model
583 * - create_view and remove_view are default functions called when adding or removing views
528 // * remove_view takes a view and destroys it (including calling `view.remove()`)
584 * - create_view takes a model and returns a view or a promise for a view for that model
529 // * each time the update() function is called with a new list, the create and remove
585 * - remove_view takes a view and destroys it (including calling `view.remove()`)
530 // callbacks will be called in an order so that if you append the views created in the
586 * - each time the update() function is called with a new list, the create and remove
531 // create callback and remove the views in the remove callback, you will duplicate
587 * callbacks will be called in an order so that if you append the views created in the
532 // the order of the list.
588 * create callback and remove the views in the remove callback, you will duplicate
533 // * the remove callback defaults to just removing the view (e.g., pass in null for the second parameter)
589 * the order of the list.
534 // * the context defaults to the created ViewList. If you pass another context, the create and remove
590 * - the remove callback defaults to just removing the view (e.g., pass in null for the second parameter)
535 // will be called in that context.
591 * - the context defaults to the created ViewList. If you pass another context, the create and remove
592 * will be called in that context.
593 */
536
594
537 this.initialize.apply(this, arguments);
595 this.initialize.apply(this, arguments);
538 };
596 };
@@ -548,9 +606,11 b' define(["widgets/js/manager",'
548 },
606 },
549
607
550 update: function(new_models, create_view, remove_view, context) {
608 update: function(new_models, create_view, remove_view, context) {
551 // the create_view, remove_view, and context arguments override the defaults
609 /**
552 // specified when the list is created.
610 * the create_view, remove_view, and context arguments override the defaults
553 // returns a promise that resolves after this update is done
611 * specified when the list is created.
612 * returns a promise that resolves after this update is done
613 */
554 var remove = remove_view || this._remove_view;
614 var remove = remove_view || this._remove_view;
555 var create = create_view || this._create_view;
615 var create = create_view || this._create_view;
556 if (create === undefined || remove === undefined){
616 if (create === undefined || remove === undefined){
@@ -588,9 +648,11 b' define(["widgets/js/manager",'
588 },
648 },
589
649
590 remove: function() {
650 remove: function() {
591 // removes every view in the list; convenience function for `.update([])`
651 /**
592 // that should be faster
652 * removes every view in the list; convenience function for `.update([])`
593 // returns a promise that resolves after this removal is done
653 * that should be faster
654 * returns a promise that resolves after this removal is done
655 */
594 var that = this;
656 var that = this;
595 this.state_change = this.state_change.then(function() {
657 this.state_change = this.state_change.then(function() {
596 for (var i = 0; i < that.views.length; i++) {
658 for (var i = 0; i < that.views.length; i++) {
@@ -9,7 +9,9 b' define(['
9
9
10 var CheckboxView = widget.DOMWidgetView.extend({
10 var CheckboxView = widget.DOMWidgetView.extend({
11 render : function(){
11 render : function(){
12 // Called when view is rendered.
12 /**
13 * Called when view is rendered.
14 */
13 this.$el
15 this.$el
14 .addClass('widget-hbox widget-checkbox');
16 .addClass('widget-hbox widget-checkbox');
15 this.$label = $('<div />')
17 this.$label = $('<div />')
@@ -25,25 +27,31 b' define(['
25 },
27 },
26
28
27 update_attr: function(name, value) {
29 update_attr: function(name, value) {
28 // Set a css attr of the widget view.
30 /**
31 * Set a css attr of the widget view.
32 */
29 this.$checkbox.css(name, value);
33 this.$checkbox.css(name, value);
30 },
34 },
31
35
32 handle_click: function() {
36 handle_click: function() {
33 // Handles when the checkbox is clicked.
37 /**
34
38 * Handles when the checkbox is clicked.
35 // Calling model.set will trigger all of the other views of the
39 *
36 // model to update.
40 * Calling model.set will trigger all of the other views of the
41 * model to update.
42 */
37 var value = this.model.get('value');
43 var value = this.model.get('value');
38 this.model.set('value', ! value, {updated_view: this});
44 this.model.set('value', ! value, {updated_view: this});
39 this.touch();
45 this.touch();
40 },
46 },
41
47
42 update : function(options){
48 update : function(options){
43 // Update the contents of this view
49 /**
44 //
50 * Update the contents of this view
45 // Called when the model is changed. The model may have been
51 *
46 // changed by another view or by a state update from the back-end.
52 * Called when the model is changed. The model may have been
53 * changed by another view or by a state update from the back-end.
54 */
47 this.$checkbox.prop('checked', this.model.get('value'));
55 this.$checkbox.prop('checked', this.model.get('value'));
48
56
49 if (options === undefined || options.updated_view != this) {
57 if (options === undefined || options.updated_view != this) {
@@ -67,7 +75,9 b' define(['
67
75
68 var ToggleButtonView = widget.DOMWidgetView.extend({
76 var ToggleButtonView = widget.DOMWidgetView.extend({
69 render : function() {
77 render : function() {
70 // Called when view is rendered.
78 /**
79 * Called when view is rendered.
80 */
71 var that = this;
81 var that = this;
72 this.setElement($('<button />')
82 this.setElement($('<button />')
73 .addClass('btn btn-default')
83 .addClass('btn btn-default')
@@ -97,10 +107,12 b' define(['
97 },
107 },
98
108
99 update : function(options){
109 update : function(options){
100 // Update the contents of this view
110 /**
101 //
111 * Update the contents of this view
102 // Called when the model is changed. The model may have been
112 *
103 // changed by another view or by a state update from the back-end.
113 * Called when the model is changed. The model may have been
114 * changed by another view or by a state update from the back-end.
115 */
104 if (this.model.get('value')) {
116 if (this.model.get('value')) {
105 this.$el.addClass('active');
117 this.$el.addClass('active');
106 } else {
118 } else {
@@ -124,10 +136,12 b' define(['
124 },
136 },
125
137
126 handle_click: function(e) {
138 handle_click: function(e) {
127 // Handles and validates user input.
139 /**
128
140 * Handles and validates user input.
129 // Calling model.set will trigger all of the other views of the
141 *
130 // model to update.
142 * Calling model.set will trigger all of the other views of the
143 * model to update.
144 */
131 var value = this.model.get('value');
145 var value = this.model.get('value');
132 this.model.set('value', ! value, {updated_view: this});
146 this.model.set('value', ! value, {updated_view: this});
133 this.touch();
147 this.touch();
@@ -10,7 +10,9 b' define(['
10
10
11 var BoxView = widget.DOMWidgetView.extend({
11 var BoxView = widget.DOMWidgetView.extend({
12 initialize: function(){
12 initialize: function(){
13 // Public constructor
13 /**
14 * Public constructor
15 */
14 BoxView.__super__.initialize.apply(this, arguments);
16 BoxView.__super__.initialize.apply(this, arguments);
15 this.children_views = new widget.ViewList(this.add_child_model, null, this);
17 this.children_views = new widget.ViewList(this.add_child_model, null, this);
16 this.listenTo(this.model, 'change:children', function(model, value) {
18 this.listenTo(this.model, 'change:children', function(model, value) {
@@ -28,12 +30,16 b' define(['
28 },
30 },
29
31
30 update_attr: function(name, value) {
32 update_attr: function(name, value) {
31 // Set a css attr of the widget view.
33 /**
34 * Set a css attr of the widget view.
35 */
32 this.$box.css(name, value);
36 this.$box.css(name, value);
33 },
37 },
34
38
35 render: function(){
39 render: function(){
36 // Called when view is rendered.
40 /**
41 * Called when view is rendered.
42 */
37 this.$box = this.$el;
43 this.$box = this.$el;
38 this.$box.addClass('widget-box');
44 this.$box.addClass('widget-box');
39 this.children_views.update(this.model.get('children'));
45 this.children_views.update(this.model.get('children'));
@@ -43,12 +49,16 b' define(['
43 },
49 },
44
50
45 update_overflow_x: function() {
51 update_overflow_x: function() {
46 // Called when the x-axis overflow setting is changed.
52 /**
53 * Called when the x-axis overflow setting is changed.
54 */
47 this.$box.css('overflow-x', this.model.get('overflow_x'));
55 this.$box.css('overflow-x', this.model.get('overflow_x'));
48 },
56 },
49
57
50 update_overflow_y: function() {
58 update_overflow_y: function() {
51 // Called when the y-axis overflow setting is changed.
59 /**
60 * Called when the y-axis overflow setting is changed.
61 */
52 this.$box.css('overflow-y', this.model.get('overflow_y'));
62 this.$box.css('overflow-y', this.model.get('overflow_y'));
53 },
63 },
54
64
@@ -63,7 +73,9 b' define(['
63 },
73 },
64
74
65 add_child_model: function(model) {
75 add_child_model: function(model) {
66 // Called when a model is added to the children list.
76 /**
77 * Called when a model is added to the children list.
78 */
67 var that = this;
79 var that = this;
68 var dummy = $('<div/>');
80 var dummy = $('<div/>');
69 that.$box.append(dummy);
81 that.$box.append(dummy);
@@ -79,9 +91,11 b' define(['
79 },
91 },
80
92
81 remove: function() {
93 remove: function() {
82 // We remove this widget before removing the children as an optimization
94 /**
83 // we want to remove the entire container from the DOM first before
95 * We remove this widget before removing the children as an optimization
84 // removing each individual child separately.
96 * we want to remove the entire container from the DOM first before
97 * removing each individual child separately.
98 */
85 BoxView.__super__.remove.apply(this, arguments);
99 BoxView.__super__.remove.apply(this, arguments);
86 this.children_views.remove();
100 this.children_views.remove();
87 },
101 },
@@ -135,7 +149,9 b' define(['
135 var PopupView = BoxView.extend({
149 var PopupView = BoxView.extend({
136
150
137 render: function(){
151 render: function(){
138 // Called when view is rendered.
152 /**
153 * Called when view is rendered.
154 */
139 var that = this;
155 var that = this;
140
156
141 this.$el.on("remove", function(){
157 this.$el.on("remove", function(){
@@ -245,13 +261,17 b' define(['
245 },
261 },
246
262
247 hide: function() {
263 hide: function() {
248 // Called when the modal hide button is clicked.
264 /**
265 * Called when the modal hide button is clicked.
266 */
249 this.$window.hide();
267 this.$window.hide();
250 this.$show_button.removeClass('btn-info');
268 this.$show_button.removeClass('btn-info');
251 },
269 },
252
270
253 show: function() {
271 show: function() {
254 // Called when the modal show button is clicked.
272 /**
273 * Called when the modal show button is clicked.
274 */
255 this.$show_button.addClass('btn-info');
275 this.$show_button.addClass('btn-info');
256 this.$window.show();
276 this.$window.show();
257 if (this.popped_out) {
277 if (this.popped_out) {
@@ -264,7 +284,9 b' define(['
264 },
284 },
265
285
266 bring_to_front: function() {
286 bring_to_front: function() {
267 // Make the modal top-most, z-ordered about the other modals.
287 /**
288 * Make the modal top-most, z-ordered about the other modals.
289 */
268 var $widget_modals = $(".widget-modal");
290 var $widget_modals = $(".widget-modal");
269 var max_zindex = 0;
291 var max_zindex = 0;
270 $widget_modals.each(function (index, el){
292 $widget_modals.each(function (index, el){
@@ -287,10 +309,12 b' define(['
287 },
309 },
288
310
289 update: function(){
311 update: function(){
290 // Update the contents of this view
312 /**
291 //
313 * Update the contents of this view
292 // Called when the model is changed. The model may have been
314 *
293 // changed by another view or by a state update from the back-end.
315 * Called when the model is changed. The model may have been
316 * changed by another view or by a state update from the back-end.
317 */
294 var description = this.model.get('description');
318 var description = this.model.get('description');
295 if (description.trim().length === 0) {
319 if (description.trim().length === 0) {
296 this.$title.html("&nbsp;"); // Preserve title height
320 this.$title.html("&nbsp;"); // Preserve title height
@@ -315,15 +339,17 b' define(['
315 },
339 },
316
340
317 _get_selector_element: function(selector) {
341 _get_selector_element: function(selector) {
318 // Get an element view a 'special' jquery selector. (see widget.js)
342 /**
319 //
343 * Get an element view a 'special' jquery selector. (see widget.js)
320 // Since the modal actually isn't within the $el in the DOM, we need to extend
344 *
321 // the selector logic to allow the user to set css on the modal if need be.
345 * Since the modal actually isn't within the $el in the DOM, we need to extend
322 // The convention used is:
346 * the selector logic to allow the user to set css on the modal if need be.
323 // "modal" - select the modal div
347 * The convention used is:
324 // "modal [selector]" - select element(s) within the modal div.
348 * "modal" - select the modal div
325 // "[selector]" - select elements within $el
349 * "modal [selector]" - select element(s) within the modal div.
326 // "" - select the $el
350 * "[selector]" - select elements within $el
351 * "" - select the $el
352 */
327 if (selector.substring(0, 5) == 'modal') {
353 if (selector.substring(0, 5) == 'modal') {
328 if (selector == 'modal') {
354 if (selector == 'modal') {
329 return this.$window;
355 return this.$window;
@@ -9,7 +9,9 b' define(['
9
9
10 var ButtonView = widget.DOMWidgetView.extend({
10 var ButtonView = widget.DOMWidgetView.extend({
11 render : function(){
11 render : function(){
12 // Called when view is rendered.
12 /**
13 * Called when view is rendered.
14 */
13 this.setElement($("<button />")
15 this.setElement($("<button />")
14 .addClass('btn btn-default'));
16 .addClass('btn btn-default'));
15 this.$el.attr("data-toggle", "tooltip");
17 this.$el.attr("data-toggle", "tooltip");
@@ -22,10 +24,12 b' define(['
22 },
24 },
23
25
24 update : function(){
26 update : function(){
25 // Update the contents of this view
27 /**
26 //
28 * Update the contents of this view
27 // Called when the model is changed. The model may have been
29 *
28 // changed by another view or by a state update from the back-end.
30 * Called when the model is changed. The model may have been
31 * changed by another view or by a state update from the back-end.
32 */
29 var description = this.model.get('description');
33 var description = this.model.get('description');
30 this.$el.attr("title", this.model.get("tooltip"));
34 this.$el.attr("title", this.model.get("tooltip"));
31 if (description.length === 0) {
35 if (description.length === 0) {
@@ -60,7 +64,9 b' define(['
60 },
64 },
61
65
62 _handle_click: function(){
66 _handle_click: function(){
63 // Handles when the button is clicked.
67 /**
68 * Handles when the button is clicked.
69 */
64 this.send({event: 'click'});
70 this.send({event: 'click'});
65 },
71 },
66 });
72 });
@@ -15,8 +15,10 b' define(['
15 _range_regex: /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)\s*[-:]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/,
15 _range_regex: /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)\s*[-:]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/,
16
16
17 _validate_slide_value: function(x) {
17 _validate_slide_value: function(x) {
18 // Validate the value of the slider before sending it to the back-end
18 /**
19 // and applying it to the other views on the page.
19 * Validate the value of the slider before sending it to the back-end
20 * and applying it to the other views on the page.
21 */
20 return x;
22 return x;
21 },
23 },
22 });
24 });
@@ -8,16 +8,20 b' define(['
8
8
9 var ImageView = widget.DOMWidgetView.extend({
9 var ImageView = widget.DOMWidgetView.extend({
10 render : function(){
10 render : function(){
11 // Called when view is rendered.
11 /**
12 * Called when view is rendered.
13 */
12 this.setElement($("<img />"));
14 this.setElement($("<img />"));
13 this.update(); // Set defaults.
15 this.update(); // Set defaults.
14 },
16 },
15
17
16 update : function(){
18 update : function(){
17 // Update the contents of this view
19 /**
18 //
20 * Update the contents of this view
19 // Called when the model is changed. The model may have been
21 *
20 // changed by another view or by a state update from the back-end.
22 * Called when the model is changed. The model may have been
23 * changed by another view or by a state update from the back-end.
24 */
21 var image_src = 'data:image/' + this.model.get('format') + ';base64,' + this.model.get('_b64value');
25 var image_src = 'data:image/' + this.model.get('format') + ';base64,' + this.model.get('_b64value');
22 this.$el.attr('src', image_src);
26 this.$el.attr('src', image_src);
23
27
@@ -10,7 +10,9 b' define(['
10
10
11 var IntSliderView = widget.DOMWidgetView.extend({
11 var IntSliderView = widget.DOMWidgetView.extend({
12 render : function(){
12 render : function(){
13 // Called when view is rendered.
13 /**
14 * Called when view is rendered.
15 */
14 this.$el
16 this.$el
15 .addClass('widget-hbox widget-slider');
17 .addClass('widget-hbox widget-slider');
16 this.$label = $('<div />')
18 this.$label = $('<div />')
@@ -43,7 +45,9 b' define(['
43 },
45 },
44
46
45 update_attr: function(name, value) {
47 update_attr: function(name, value) {
46 // Set a css attr of the widget view.
48 /**
49 * Set a css attr of the widget view.
50 */
47 if (name == 'color') {
51 if (name == 'color') {
48 this.$readout.css(name, value);
52 this.$readout.css(name, value);
49 } else if (name.substring(0, 4) == 'font') {
53 } else if (name.substring(0, 4) == 'font') {
@@ -59,10 +63,12 b' define(['
59 },
63 },
60
64
61 update : function(options){
65 update : function(options){
62 // Update the contents of this view
66 /**
63 //
67 * Update the contents of this view
64 // Called when the model is changed. The model may have been
68 *
65 // changed by another view or by a state update from the back-end.
69 * Called when the model is changed. The model may have been
70 * changed by another view or by a state update from the back-end.
71 */
66 if (options === undefined || options.updated_view != this) {
72 if (options === undefined || options.updated_view != this) {
67 // JQuery slider option keys. These keys happen to have a
73 // JQuery slider option keys. These keys happen to have a
68 // one-to-one mapping with the corrosponding keys of the model.
74 // one-to-one mapping with the corrosponding keys of the model.
@@ -179,15 +185,17 b' define(['
179 },
185 },
180
186
181 handleTextChange: function() {
187 handleTextChange: function() {
182 // this handles the entry of text into the contentEditable label
188 /**
183 // first, the value is checked if it contains a parseable number
189 * this handles the entry of text into the contentEditable label
184 // (or pair of numbers, for the _range case)
190 * first, the value is checked if it contains a parseable number
185 // then it is clamped within the min-max range of the slider
191 * (or pair of numbers, for the _range case)
186 // finally, the model is updated if the value is to be changed
192 * then it is clamped within the min-max range of the slider
187 //
193 * finally, the model is updated if the value is to be changed
188 // if any of these conditions are not met, the text is reset
194 *
189 //
195 * if any of these conditions are not met, the text is reset
190 // the step size is not enforced
196 *
197 * the step size is not enforced
198 */
191
199
192 var text = this.$readout.text();
200 var text = this.$readout.text();
193 var vmin = this.model.get('min');
201 var vmin = this.model.get('min');
@@ -245,10 +253,12 b' define(['
245 _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
253 _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
246
254
247 handleSliderChange: function(e, ui) {
255 handleSliderChange: function(e, ui) {
248 // Called when the slider value is changed.
256 /**
249
257 * Called when the slider value is changed.
250 // Calling model.set will trigger all of the other views of the
258 *
251 // model to update.
259 * Calling model.set will trigger all of the other views of the
260 * model to update.
261 */
252 if (this.model.get("_range")) {
262 if (this.model.get("_range")) {
253 var actual_value = ui.values.map(this._validate_slide_value);
263 var actual_value = ui.values.map(this._validate_slide_value);
254 this.$readout.text(actual_value.join("-"));
264 this.$readout.text(actual_value.join("-"));
@@ -261,10 +271,12 b' define(['
261 },
271 },
262
272
263 _validate_slide_value: function(x) {
273 _validate_slide_value: function(x) {
264 // Validate the value of the slider before sending it to the back-end
274 /**
265 // and applying it to the other views on the page.
275 * Validate the value of the slider before sending it to the back-end
266
276 * and applying it to the other views on the page.
267 // Double bit-wise not truncates the decimel (int cast).
277 *
278 * Double bit-wise not truncates the decimel (int cast).
279 */
268 return ~~x;
280 return ~~x;
269 },
281 },
270 });
282 });
@@ -272,7 +284,9 b' define(['
272
284
273 var IntTextView = widget.DOMWidgetView.extend({
285 var IntTextView = widget.DOMWidgetView.extend({
274 render : function(){
286 render : function(){
275 // Called when view is rendered.
287 /**
288 * Called when view is rendered.
289 */
276 this.$el
290 this.$el
277 .addClass('widget-hbox widget-text');
291 .addClass('widget-hbox widget-text');
278 this.$label = $('<div />')
292 this.$label = $('<div />')
@@ -287,10 +301,12 b' define(['
287 },
301 },
288
302
289 update : function(options){
303 update : function(options){
290 // Update the contents of this view
304 /**
291 //
305 * Update the contents of this view
292 // Called when the model is changed. The model may have been
306 *
293 // changed by another view or by a state update from the back-end.
307 * Called when the model is changed. The model may have been
308 * changed by another view or by a state update from the back-end.
309 */
294 if (options === undefined || options.updated_view != this) {
310 if (options === undefined || options.updated_view != this) {
295 var value = this.model.get('value');
311 var value = this.model.get('value');
296 if (this._parse_value(this.$textbox.val()) != value) {
312 if (this._parse_value(this.$textbox.val()) != value) {
@@ -316,7 +332,9 b' define(['
316 },
332 },
317
333
318 update_attr: function(name, value) {
334 update_attr: function(name, value) {
319 // Set a css attr of the widget view.
335 /**
336 * Set a css attr of the widget view.
337 */
320 this.$textbox.css(name, value);
338 this.$textbox.css(name, value);
321 },
339 },
322
340
@@ -331,9 +349,11 b' define(['
331 },
349 },
332
350
333 handleChanging: function(e) {
351 handleChanging: function(e) {
334 // Handles and validates user input.
352 /**
335
353 * Handles and validates user input.
336 // Try to parse value as a int.
354 *
355 * Try to parse value as a int.
356 */
337 var numericalValue = 0;
357 var numericalValue = 0;
338 var trimmed = e.target.value.trim();
358 var trimmed = e.target.value.trim();
339 if (trimmed === '') {
359 if (trimmed === '') {
@@ -367,7 +387,9 b' define(['
367 },
387 },
368
388
369 handleChanged: function(e) {
389 handleChanged: function(e) {
370 // Applies validated input.
390 /**
391 * Applies validated input.
392 */
371 if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
393 if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
372 e.target.value = this.model.get('value');
394 e.target.value = this.model.get('value');
373 }
395 }
@@ -379,7 +401,9 b' define(['
379
401
380 var ProgressView = widget.DOMWidgetView.extend({
402 var ProgressView = widget.DOMWidgetView.extend({
381 render : function(){
403 render : function(){
382 // Called when view is rendered.
404 /**
405 * Called when view is rendered.
406 */
383 this.$el
407 this.$el
384 .addClass('widget-hbox widget-progress');
408 .addClass('widget-hbox widget-progress');
385 this.$label = $('<div />')
409 this.$label = $('<div />')
@@ -403,10 +427,12 b' define(['
403 },
427 },
404
428
405 update : function(){
429 update : function(){
406 // Update the contents of this view
430 /**
407 //
431 * Update the contents of this view
408 // Called when the model is changed. The model may have been
432 *
409 // changed by another view or by a state update from the back-end.
433 * Called when the model is changed. The model may have been
434 * changed by another view or by a state update from the back-end.
435 */
410 var value = this.model.get('value');
436 var value = this.model.get('value');
411 var max = this.model.get('max');
437 var max = this.model.get('max');
412 var min = this.model.get('min');
438 var min = this.model.get('min');
@@ -435,7 +461,9 b' define(['
435 },
461 },
436
462
437 update_attr: function(name, value) {
463 update_attr: function(name, value) {
438 // Set a css attr of the widget view.
464 /**
465 * Set a css attr of the widget view.
466 */
439 if (name.substring(0, 6) == 'border' || name == 'width' ||
467 if (name.substring(0, 6) == 'border' || name == 'width' ||
440 name == 'height' || name == 'background' || name == 'margin' ||
468 name == 'height' || name == 'background' || name == 'margin' ||
441 name == 'padding') {
469 name == 'padding') {
@@ -10,13 +10,17 b' define(['
10
10
11 var OutputView = widget.DOMWidgetView.extend({
11 var OutputView = widget.DOMWidgetView.extend({
12 initialize: function (parameters) {
12 initialize: function (parameters) {
13 // Public constructor
13 /**
14 * Public constructor
15 */
14 OutputView.__super__.initialize.apply(this, [parameters]);
16 OutputView.__super__.initialize.apply(this, [parameters]);
15 this.model.on('msg:custom', this._handle_route_msg, this);
17 this.model.on('msg:custom', this._handle_route_msg, this);
16 },
18 },
17
19
18 render: function(){
20 render: function(){
19 // Called when view is rendered.
21 /**
22 * Called when view is rendered.
23 */
20 this.output_area = new outputarea.OutputArea({
24 this.output_area = new outputarea.OutputArea({
21 selector: this.$el,
25 selector: this.$el,
22 prompt_area: false,
26 prompt_area: false,
@@ -10,7 +10,9 b' define(['
10
10
11 var DropdownView = widget.DOMWidgetView.extend({
11 var DropdownView = widget.DOMWidgetView.extend({
12 render : function(){
12 render : function(){
13 // Called when view is rendered.
13 /**
14 * Called when view is rendered.
15 */
14 this.$el
16 this.$el
15 .addClass('widget-hbox widget-dropdown');
17 .addClass('widget-hbox widget-dropdown');
16 this.$label = $('<div />')
18 this.$label = $('<div />')
@@ -47,10 +49,12 b' define(['
47 },
49 },
48
50
49 update : function(options){
51 update : function(options){
50 // Update the contents of this view
52 /**
51 //
53 * Update the contents of this view
52 // Called when the model is changed. The model may have been
54 *
53 // changed by another view or by a state update from the back-end.
55 * Called when the model is changed. The model may have been
56 * changed by another view or by a state update from the back-end.
57 */
54
58
55 if (options === undefined || options.updated_view != this) {
59 if (options === undefined || options.updated_view != this) {
56 var selected_item_text = this.model.get('value_name');
60 var selected_item_text = this.model.get('value_name');
@@ -114,7 +118,9 b' define(['
114 },
118 },
115
119
116 update_attr: function(name, value) {
120 update_attr: function(name, value) {
117 // Set a css attr of the widget view.
121 /**
122 * Set a css attr of the widget view.
123 */
118 if (name.substring(0, 6) == 'border' || name == 'background' || name == 'color') {
124 if (name.substring(0, 6) == 'border' || name == 'background' || name == 'color') {
119 this.$droplabel.css(name, value);
125 this.$droplabel.css(name, value);
120 this.$dropbutton.css(name, value);
126 this.$dropbutton.css(name, value);
@@ -137,10 +143,12 b' define(['
137 },
143 },
138
144
139 handle_click: function (e) {
145 handle_click: function (e) {
140 // Handle when a value is clicked.
146 /**
141
147 * Handle when a value is clicked.
142 // Calling model.set will trigger all of the other views of the
148 *
143 // model to update.
149 * Calling model.set will trigger all of the other views of the
150 * model to update.
151 */
144 this.model.set('value_name', $(e.target).text(), {updated_view: this});
152 this.model.set('value_name', $(e.target).text(), {updated_view: this});
145 this.touch();
153 this.touch();
146 },
154 },
@@ -150,7 +158,9 b' define(['
150
158
151 var RadioButtonsView = widget.DOMWidgetView.extend({
159 var RadioButtonsView = widget.DOMWidgetView.extend({
152 render : function(){
160 render : function(){
153 // Called when view is rendered.
161 /**
162 * Called when view is rendered.
163 */
154 this.$el
164 this.$el
155 .addClass('widget-hbox widget-radio');
165 .addClass('widget-hbox widget-radio');
156 this.$label = $('<div />')
166 this.$label = $('<div />')
@@ -164,10 +174,12 b' define(['
164 },
174 },
165
175
166 update : function(options){
176 update : function(options){
167 // Update the contents of this view
177 /**
168 //
178 * Update the contents of this view
169 // Called when the model is changed. The model may have been
179 *
170 // changed by another view or by a state update from the back-end.
180 * Called when the model is changed. The model may have been
181 * changed by another view or by a state update from the back-end.
182 */
171 if (options === undefined || options.updated_view != this) {
183 if (options === undefined || options.updated_view != this) {
172 // Add missing items to the DOM.
184 // Add missing items to the DOM.
173 var items = this.model.get('value_names');
185 var items = this.model.get('value_names');
@@ -227,15 +239,19 b' define(['
227 },
239 },
228
240
229 update_attr: function(name, value) {
241 update_attr: function(name, value) {
230 // Set a css attr of the widget view.
242 /**
243 * Set a css attr of the widget view.
244 */
231 this.$container.css(name, value);
245 this.$container.css(name, value);
232 },
246 },
233
247
234 handle_click: function (e) {
248 handle_click: function (e) {
235 // Handle when a value is clicked.
249 /**
236
250 * Handle when a value is clicked.
237 // Calling model.set will trigger all of the other views of the
251 *
238 // model to update.
252 * Calling model.set will trigger all of the other views of the
253 * model to update.
254 */
239 this.model.set('value_name', $(e.target).val(), {updated_view: this});
255 this.model.set('value_name', $(e.target).val(), {updated_view: this});
240 this.touch();
256 this.touch();
241 },
257 },
@@ -249,7 +265,9 b' define(['
249 },
265 },
250
266
251 render: function() {
267 render: function() {
252 // Called when view is rendered.
268 /**
269 * Called when view is rendered.
270 */
253 this.$el
271 this.$el
254 .addClass('widget-hbox widget-toggle-buttons');
272 .addClass('widget-hbox widget-toggle-buttons');
255 this.$label = $('<div />')
273 this.$label = $('<div />')
@@ -269,10 +287,12 b' define(['
269 },
287 },
270
288
271 update : function(options){
289 update : function(options){
272 // Update the contents of this view
290 /**
273 //
291 * Update the contents of this view
274 // Called when the model is changed. The model may have been
292 *
275 // changed by another view or by a state update from the back-end.
293 * Called when the model is changed. The model may have been
294 * changed by another view or by a state update from the back-end.
295 */
276 if (options === undefined || options.updated_view != this) {
296 if (options === undefined || options.updated_view != this) {
277 // Add missing items to the DOM.
297 // Add missing items to the DOM.
278 var items = this.model.get('value_names');
298 var items = this.model.get('value_names');
@@ -334,7 +354,9 b' define(['
334 },
354 },
335
355
336 update_attr: function(name, value) {
356 update_attr: function(name, value) {
337 // Set a css attr of the widget view.
357 /**
358 * Set a css attr of the widget view.
359 */
338 this._css_state[name] = value;
360 this._css_state[name] = value;
339 this.update_style_traits();
361 this.update_style_traits();
340 },
362 },
@@ -367,10 +389,12 b' define(['
367 },
389 },
368
390
369 handle_click: function (e) {
391 handle_click: function (e) {
370 // Handle when a value is clicked.
392 /**
371
393 * Handle when a value is clicked.
372 // Calling model.set will trigger all of the other views of the
394 *
373 // model to update.
395 * Calling model.set will trigger all of the other views of the
396 * model to update.
397 */
374 this.model.set('value_name', $(e.target).data('value'), {updated_view: this});
398 this.model.set('value_name', $(e.target).data('value'), {updated_view: this});
375 this.touch();
399 this.touch();
376 },
400 },
@@ -379,7 +403,9 b' define(['
379
403
380 var SelectView = widget.DOMWidgetView.extend({
404 var SelectView = widget.DOMWidgetView.extend({
381 render : function(){
405 render : function(){
382 // Called when view is rendered.
406 /**
407 * Called when view is rendered.
408 */
383 this.$el
409 this.$el
384 .addClass('widget-hbox widget-select');
410 .addClass('widget-hbox widget-select');
385 this.$label = $('<div />')
411 this.$label = $('<div />')
@@ -394,10 +420,12 b' define(['
394 },
420 },
395
421
396 update : function(options){
422 update : function(options){
397 // Update the contents of this view
423 /**
398 //
424 * Update the contents of this view
399 // Called when the model is changed. The model may have been
425 *
400 // changed by another view or by a state update from the back-end.
426 * Called when the model is changed. The model may have been
427 * changed by another view or by a state update from the back-end.
428 */
401 if (options === undefined || options.updated_view != this) {
429 if (options === undefined || options.updated_view != this) {
402 // Add missing items to the DOM.
430 // Add missing items to the DOM.
403 var items = this.model.get('value_names');
431 var items = this.model.get('value_names');
@@ -449,15 +477,19 b' define(['
449 },
477 },
450
478
451 update_attr: function(name, value) {
479 update_attr: function(name, value) {
452 // Set a css attr of the widget view.
480 /**
481 * Set a css attr of the widget view.
482 */
453 this.$listbox.css(name, value);
483 this.$listbox.css(name, value);
454 },
484 },
455
485
456 handle_click: function (e) {
486 handle_click: function (e) {
457 // Handle when a value is clicked.
487 /**
458
488 * Handle when a value is clicked.
459 // Calling model.set will trigger all of the other views of the
489 *
460 // model to update.
490 * Calling model.set will trigger all of the other views of the
491 * model to update.
492 */
461 this.model.set('value_name', $(e.target).text(), {updated_view: this});
493 this.model.set('value_name', $(e.target).text(), {updated_view: this});
462 this.touch();
494 this.touch();
463 },
495 },
@@ -21,7 +21,9 b' define(['
21 },
21 },
22
22
23 render: function(){
23 render: function(){
24 // Called when view is rendered.
24 /**
25 * Called when view is rendered.
26 */
25 var guid = 'panel-group' + utils.uuid();
27 var guid = 'panel-group' + utils.uuid();
26 this.$el
28 this.$el
27 .attr('id', guid)
29 .attr('id', guid)
@@ -40,7 +42,9 b' define(['
40 },
42 },
41
43
42 update_titles: function(titles) {
44 update_titles: function(titles) {
43 // Set tab titles
45 /**
46 * Set tab titles
47 */
44 if (!titles) {
48 if (!titles) {
45 titles = this.model.get('_titles');
49 titles = this.model.get('_titles');
46 }
50 }
@@ -58,8 +62,10 b' define(['
58 },
62 },
59
63
60 update_selected_index: function(old_index, new_index, options) {
64 update_selected_index: function(old_index, new_index, options) {
61 // Only update the selection if the selection wasn't triggered
65 /**
62 // by the front-end. It must be triggered by the back-end.
66 * Only update the selection if the selection wasn't triggered
67 * by the front-end. It must be triggered by the back-end.
68 */
63 if (options === undefined || options.updated_view != this) {
69 if (options === undefined || options.updated_view != this) {
64 this.containers[old_index].find('.panel-collapse').collapse('hide');
70 this.containers[old_index].find('.panel-collapse').collapse('hide');
65 if (0 <= new_index && new_index < this.containers.length) {
71 if (0 <= new_index && new_index < this.containers.length) {
@@ -69,8 +75,10 b' define(['
69 },
75 },
70
76
71 remove_child_view: function(view) {
77 remove_child_view: function(view) {
72 // Called when a child is removed from children list.
78 /**
73 // TODO: does this handle two different views of the same model as children?
79 * Called when a child is removed from children list.
80 * TODO: does this handle two different views of the same model as children?
81 */
74 var model = view.model;
82 var model = view.model;
75 var accordion_group = this.model_containers[model.id];
83 var accordion_group = this.model_containers[model.id];
76 this.containers.splice(accordion_group.container_index, 1);
84 this.containers.splice(accordion_group.container_index, 1);
@@ -79,7 +87,9 b' define(['
79 },
87 },
80
88
81 add_child_view: function(model) {
89 add_child_view: function(model) {
82 // Called when a child is added to children list.
90 /**
91 * Called when a child is added to children list.
92 */
83 var index = this.containers.length;
93 var index = this.containers.length;
84 var uuid = utils.uuid();
94 var uuid = utils.uuid();
85 var accordion_group = $('<div />')
95 var accordion_group = $('<div />')
@@ -129,9 +139,11 b' define(['
129 },
139 },
130
140
131 remove: function() {
141 remove: function() {
132 // We remove this widget before removing the children as an optimization
142 /**
133 // we want to remove the entire container from the DOM first before
143 * We remove this widget before removing the children as an optimization
134 // removing each individual child separately.
144 * we want to remove the entire container from the DOM first before
145 * removing each individual child separately.
146 */
135 AccordionView.__super__.remove.apply(this, arguments);
147 AccordionView.__super__.remove.apply(this, arguments);
136 this.children_views.remove();
148 this.children_views.remove();
137 },
149 },
@@ -140,7 +152,9 b' define(['
140
152
141 var TabView = widget.DOMWidgetView.extend({
153 var TabView = widget.DOMWidgetView.extend({
142 initialize: function() {
154 initialize: function() {
143 // Public constructor.
155 /**
156 * Public constructor.
157 */
144 TabView.__super__.initialize.apply(this, arguments);
158 TabView.__super__.initialize.apply(this, arguments);
145
159
146 this.containers = [];
160 this.containers = [];
@@ -151,7 +165,9 b' define(['
151 },
165 },
152
166
153 render: function(){
167 render: function(){
154 // Called when view is rendered.
168 /**
169 * Called when view is rendered.
170 */
155 var uuid = 'tabs'+utils.uuid();
171 var uuid = 'tabs'+utils.uuid();
156 var that = this;
172 var that = this;
157 this.$tabs = $('<div />', {id: uuid})
173 this.$tabs = $('<div />', {id: uuid})
@@ -165,12 +181,16 b' define(['
165 },
181 },
166
182
167 update_attr: function(name, value) {
183 update_attr: function(name, value) {
168 // Set a css attr of the widget view.
184 /**
185 * Set a css attr of the widget view.
186 */
169 this.$tabs.css(name, value);
187 this.$tabs.css(name, value);
170 },
188 },
171
189
172 remove_child_view: function(view) {
190 remove_child_view: function(view) {
173 // Called when a child is removed from children list.
191 /**
192 * Called when a child is removed from children list.
193 */
174 this.containers.splice(view.parent_tab.tab_text_index, 1);
194 this.containers.splice(view.parent_tab.tab_text_index, 1);
175 view.parent_tab.remove();
195 view.parent_tab.remove();
176 view.parent_container.remove();
196 view.parent_container.remove();
@@ -178,7 +198,9 b' define(['
178 },
198 },
179
199
180 add_child_view: function(model) {
200 add_child_view: function(model) {
181 // Called when a child is added to children list.
201 /**
202 * Called when a child is added to children list.
203 */
182 var index = this.containers.length;
204 var index = this.containers.length;
183 var uuid = utils.uuid();
205 var uuid = utils.uuid();
184
206
@@ -224,10 +246,12 b' define(['
224 },
246 },
225
247
226 update: function(options) {
248 update: function(options) {
227 // Update the contents of this view
249 /**
228 //
250 * Update the contents of this view
229 // Called when the model is changed. The model may have been
251 *
230 // changed by another view or by a state update from the back-end.
252 * Called when the model is changed. The model may have been
253 * changed by another view or by a state update from the back-end.
254 */
231 if (options === undefined || options.updated_view != this) {
255 if (options === undefined || options.updated_view != this) {
232 // Set tab titles
256 // Set tab titles
233 var titles = this.model.get('_titles');
257 var titles = this.model.get('_titles');
@@ -248,16 +272,20 b' define(['
248 },
272 },
249
273
250 select_page: function(index) {
274 select_page: function(index) {
251 // Select a page.
275 /**
276 * Select a page.
277 */
252 this.$tabs.find('li')
278 this.$tabs.find('li')
253 .removeClass('active');
279 .removeClass('active');
254 this.containers[index].tab('show');
280 this.containers[index].tab('show');
255 },
281 },
256
282
257 remove: function() {
283 remove: function() {
258 // We remove this widget before removing the children as an optimization
284 /**
259 // we want to remove the entire container from the DOM first before
285 * We remove this widget before removing the children as an optimization
260 // removing each individual child separately.
286 * we want to remove the entire container from the DOM first before
287 * removing each individual child separately.
288 */
261 TabView.__super__.remove.apply(this, arguments);
289 TabView.__super__.remove.apply(this, arguments);
262 this.children_views.remove();
290 this.children_views.remove();
263 },
291 },
@@ -9,15 +9,19 b' define(['
9
9
10 var HTMLView = widget.DOMWidgetView.extend({
10 var HTMLView = widget.DOMWidgetView.extend({
11 render : function(){
11 render : function(){
12 // Called when view is rendered.
12 /**
13 * Called when view is rendered.
14 */
13 this.update(); // Set defaults.
15 this.update(); // Set defaults.
14 },
16 },
15
17
16 update : function(){
18 update : function(){
17 // Update the contents of this view
19 /**
18 //
20 * Update the contents of this view
19 // Called when the model is changed. The model may have been
21 *
20 // changed by another view or by a state update from the back-end.
22 * Called when the model is changed. The model may have been
23 * changed by another view or by a state update from the back-end.
24 */
21 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
25 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
22 return HTMLView.__super__.update.apply(this);
26 return HTMLView.__super__.update.apply(this);
23 },
27 },
@@ -26,15 +30,19 b' define(['
26
30
27 var LatexView = widget.DOMWidgetView.extend({
31 var LatexView = widget.DOMWidgetView.extend({
28 render : function(){
32 render : function(){
29 // Called when view is rendered.
33 /**
34 * Called when view is rendered.
35 */
30 this.update(); // Set defaults.
36 this.update(); // Set defaults.
31 },
37 },
32
38
33 update : function(){
39 update : function(){
34 // Update the contents of this view
40 /**
35 //
41 * Update the contents of this view
36 // Called when the model is changed. The model may have been
42 *
37 // changed by another view or by a state update from the back-end.
43 * Called when the model is changed. The model may have been
44 * changed by another view or by a state update from the back-end.
45 */
38 this.$el.text(this.model.get('value'));
46 this.$el.text(this.model.get('value'));
39 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
47 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
40
48
@@ -45,7 +53,9 b' define(['
45
53
46 var TextareaView = widget.DOMWidgetView.extend({
54 var TextareaView = widget.DOMWidgetView.extend({
47 render: function(){
55 render: function(){
48 // Called when view is rendered.
56 /**
57 * Called when view is rendered.
58 */
49 this.$el
59 this.$el
50 .addClass('widget-hbox widget-textarea');
60 .addClass('widget-hbox widget-textarea');
51 this.$label = $('<div />')
61 this.$label = $('<div />')
@@ -67,7 +77,9 b' define(['
67 },
77 },
68
78
69 _handle_textarea_msg: function (content){
79 _handle_textarea_msg: function (content){
70 // Handle when a custom msg is recieved from the back-end.
80 /**
81 * Handle when a custom msg is recieved from the back-end.
82 */
71 if (content.method == "scroll_to_bottom") {
83 if (content.method == "scroll_to_bottom") {
72 this.scroll_to_bottom();
84 this.scroll_to_bottom();
73 }
85 }
@@ -81,15 +93,19 b' define(['
81 },
93 },
82
94
83 scroll_to_bottom: function (){
95 scroll_to_bottom: function (){
84 // Scroll the text-area view to the bottom.
96 /**
97 * Scroll the text-area view to the bottom.
98 */
85 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
99 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
86 },
100 },
87
101
88 update: function(options){
102 update: function(options){
89 // Update the contents of this view
103 /**
90 //
104 * Update the contents of this view
91 // Called when the model is changed. The model may have been
105 *
92 // changed by another view or by a state update from the back-end.
106 * Called when the model is changed. The model may have been
107 * changed by another view or by a state update from the back-end.
108 */
93 if (options === undefined || options.updated_view != this) {
109 if (options === undefined || options.updated_view != this) {
94 this.$textbox.val(this.model.get('value'));
110 this.$textbox.val(this.model.get('value'));
95
111
@@ -109,7 +125,9 b' define(['
109 },
125 },
110
126
111 update_attr: function(name, value) {
127 update_attr: function(name, value) {
112 // Set a css attr of the widget view.
128 /**
129 * Set a css attr of the widget view.
130 */
113 this.$textbox.css(name, value);
131 this.$textbox.css(name, value);
114 },
132 },
115
133
@@ -121,10 +139,12 b' define(['
121 },
139 },
122
140
123 handleChanging: function(e) {
141 handleChanging: function(e) {
124 // Handles and validates user input.
142 /**
125
143 * Handles and validates user input.
126 // Calling model.set will trigger all of the other views of the
144 *
127 // model to update.
145 * Calling model.set will trigger all of the other views of the
146 * model to update.
147 */
128 this.model.set('value', e.target.value, {updated_view: this});
148 this.model.set('value', e.target.value, {updated_view: this});
129 this.touch();
149 this.touch();
130 },
150 },
@@ -133,7 +153,9 b' define(['
133
153
134 var TextView = widget.DOMWidgetView.extend({
154 var TextView = widget.DOMWidgetView.extend({
135 render: function(){
155 render: function(){
136 // Called when view is rendered.
156 /**
157 * Called when view is rendered.
158 */
137 this.$el
159 this.$el
138 .addClass('widget-hbox widget-text');
160 .addClass('widget-hbox widget-text');
139 this.$label = $('<div />')
161 this.$label = $('<div />')
@@ -160,10 +182,12 b' define(['
160 },
182 },
161
183
162 update: function(options){
184 update: function(options){
163 // Update the contents of this view
185 /**
164 //
186 * Update the contents of this view
165 // Called when the model is changed. The model may have been
187 *
166 // changed by another view or by a state update from the back-end.
188 * Called when the model is changed. The model may have been
189 * changed by another view or by a state update from the back-end.
190 */
167 if (options === undefined || options.updated_view != this) {
191 if (options === undefined || options.updated_view != this) {
168 if (this.$textbox.val() != this.model.get('value')) {
192 if (this.$textbox.val() != this.model.get('value')) {
169 this.$textbox.val(this.model.get('value'));
193 this.$textbox.val(this.model.get('value'));
@@ -185,7 +209,9 b' define(['
185 },
209 },
186
210
187 update_attr: function(name, value) {
211 update_attr: function(name, value) {
188 // Set a css attr of the widget view.
212 /**
213 * Set a css attr of the widget view.
214 */
189 this.$textbox.css(name, value);
215 this.$textbox.css(name, value);
190 },
216 },
191
217
@@ -200,16 +226,20 b' define(['
200 },
226 },
201
227
202 handleChanging: function(e) {
228 handleChanging: function(e) {
203 // Handles user input.
229 /**
204
230 * Handles user input.
205 // Calling model.set will trigger all of the other views of the
231 *
206 // model to update.
232 * Calling model.set will trigger all of the other views of the
233 * model to update.
234 */
207 this.model.set('value', e.target.value, {updated_view: this});
235 this.model.set('value', e.target.value, {updated_view: this});
208 this.touch();
236 this.touch();
209 },
237 },
210
238
211 handleKeypress: function(e) {
239 handleKeypress: function(e) {
212 // Handles text submition
240 /**
241 * Handles text submition
242 */
213 if (e.keyCode == 13) { // Return key
243 if (e.keyCode == 13) { // Return key
214 this.send({event: 'submit'});
244 this.send({event: 'submit'});
215 e.stopPropagation();
245 e.stopPropagation();
@@ -219,10 +249,12 b' define(['
219 },
249 },
220
250
221 handleBlur: function(e) {
251 handleBlur: function(e) {
222 // Prevent a blur from firing if the blur was not user intended.
252 /**
223 // This is a workaround for the return-key focus loss bug.
253 * Prevent a blur from firing if the blur was not user intended.
224 // TODO: Is the original bug actually a fault of the keyboard
254 * This is a workaround for the return-key focus loss bug.
225 // manager?
255 * TODO: Is the original bug actually a fault of the keyboard
256 * manager?
257 */
226 if (e.relatedTarget === null) {
258 if (e.relatedTarget === null) {
227 e.stopPropagation();
259 e.stopPropagation();
228 e.preventDefault();
260 e.preventDefault();
@@ -231,8 +263,10 b' define(['
231 },
263 },
232
264
233 handleFocusOut: function(e) {
265 handleFocusOut: function(e) {
234 // Prevent a blur from firing if the blur was not user intended.
266 /**
235 // This is a workaround for the return-key focus loss bug.
267 * Prevent a blur from firing if the blur was not user intended.
268 * This is a workaround for the return-key focus loss bug.
269 */
236 if (e.relatedTarget === null) {
270 if (e.relatedTarget === null) {
237 e.stopPropagation();
271 e.stopPropagation();
238 e.preventDefault();
272 e.preventDefault();
General Comments 0
You need to be logged in to leave comments. Login now