##// END OF EJS Templates
fix bug in stale profile clean up for clusters...
fix bug in stale profile clean up for clusters "clusters" tab of my notebook wasn't rendering, so checked the log, found the stack trace: ``` [...] File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/handlers.py", line 21, in get self.finish(json.dumps(self.cluster_manager.list_profiles())) File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/clustermanager.py", line 77, in list_profiles self.update_profiles() File "/usr/local/lib/python3.4/site-packages/ipython-3.0.0-py3.4.egg/IPython/html/services/clusters/clustermanager.py", line 74, in update_profiles self.profiles.pop(stale) TypeError: unhashable type: 'set' ``` looks like a pretty straightforward mistake

File last commit:

r21208:e65db1aa
r21236:10a376e0
Show More
textcell.js
374 lines | 11.7 KiB | application/javascript | JavascriptLexer
// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
define([
'base/js/namespace',
'base/js/utils',
'jquery',
'notebook/js/cell',
'base/js/security',
'services/config',
'notebook/js/mathjaxutils',
'notebook/js/celltoolbar',
'components/marked/lib/marked',
'codemirror/lib/codemirror',
'codemirror/mode/gfm/gfm',
'notebook/js/codemirror-ipythongfm'
], function(IPython,
utils,
$,
cell,
security,
configmod,
mathjaxutils,
celltoolbar,
marked,
CodeMirror,
gfm,
ipgfm
) {
"use strict";
var Cell = cell.Cell;
var TextCell = function (options) {
/**
* Constructor
*
* Construct a new TextCell, codemirror mode is by default 'htmlmixed',
* and cell type is 'text' cell start as not redered.
*
* Parameters:
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
* config: dictionary
* keyboard_manager: KeyboardManager instance
* notebook: Notebook instance
*/
options = options || {};
// in all TextCell/Cell subclasses
// do not assign most of members here, just pass it down
// in the options dict potentially overwriting what you wish.
// they will be assigned in the base class.
this.notebook = options.notebook;
this.events = options.events;
this.config = options.config;
// we cannot put this as a class key as it has handle to "this".
var config = utils.mergeopt(TextCell, this.config);
Cell.apply(this, [{
config: config,
keyboard_manager: options.keyboard_manager,
events: this.events}]);
this.cell_type = this.cell_type || 'text';
mathjaxutils = mathjaxutils;
this.rendered = false;
};
TextCell.prototype = Object.create(Cell.prototype);
TextCell.options_default = {
cm_config : {
extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
mode: 'htmlmixed',
lineWrapping : true,
}
};
/**
* Create the DOM element of the TextCell
* @method create_element
* @private
*/
TextCell.prototype.create_element = function () {
Cell.prototype.create_element.apply(this, arguments);
var that = this;
var cell = $("<div>").addClass('cell text_cell');
cell.attr('tabindex','2');
var prompt = $('<div/>').addClass('prompt input_prompt');
cell.append(prompt);
var inner_cell = $('<div/>').addClass('inner_cell');
this.celltoolbar = new celltoolbar.CellToolbar({
cell: this,
notebook: this.notebook});
inner_cell.append(this.celltoolbar.element);
var input_area = $('<div/>').addClass('input_area');
this.code_mirror = new CodeMirror(input_area.get(0), this.cm_config);
// In case of bugs that put the keyboard manager into an inconsistent state,
// ensure KM is enabled when CodeMirror is focused:
this.code_mirror.on('focus', function () {
if (that.keyboard_manager) {
that.keyboard_manager.enable();
}
});
this.code_mirror.on('keydown', $.proxy(this.handle_keyevent,this))
// The tabindex=-1 makes this div focusable.
var render_area = $('<div/>').addClass('text_cell_render rendered_html')
.attr('tabindex','-1');
inner_cell.append(input_area).append(render_area);
cell.append(inner_cell);
this.element = cell;
};
// Cell level actions
TextCell.prototype.select = function () {
var cont = Cell.prototype.select.apply(this);
if (cont) {
if (this.mode === 'edit') {
this.code_mirror.refresh();
}
}
return cont;
};
TextCell.prototype.unrender = function () {
var cont = Cell.prototype.unrender.apply(this);
if (cont) {
var text_cell = this.element;
if (this.get_text() === this.placeholder) {
this.set_text('');
}
this.refresh();
}
return cont;
};
TextCell.prototype.execute = function () {
this.render();
};
/**
* setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
* @method get_text
* @retrun {string} CodeMirror current text value
*/
TextCell.prototype.get_text = function() {
return this.code_mirror.getValue();
};
/**
* @param {string} text - Codemiror text value
* @see TextCell#get_text
* @method set_text
* */
TextCell.prototype.set_text = function(text) {
this.code_mirror.setValue(text);
this.unrender();
this.code_mirror.refresh();
};
/**
* setter :{{#crossLink "TextCell/set_rendered"}}{{/crossLink}}
* @method get_rendered
* */
TextCell.prototype.get_rendered = function() {
return this.element.find('div.text_cell_render').html();
};
/**
* @method set_rendered
*/
TextCell.prototype.set_rendered = function(text) {
this.element.find('div.text_cell_render').html(text);
};
/**
* Create Text cell from JSON
* @param {json} data - JSON serialized text-cell
* @method fromJSON
*/
TextCell.prototype.fromJSON = function (data) {
Cell.prototype.fromJSON.apply(this, arguments);
if (data.cell_type === this.cell_type) {
if (data.source !== undefined) {
this.set_text(data.source);
// make this value the starting point, so that we can only undo
// to this state, instead of a blank cell
this.code_mirror.clearHistory();
// TODO: This HTML needs to be treated as potentially dangerous
// user input and should be handled before set_rendered.
this.set_rendered(data.rendered || '');
this.rendered = false;
this.render();
}
}
};
/** Generate JSON from cell
* @return {object} cell data serialised to json
*/
TextCell.prototype.toJSON = function () {
var data = Cell.prototype.toJSON.apply(this);
data.source = this.get_text();
if (data.source == this.placeholder) {
data.source = "";
}
return data;
};
var MarkdownCell = function (options) {
/**
* Constructor
*
* Parameters:
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
* config: ConfigSection instance
* keyboard_manager: KeyboardManager instance
* notebook: Notebook instance
*/
options = options || {};
var config = utils.mergeopt(MarkdownCell, {});
this.class_config = new configmod.ConfigWithDefaults(options.config,
{}, 'MarkdownCell');
TextCell.apply(this, [$.extend({}, options, {config: config})]);
this.cell_type = 'markdown';
};
MarkdownCell.options_default = {
cm_config: {
mode: 'ipythongfm'
},
placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
};
MarkdownCell.prototype = Object.create(TextCell.prototype);
MarkdownCell.prototype.set_heading_level = function (level) {
/**
* make a markdown cell a heading
*/
level = level || 1;
var source = this.get_text();
source = source.replace(/^(#*)\s?/,
new Array(level + 1).join('#') + ' ');
this.set_text(source);
this.refresh();
if (this.rendered) {
this.render();
}
};
/**
* @method render
*/
MarkdownCell.prototype.render = function () {
var cont = TextCell.prototype.render.apply(this);
if (cont) {
var that = this;
var text = this.get_text();
var math = null;
if (text === "") { text = this.placeholder; }
var text_and_math = mathjaxutils.remove_math(text);
text = text_and_math[0];
math = text_and_math[1];
marked(text, function (err, html) {
html = mathjaxutils.replace_math(html, math);
html = security.sanitize_html(html);
html = $($.parseHTML(html));
// add anchors to headings
html.find(":header").addBack(":header").each(function (i, h) {
h = $(h);
var hash = h.text().replace(/ /g, '-');
h.attr('id', hash);
h.append(
$('<a/>')
.addClass('anchor-link')
.attr('href', '#' + hash)
.text('ΒΆ')
);
});
// links in markdown cells should open in new tabs
html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
that.set_rendered(html);
that.typeset();
that.events.trigger("rendered.MarkdownCell", {cell: that});
});
}
return cont;
};
var RawCell = function (options) {
/**
* Constructor
*
* Parameters:
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
* config: ConfigSection instance
* keyboard_manager: KeyboardManager instance
* notebook: Notebook instance
*/
options = options || {};
var config = utils.mergeopt(RawCell, {});
TextCell.apply(this, [$.extend({}, options, {config: config})]);
this.class_config = new configmod.ConfigWithDefaults(options.config,
RawCell.config_defaults, 'RawCell');
this.cell_type = 'raw';
};
RawCell.options_default = {
placeholder : "Write raw LaTeX or other formats here, for use with nbconvert. " +
"It will not be rendered in the notebook. " +
"When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
};
RawCell.config_defaults = {
highlight_modes : {
'diff' :{'reg':[/^diff/]}
},
};
RawCell.prototype = Object.create(TextCell.prototype);
/** @method bind_events **/
RawCell.prototype.bind_events = function () {
TextCell.prototype.bind_events.apply(this);
var that = this;
this.element.focusout(function() {
that.auto_highlight();
that.render();
});
this.code_mirror.on('focus', function() { that.unrender(); });
};
/** @method render **/
RawCell.prototype.render = function () {
var cont = TextCell.prototype.render.apply(this);
if (cont){
var text = this.get_text();
if (text === "") { text = this.placeholder; }
this.set_text(text);
this.element.removeClass('rendered');
this.auto_highlight();
}
return cont;
};
// Backwards compatability.
IPython.TextCell = TextCell;
IPython.MarkdownCell = MarkdownCell;
IPython.RawCell = RawCell;
var textcell = {
TextCell: TextCell,
MarkdownCell: MarkdownCell,
RawCell: RawCell
};
return textcell;
});