//---------------------------------------------------------------------------- // Copyright (C) 2012 The IPython Development Team // // Distributed under the terms of the BSD License. The full license is in // the file COPYING, distributed as part of this software. //---------------------------------------------------------------------------- //============================================================================ // MetaUI //============================================================================ /** * A Module to control the per-cell toolbar. * @module IPython * @namespace IPython * @submodule MetaUI */ var IPython = (function (IPython) { "use strict"; /** * @constructor * @class MetaUI * @param {The cell to attach the metadata UI to} cell */ var MetaUI = function (cell) { MetaUI._instances.push(this); this.metainner = $('
'); this.cell = cell; this.element = $('
').addClass('metaedit') .append(this.metainner) this.rebuild(); return this; }; /** * Class variable that should contain a dict of all availlable callback * we need to think of wether or not we allow nested namespace * @property _callback_dict * @private */ MetaUI._callback_dict = {}; /** * Class variable that should contain the reverse order list of the button * to add to the toolbar of each cell * @property _button_list * @private */ MetaUI._button_list = []; /** * keep a list of all instances to * be able to llop over them... * but how to 'destroy' them ? * have to think about it... * or loop over the cells, and find their MetaUI instances. * @private * @property _instances */ MetaUI._instances =[] /** * keep a list of all the availlabel presets for the toolbar * @private * @property _presets */ MetaUI._presets ={} // this is by design not a prototype. /** * Register a callback to create an UI element in a cell toolbar. * @method register_callback * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name * for easier sorting and avoid collision * @param callback {function(div, cell)} callback that will be called to generate the ui element * * * The callback will receive the following element : * * * a div in which to add element. * * the cell it is responsable from * * @example * * Example that create callback for a button that toggle between `true` and `false` label, * with the metadata under the key 'foo' to reflect the status of the button. * * // first param reference to a DOM div * // second param reference to the cell. * var toggle = function(div, cell) { * var button_container = $(div) * * // let's create a button that show the current value of the metadata * var button = $('
').button({label:String(cell.metadata.foo)}); * * // On click, change the metadata value and update the button label * button.click(function(){ * var v = cell.metadata.foo; * cell.metadata.foo = !v; * button.button("option","label",String(!v)); * }) * * // add the button to the DOM div. * button_container.append(button); * } * * // now we register the callback under the name `foo` to give the * // user the ability to use it later * MetaUI.register_callback('foo',toggle); */ MetaUI.register_callback = function(name, callback){ // what do we do if name already exist ? MetaUI._callback_dict[name] = callback; }; /** * Register a preset of UI element in a cell toolbar. * Not supported Yet. * @method register_preset * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name * for easier sorting and avoid collision * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list * should correspond to a name of a registerd callback. * * @private * @example * * MetaUI.register_callback('foo.c1',function(div,cell){...}); * MetaUI.register_callback('foo.c2',function(div,cell){...}); * MetaUI.register_callback('foo.c3',function(div,cell){...}); * MetaUI.register_callback('foo.c4',function(div,cell){...}); * MetaUI.register_callback('foo.c5',function(div,cell){...}); * * MetaUI.register_preset('foo.foo_preset1',['foo.c1','foo.c2','foo.c5']) * MetaUI.register_preset('foo.foo_preset2',['foo.c4','foo.c5']) */ MetaUI.register_preset = function(name, preset_list){ MetaUI._presets[name] = preset_list } /** * set an UI preset from `register_preset` * @method set_preset * @param preset_name {String} string corresponding to the preset name * * @static * @private * @example * * MetaUI.set_preset('foo.foo_preset1'); */ MetaUI.set_preset= function(preset_name){ var preset = MetaUI._presets[preset_name]; if(preset != undefined){ MetaUI._button_list = preset; MetaUI.rebuild_all(); } } // this is by design not a prototype. /** * This should be called on the class and not on a instance as it will trigger * rebuild of all the instances. * @method rebuild_all * @static * */ MetaUI.rebuild_all = function(){ for(var i in MetaUI._instances){ MetaUI._instances[i].rebuild(); } } /** * Rebuild all the button on the toolbar to update it's state. * @method rebuild */ MetaUI.prototype.rebuild = function(){ // strip evrything from the div // which is probabli metainner. // or this.element. this.metainner.empty(); //this.add_raw_edit_button() var cdict = MetaUI._callback_dict; var preset = MetaUI._button_list; // Yes we iterate on the class varaible, not the instance one. for ( var index in MetaUI._button_list){ var local_div = $('
').addClass('button_container'); // Note, // do this the other way, wrap in try/catch and don't append if any errors. this.metainner.append(local_div) cdict[preset[index]](local_div,this.cell) } } var raw_edit = function(cell){ var md = cell.metadata var textarea = $('