Merge pull request #621 from julienr/inline_images
Implement markdown cell attachments. Allow drag’n’drop of images into…pull/1187/head
commit
233f04428d
@ -0,0 +1,50 @@
|
||||
// Copyright (c) Jupyter Development Team.
|
||||
// Distributed under the terms of the Modified BSD License.
|
||||
|
||||
define([
|
||||
'notebook/js/celltoolbar',
|
||||
'base/js/dialog',
|
||||
], function(celltoolbar, dialog) {
|
||||
"use strict";
|
||||
|
||||
var CellToolbar = celltoolbar.CellToolbar;
|
||||
|
||||
var edit_attachments_dialog = function(cell) {
|
||||
dialog.edit_attachments({
|
||||
attachments: cell.attachments,
|
||||
callback: function(attachments) {
|
||||
cell.attachments = attachments;
|
||||
// Force cell refresh
|
||||
cell.unrender();
|
||||
cell.render();
|
||||
},
|
||||
name: 'cell',
|
||||
notebook: cell.notebook,
|
||||
keyboard_manager: cell.keyboard_manager
|
||||
});
|
||||
};
|
||||
|
||||
var add_dialog_button = function(div, cell) {
|
||||
var button_container = $(div);
|
||||
var button = $('<button />')
|
||||
.addClass('btn btn-default btn-xs')
|
||||
.text('Edit Attachments')
|
||||
.click( function() {
|
||||
edit_attachments_dialog(cell);
|
||||
return false;
|
||||
});
|
||||
button_container.append(button);
|
||||
};
|
||||
|
||||
var register = function(notebook) {
|
||||
CellToolbar.register_callback('attachments.edit', add_dialog_button);
|
||||
|
||||
var attachments_preset = [];
|
||||
attachments_preset.push('attachments.edit');
|
||||
|
||||
CellToolbar.register_preset('Attachments', attachments_preset, notebook);
|
||||
console.log('Attachments editing toolbar loaded.');
|
||||
|
||||
};
|
||||
return {'register' : register}
|
||||
});
|
||||
|
After Width: | Height: | Size: 145 B |
@ -0,0 +1,123 @@
|
||||
//
|
||||
// Test cell attachments
|
||||
//
|
||||
var fs = require('fs');
|
||||
casper.notebook_test(function () {
|
||||
// -- Test the Edit->Insert Image menu to insert new attachments
|
||||
"use strict";
|
||||
casper.test.info("Testing attachments insertion through the menuitem");
|
||||
|
||||
this.viewport(1024, 768);
|
||||
|
||||
// Click on menuitem
|
||||
var selector = '#insert_image > a';
|
||||
this.waitForSelector(selector);
|
||||
this.thenEvaluate(function(sel) {
|
||||
IPython.notebook.to_markdown();
|
||||
var cell = IPython.notebook.get_selected_cell();
|
||||
cell.set_text("");
|
||||
cell.unrender();
|
||||
|
||||
$(sel).click();
|
||||
}, selector);
|
||||
// Wait for the dialog to be shown
|
||||
this.waitUntilVisible(".modal-body");
|
||||
this.wait(200);
|
||||
|
||||
// Select the image file to insert
|
||||
|
||||
// For some reason, this doesn't seem to work in a reliable way in
|
||||
// phantomjs. So we manually set the input's files attribute
|
||||
//this.page.uploadFile('.modal-body input[name=file]', 'test.png')
|
||||
this.then(function() {
|
||||
var fname = 'notebook/tests/_testdata/black_square_22.png';
|
||||
if (!fs.exists(fname)) {
|
||||
this.test.fail(
|
||||
" does not exist, are you running the tests " +
|
||||
"from the root directory ? "
|
||||
);
|
||||
}
|
||||
this.fill('form#insert-image-form', {'file': fname});
|
||||
});
|
||||
|
||||
// Validate and render the markdown cell
|
||||
this.thenClick('#btn_ok');
|
||||
this.thenEvaluate(function() {
|
||||
IPython.notebook.get_cell(0).render();
|
||||
});
|
||||
this.wait(300);
|
||||
// Check that an <img> tag has been inserted and that it contains the
|
||||
// image
|
||||
this.then(function() {
|
||||
var img = this.evaluate(function() {
|
||||
var cell = IPython.notebook.get_cell(0);
|
||||
var img = $("div.text_cell_render").find("img");
|
||||
return {
|
||||
src: img.attr("src"),
|
||||
width: img.width(),
|
||||
height: img.height(),
|
||||
};
|
||||
});
|
||||
this.test.assertType(img, "object", "Image('image/png')");
|
||||
this.test.assertEquals(img.src.split(',')[0],
|
||||
"data:image/png;base64",
|
||||
"Image data-uri prefix");
|
||||
this.test.assertEquals(img.width, 2, "width == 2");
|
||||
this.test.assertEquals(img.height, 2, "height == 2");
|
||||
});
|
||||
|
||||
//this.then(function() {
|
||||
//this.capture('test.png');
|
||||
//});
|
||||
|
||||
// -- Use the Edit->Copy/Paste Cell Attachments menu items
|
||||
selector = '#copy_cell_attachments > a';
|
||||
this.waitForSelector(selector);
|
||||
this.thenClick(selector);
|
||||
|
||||
// append a new cell
|
||||
this.append_cell('', 'markdown');
|
||||
this.thenEvaluate(function() {
|
||||
IPython.notebook.select_next();
|
||||
});
|
||||
|
||||
// and paste the attachments into it
|
||||
selector = '#paste_cell_attachments > a';
|
||||
this.waitForSelector(selector);
|
||||
this.thenClick(selector);
|
||||
|
||||
// check that the new cell has attachments
|
||||
this.then(function() {
|
||||
var cell = this.evaluate(function() {
|
||||
return IPython.notebook.get_selected_cell();
|
||||
});
|
||||
var orig_cell = this.evaluate(function() {
|
||||
return IPython.notebook.get_cell(0);
|
||||
});
|
||||
var clip = this.evaluate(function() { return IPython.notebook.clipboard_attachments; });
|
||||
// Check that the two cells have the same attachments
|
||||
this.test.assertEquals(cell.attachments, orig_cell.attachments,
|
||||
"both cells have the attachments");
|
||||
});
|
||||
|
||||
// -- Save the notebook. This should cause garbage collection for the
|
||||
// second cell (since we just pasted the attachments but there is no
|
||||
// markdown referencing them)
|
||||
this.thenEvaluate(function() {
|
||||
IPython.notebook.save_checkpoint();
|
||||
});
|
||||
|
||||
this.then(function() {
|
||||
var cell0 = this.evaluate(function() {
|
||||
return IPython.notebook.get_cell(0);
|
||||
});
|
||||
var cell1 = this.evaluate(function() {
|
||||
return IPython.notebook.get_cell(1);
|
||||
});
|
||||
this.test.assert('black_square_22.png' in cell0.attachments,
|
||||
'cell0 has kept its attachments');
|
||||
this.test.assertEquals(Object.keys(cell1.attachments).length, 0,
|
||||
'cell1 attachments have been garbage collected');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in new issue