diff --git a/.gitignore b/.gitignore index bbd62a042419..491c72e229b5 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,5 @@ lib/z.lib ######################### jquery-ui-*/ +lib/matplotlib/backends/web_backend/node_modules/ +lib/matplotlib/backends/web_backend/package-lock.json diff --git a/lib/matplotlib/backends/web_backend/.eslintrc.js b/lib/matplotlib/backends/web_backend/.eslintrc.js new file mode 100644 index 000000000000..f073e7fa3dc0 --- /dev/null +++ b/lib/matplotlib/backends/web_backend/.eslintrc.js @@ -0,0 +1,21 @@ +module.exports = { + root: true, + ignorePatterns: ["jquery-ui-*/", "node_modules/"], + env: { + browser: true, + jquery: true, + }, + extends: ["eslint:recommended", "prettier"], + globals: { + IPython: "readonly", + MozWebSocket: "readonly", + }, + rules: { + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + }, + ], + }, +}; diff --git a/lib/matplotlib/backends/web_backend/.prettierignore b/lib/matplotlib/backends/web_backend/.prettierignore new file mode 100644 index 000000000000..06a29c66e0fc --- /dev/null +++ b/lib/matplotlib/backends/web_backend/.prettierignore @@ -0,0 +1,7 @@ +node_modules/ + +# Vendored dependencies +css/boilerplate.css +css/fbm.css +css/page.css +jquery-ui-*/ diff --git a/lib/matplotlib/backends/web_backend/.prettierrc b/lib/matplotlib/backends/web_backend/.prettierrc new file mode 100644 index 000000000000..fe8d711065d6 --- /dev/null +++ b/lib/matplotlib/backends/web_backend/.prettierrc @@ -0,0 +1,11 @@ +{ + "overrides": [ + { + "files": "js/**/*.js", + "options": { + "singleQuote": true, + "tabWidth": 4, + } + } + ] +} diff --git a/lib/matplotlib/backends/web_backend/js/mpl.js b/lib/matplotlib/backends/web_backend/js/mpl.js index 7c774b4a16d0..4986680f5f2b 100644 --- a/lib/matplotlib/backends/web_backend/js/mpl.js +++ b/lib/matplotlib/backends/web_backend/js/mpl.js @@ -1,34 +1,36 @@ /* Put everything inside the global mpl namespace */ +/* global mpl */ window.mpl = {}; - -mpl.get_websocket_type = function() { - if (typeof(WebSocket) !== 'undefined') { +mpl.get_websocket_type = function () { + if (typeof WebSocket !== 'undefined') { return WebSocket; - } else if (typeof(MozWebSocket) !== 'undefined') { + } else if (typeof MozWebSocket !== 'undefined') { return MozWebSocket; } else { - alert('Your browser does not have WebSocket support. ' + - 'Please try Chrome, Safari or Firefox ≥ 6. ' + - 'Firefox 4 and 5 are also supported but you ' + - 'have to enable WebSockets in about:config.'); - }; -} + alert( + 'Your browser does not have WebSocket support. ' + + 'Please try Chrome, Safari or Firefox ≥ 6. ' + + 'Firefox 4 and 5 are also supported but you ' + + 'have to enable WebSockets in about:config.' + ); + } +}; -mpl.figure = function(figure_id, websocket, ondownload, parent_element) { +mpl.figure = function (figure_id, websocket, ondownload, parent_element) { this.id = figure_id; this.ws = websocket; - this.supports_binary = (this.ws.binaryType != undefined); + this.supports_binary = this.ws.binaryType !== undefined; if (!this.supports_binary) { - var warnings = document.getElementById("mpl-warnings"); + var warnings = document.getElementById('mpl-warnings'); if (warnings) { warnings.style.display = 'block'; - warnings.textContent = ( - "This browser does not support binary websocket messages. " + - "Performance may be slow."); + warnings.textContent = + 'This browser does not support binary websocket messages. ' + + 'Performance may be slow.'; } } @@ -44,7 +46,7 @@ mpl.figure = function(figure_id, websocket, ondownload, parent_element) { this.image_mode = 'full'; this.root = $('
'); - this._root_extra_style(this.root) + this._root_extra_style(this.root); this.root.attr('style', 'display: inline-block'); $(parent_element).append(this.root); @@ -57,58 +59,53 @@ mpl.figure = function(figure_id, websocket, ondownload, parent_element) { this.waiting = false; - this.ws.onopen = function () { - fig.send_message("supports_binary", {value: fig.supports_binary}); - fig.send_message("send_image_mode", {}); - if (mpl.ratio != 1) { - fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio}); - } - fig.send_message("refresh", {}); + this.ws.onopen = function () { + fig.send_message('supports_binary', { value: fig.supports_binary }); + fig.send_message('send_image_mode', {}); + if (mpl.ratio !== 1) { + fig.send_message('set_dpi_ratio', { dpi_ratio: mpl.ratio }); } + fig.send_message('refresh', {}); + }; - this.imageObj.onload = function() { - if (fig.image_mode == 'full') { - // Full images could contain transparency (where diff images - // almost always do), so we need to clear the canvas so that - // there is no ghosting. - fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height); - } - fig.context.drawImage(fig.imageObj, 0, 0); - }; + this.imageObj.onload = function () { + if (fig.image_mode === 'full') { + // Full images could contain transparency (where diff images + // almost always do), so we need to clear the canvas so that + // there is no ghosting. + fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height); + } + fig.context.drawImage(fig.imageObj, 0, 0); + }; - this.imageObj.onunload = function() { + this.imageObj.onunload = function () { fig.ws.close(); - } + }; this.ws.onmessage = this._make_on_message_function(this); this.ondownload = ondownload; -} +}; -mpl.figure.prototype._init_header = function() { +mpl.figure.prototype._init_header = function () { var titlebar = $( ''); + 'ui-helper-clearfix"/>' + ); var titletext = $( ''); - titlebar.append(titletext) + 'text-align: center; padding: 3px;"/>' + ); + titlebar.append(titletext); this.root.append(titlebar); this.header = titletext[0]; -} - - - -mpl.figure.prototype._canvas_extra_style = function(canvas_div) { - -} - +}; -mpl.figure.prototype._root_extra_style = function(canvas_div) { +mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {}; -} +mpl.figure.prototype._root_extra_style = function (_canvas_div) {}; -mpl.figure.prototype._init_canvas = function() { +mpl.figure.prototype._init_canvas = function () { var fig = this; var canvas_div = $(''); @@ -121,47 +118,53 @@ mpl.figure.prototype._init_canvas = function() { canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); - this.canvas_div = canvas_div - this._canvas_extra_style(canvas_div) + this.canvas_div = canvas_div; + this._canvas_extra_style(canvas_div); this.root.append(canvas_div); var canvas = $(''); canvas.addClass('mpl-canvas'); - canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0") + canvas.attr('style', 'left: 0; top: 0; z-index: 0; outline: 0'); this.canvas = canvas[0]; - this.context = canvas[0].getContext("2d"); + this.context = canvas[0].getContext('2d'); - var backingStore = this.context.backingStorePixelRatio || - this.context.webkitBackingStorePixelRatio || - this.context.mozBackingStorePixelRatio || - this.context.msBackingStorePixelRatio || - this.context.oBackingStorePixelRatio || - this.context.backingStorePixelRatio || 1; + var backingStore = + this.context.backingStorePixelRatio || + this.context.webkitBackingStorePixelRatio || + this.context.mozBackingStorePixelRatio || + this.context.msBackingStorePixelRatio || + this.context.oBackingStorePixelRatio || + this.context.backingStorePixelRatio || + 1; mpl.ratio = (window.devicePixelRatio || 1) / backingStore; var rubberband = $(''); - rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") + rubberband.attr( + 'style', + 'position: absolute; left: 0; top: 0; z-index: 1;' + ); var pass_mouse_events = true; canvas_div.resizable({ - start: function(event, ui) { + start: function (_event, _ui) { pass_mouse_events = false; }, - resize: function(event, ui) { + resize: function (_event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, - stop: function(event, ui) { + stop: function (_event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { - if (pass_mouse_events) + if (pass_mouse_events) { return fig.mouse_event(event, event['data']); + } } rubberband.mousedown('button_press', mouse_event_fn); @@ -172,9 +175,9 @@ mpl.figure.prototype._init_canvas = function() { rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); - canvas_div.on("wheel", function (event) { + canvas_div.on('wheel', function (event) { event = event.originalEvent; - event['data'] = 'scroll' + event['data'] = 'scroll'; if (event.deltaY < 0) { event.step = 1; } else { @@ -188,41 +191,44 @@ mpl.figure.prototype._init_canvas = function() { this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; - this.rubberband_context = rubberband[0].getContext("2d"); - this.rubberband_context.strokeStyle = "#000000"; + this.rubberband_context = rubberband[0].getContext('2d'); + this.rubberband_context.strokeStyle = '#000000'; - this._resize_canvas = function(width, height) { + this._resize_canvas = function (width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. - canvas_div.css('width', width) - canvas_div.css('height', height) + canvas_div.css('width', width); + canvas_div.css('height', height); canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); - canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); + canvas.attr( + 'style', + 'width: ' + width + 'px; height: ' + height + 'px;' + ); rubberband.attr('width', width); rubberband.attr('height', height); - } + }; // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu. - $(this.rubberband_canvas).bind("contextmenu",function(e){ + $(this.rubberband_canvas).bind('contextmenu', function (_e) { return false; }); - function set_focus () { + function set_focus() { canvas.focus(); canvas_div.focus(); } window.setTimeout(set_focus, 100); -} +}; -mpl.figure.prototype._init_toolbar = function() { +mpl.figure.prototype._init_toolbar = function () { var fig = this; var nav_element = $(''); @@ -237,7 +243,7 @@ mpl.figure.prototype._init_toolbar = function() { return fig.toolbar_button_onmouseover(event['data']); } - for(var toolbar_ind in mpl.toolbar_items) { + for (var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; @@ -248,8 +254,10 @@ mpl.figure.prototype._init_toolbar = function() { continue; } var button = $(''); - button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' + - 'ui-button-icon-only'); + button.addClass( + 'ui-button ui-widget ui-state-default ui-corner-all ' + + 'ui-button-icon-only' + ); button.attr('role', 'button'); button.attr('aria-disabled', 'false'); button.click(method_name, toolbar_event); @@ -280,58 +288,61 @@ mpl.figure.prototype._init_toolbar = function() { for (var ind in mpl.extensions) { var fmt = mpl.extensions[ind]; - var option = $( - '', {selected: fmt === mpl.default_extension}).html(fmt); + var option = $('', { + selected: fmt === mpl.default_extension, + }).html(fmt); fmt_picker.append(option); } // Add hover states to the ui-buttons - $( ".ui-button" ).hover( - function() { $(this).addClass("ui-state-hover");}, - function() { $(this).removeClass("ui-state-hover");} + $('.ui-button').hover( + function () { + $(this).addClass('ui-state-hover'); + }, + function () { + $(this).removeClass('ui-state-hover'); + } ); var status_bar = $(''); nav_element.append(status_bar); this.message = status_bar[0]; -} +}; -mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { +mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. - this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); -} + this.send_message('resize', { width: x_pixels, height: y_pixels }); +}; -mpl.figure.prototype.send_message = function(type, properties) { +mpl.figure.prototype.send_message = function (type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); -} +}; -mpl.figure.prototype.send_draw_message = function() { +mpl.figure.prototype.send_draw_message = function () { if (!this.waiting) { this.waiting = true; - this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); + this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id })); } -} - +}; -mpl.figure.prototype.handle_save = function(fig, msg) { +mpl.figure.prototype.handle_save = function (fig, _msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); -} - +}; -mpl.figure.prototype.handle_resize = function(fig, msg) { +mpl.figure.prototype.handle_resize = function (fig, msg) { var size = msg['size']; - if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { + if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) { fig._resize_canvas(size[0], size[1]); - fig.send_message("refresh", {}); - }; -} + fig.send_message('refresh', {}); + } +}; -mpl.figure.prototype.handle_rubberband = function(fig, msg) { +mpl.figure.prototype.handle_rubberband = function (fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; @@ -346,78 +357,85 @@ mpl.figure.prototype.handle_rubberband = function(fig, msg) { var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( - 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio); + 0, + 0, + fig.canvas.width / mpl.ratio, + fig.canvas.height / mpl.ratio + ); fig.rubberband_context.strokeRect(min_x, min_y, width, height); -} +}; -mpl.figure.prototype.handle_figure_label = function(fig, msg) { +mpl.figure.prototype.handle_figure_label = function (fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; -} +}; -mpl.figure.prototype.handle_cursor = function(fig, msg) { +mpl.figure.prototype.handle_cursor = function (fig, msg) { var cursor = msg['cursor']; - switch(cursor) - { - case 0: - cursor = 'pointer'; - break; - case 1: - cursor = 'default'; - break; - case 2: - cursor = 'crosshair'; - break; - case 3: - cursor = 'move'; - break; + switch (cursor) { + case 0: + cursor = 'pointer'; + break; + case 1: + cursor = 'default'; + break; + case 2: + cursor = 'crosshair'; + break; + case 3: + cursor = 'move'; + break; } fig.rubberband_canvas.style.cursor = cursor; -} +}; -mpl.figure.prototype.handle_message = function(fig, msg) { +mpl.figure.prototype.handle_message = function (fig, msg) { fig.message.textContent = msg['message']; -} +}; -mpl.figure.prototype.handle_draw = function(fig, msg) { +mpl.figure.prototype.handle_draw = function (fig, _msg) { // Request the server to send over a new figure. fig.send_draw_message(); -} +}; -mpl.figure.prototype.handle_image_mode = function(fig, msg) { +mpl.figure.prototype.handle_image_mode = function (fig, msg) { fig.image_mode = msg['mode']; -} +}; -mpl.figure.prototype.updated_canvas_event = function() { +mpl.figure.prototype.updated_canvas_event = function () { // Called whenever the canvas gets updated. - this.send_message("ack", {}); -} + this.send_message('ack', {}); +}; // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. -mpl.figure.prototype._make_on_message_function = function(fig) { +mpl.figure.prototype._make_on_message_function = function (fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ - evt.data.type = "image/png"; + evt.data.type = 'image/png'; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( - fig.imageObj.src); + fig.imageObj.src + ); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( - evt.data); + evt.data + ); fig.updated_canvas_event(); fig.waiting = false; return; - } - else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { + } else if ( + typeof evt.data === 'string' && + evt.data.slice(0, 21) === 'data:image/png;base64' + ) { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; @@ -430,9 +448,12 @@ mpl.figure.prototype._make_on_message_function = function(fig) { // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { - var callback = fig["handle_" + msg_type]; + var callback = fig['handle_' + msg_type]; } catch (e) { - console.log("No handler for the '" + msg_type + "' message type: ", msg); + console.log( + "No handler for the '" + msg_type + "' message type: ", + msg + ); return; } @@ -441,24 +462,33 @@ mpl.figure.prototype._make_on_message_function = function(fig) { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { - console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); + console.log( + "Exception inside the 'handler_" + msg_type + "' callback:", + e, + e.stack, + msg + ); } } }; -} +}; // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas -mpl.findpos = function(e) { +mpl.findpos = function (e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; - if (!e) + if (!e) { e = window.event; - if (e.target) + } + if (e.target) { targ = e.target; - else if (e.srcElement) + } else if (e.srcElement) { targ = e.srcElement; - if (targ.nodeType == 3) // defeat Safari bug + } + if (targ.nodeType === 3) { + // defeat Safari bug targ = targ.parentNode; + } // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document @@ -466,7 +496,7 @@ mpl.findpos = function(e) { var x = e.pageX - $(targ).offset().left; var y = e.pageY - $(targ).offset().top; - return {"x": x, "y": y}; + return { x: x, y: y }; }; /* @@ -474,19 +504,19 @@ mpl.findpos = function(e) { * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ -function simpleKeys (original) { - return Object.keys(original).reduce(function (obj, key) { - if (typeof original[key] !== 'object') - obj[key] = original[key] - return obj; - }, {}); +function simpleKeys(original) { + return Object.keys(original).reduce(function (obj, key) { + if (typeof original[key] !== 'object') { + obj[key] = original[key]; + } + return obj; + }, {}); } -mpl.figure.prototype.mouse_event = function(event, name) { - var canvas_pos = mpl.findpos(event) +mpl.figure.prototype.mouse_event = function (event, name) { + var canvas_pos = mpl.findpos(event); - if (name === 'button_press') - { + if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } @@ -494,9 +524,13 @@ mpl.figure.prototype.mouse_event = function(event, name) { var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; - this.send_message(name, {x: x, y: y, button: event.button, - step: event.step, - guiEvent: simpleKeys(event)}); + this.send_message(name, { + x: x, + y: y, + button: event.button, + step: event.step, + guiEvent: simpleKeys(event), + }); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want @@ -504,51 +538,53 @@ mpl.figure.prototype.mouse_event = function(event, name) { * 'cursor' event from matplotlib */ event.preventDefault(); return false; -} +}; -mpl.figure.prototype._key_event_extra = function(event, name) { +mpl.figure.prototype._key_event_extra = function (_event, _name) { // Handle any extra behaviour associated with a key event -} - -mpl.figure.prototype.key_event = function(event, name) { +}; +mpl.figure.prototype.key_event = function (event, name) { // Prevent repeat events - if (name == 'key_press') - { - if (event.which === this._key) + if (name === 'key_press') { + if (event.which === this._key) { return; - else + } else { this._key = event.which; + } } - if (name == 'key_release') + if (name === 'key_release') { this._key = null; + } var value = ''; - if (event.ctrlKey && event.which != 17) - value += "ctrl+"; - if (event.altKey && event.which != 18) - value += "alt+"; - if (event.shiftKey && event.which != 16) - value += "shift+"; + if (event.ctrlKey && event.which !== 17) { + value += 'ctrl+'; + } + if (event.altKey && event.which !== 18) { + value += 'alt+'; + } + if (event.shiftKey && event.which !== 16) { + value += 'shift+'; + } value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); - this.send_message(name, {key: value, - guiEvent: simpleKeys(event)}); + this.send_message(name, { key: value, guiEvent: simpleKeys(event) }); return false; -} +}; -mpl.figure.prototype.toolbar_button_onclick = function(name) { - if (name == 'download') { +mpl.figure.prototype.toolbar_button_onclick = function (name) { + if (name === 'download') { this.handle_save(this, null); } else { - this.send_message("toolbar_button", {name: name}); + this.send_message('toolbar_button', { name: name }); } }; -mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { +mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) { this.message.textContent = tooltip; }; diff --git a/lib/matplotlib/backends/web_backend/js/mpl_tornado.js b/lib/matplotlib/backends/web_backend/js/mpl_tornado.js index 8eb5eedb506a..b3cab8b7b906 100644 --- a/lib/matplotlib/backends/web_backend/js/mpl_tornado.js +++ b/lib/matplotlib/backends/web_backend/js/mpl_tornado.js @@ -2,6 +2,7 @@ tornado-based server, that are not relevant when embedding WebAgg in another web application. */ +/* exported mpl_ondownload */ function mpl_ondownload(figure, format) { window.open(figure.id + '/download.' + format, '_blank'); } diff --git a/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js b/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js index a66e450cd90c..6461bfca6479 100644 --- a/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js +++ b/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js @@ -1,42 +1,42 @@ -var comm_websocket_adapter = function(comm) { +/* global mpl */ + +var comm_websocket_adapter = function (comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; - ws.close = function() { - comm.close() + ws.close = function () { + comm.close(); }; - ws.send = function(m) { + ws.send = function (m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. - comm.on_msg(function(msg) { + comm.on_msg(function (msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. - ws.onmessage(msg['content']['data']) + ws.onmessage(msg['content']['data']); }); return ws; -} +}; -mpl.mpl_figure_comm = function(comm, msg) { +mpl.mpl_figure_comm = function (comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. - var element = $("#" + id); - var ws_proxy = comm_websocket_adapter(comm) + var element = $('#' + id); + var ws_proxy = comm_websocket_adapter(comm); - function ondownload(figure, format) { + function ondownload(figure, _format) { window.open(figure.imageObj.src); } - var fig = new mpl.figure(id, ws_proxy, - ondownload, - element.get(0)); + var fig = new mpl.figure(id, ws_proxy, ondownload, element.get(0)); // Call onopen now - mpl needs it, as it is assuming we've passed it a real // web socket which is closed, not our websocket->open comm proxy. @@ -45,52 +45,53 @@ mpl.mpl_figure_comm = function(comm, msg) { fig.parent_element = element.get(0); fig.cell_info = mpl.find_output_cell(""); if (!fig.cell_info) { - console.error("Failed to find cell for figure", id, fig); + console.error('Failed to find cell for figure', id, fig); return; } - - var output_index = fig.cell_info[2] - var cell = fig.cell_info[0]; - }; -mpl.figure.prototype.handle_close = function(fig, msg) { - var width = fig.canvas.width/mpl.ratio - fig.root.unbind('remove') +mpl.figure.prototype.handle_close = function (fig, msg) { + var width = fig.canvas.width / mpl.ratio; + fig.root.unbind('remove'); // Update the output cell to use the data from the current canvas. fig.push_to_output(); var dataURL = fig.canvas.toDataURL(); // Re-enable the keyboard manager in IPython - without this line, in FF, // the notebook keyboard shortcuts fail. - IPython.keyboard_manager.enable() - $(fig.parent_element).html('