Skip to content

Commit e446161

Browse files
committed
Backport PR jupyter-widgets#3370: Allow Output widget in html manager to render state updates
1 parent 02e8963 commit e446161

File tree

4 files changed

+181
-29
lines changed

4 files changed

+181
-29
lines changed

examples/web3/jupyter-logo.svg

Lines changed: 90 additions & 0 deletions
Loading

examples/web3/widget_code.json

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
[
2-
"from ipywidgets import IntSlider, Text, VBox",
3-
"from IPython.display import display",
4-
"",
5-
"s = IntSlider(max=200, value=100)",
6-
"t = Text()",
7-
"",
8-
"def update_text(change=None):",
9-
" t.value = str(s.value ** 2)",
10-
"",
11-
"s.observe(update_text, names='value')",
12-
"update_text()",
13-
"display(VBox([s, t]))"
2+
"from ipywidgets import IntSlider, Output, Text, VBox",
3+
"from IPython.display import Image, display",
4+
"",
5+
"s = IntSlider(min=1, max=500, value=200, description='Width')",
6+
"t = Text(description='Area', disabled=True)",
7+
"o = Output()",
8+
"display(VBox([s, t, o]))",
9+
"",
10+
"def update(change=None):",
11+
" width = s.value",
12+
" t.value = str(width ** 2)",
13+
" o.outputs = ()",
14+
" img = Image(url='jupyter-logo.svg', width=width)",
15+
" o.append_display_data(img)",
16+
"",
17+
"s.observe(update, names='value')",
18+
"update()"
1419
]

packages/html-manager/src/output.ts

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,40 @@ import $ from 'jquery';
1414
import '../css/output.css';
1515

1616
export class OutputModel extends outputBase.OutputModel {
17-
defaults() {
18-
return {
19-
...super.defaults(),
20-
msg_id: ''
21-
};
22-
}
17+
defaults(): Backbone.ObjectHash {
18+
return {
19+
...super.defaults(),
20+
msg_id: '',
21+
outputs: [],
22+
};
23+
}
2324

24-
initialize(attributes: any, options: any) {
25-
super.initialize(attributes, options);
26-
this._outputs = new OutputAreaModel({
27-
values: attributes.outputs,
28-
// Widgets (including this output widget) are only rendered in
29-
// trusted contexts
30-
trusted: true,
31-
});
32-
}
25+
initialize(attributes: any, options: any): void {
26+
super.initialize(attributes, options);
27+
this._outputs = new OutputAreaModel({ trusted: true });
28+
this.listenTo(this, 'change:outputs', this.setOutputs);
29+
this.setOutputs();
30+
}
3331

3432
get outputs() {
3533
return this._outputs;
3634
}
3735

38-
private _outputs: OutputAreaModel;
39-
widget_manager: HTMLManager;
36+
clear_output(wait = false): void {
37+
this._outputs.clear(wait);
38+
}
39+
40+
setOutputs(model?: any, value?: any, options?: any): void {
41+
if (!(options && options.newMessage)) {
42+
// fromJSON does not clear the existing output
43+
this.clear_output();
44+
// fromJSON does not copy the message, so we make a deep copy
45+
this._outputs.fromJSON(JSON.parse(JSON.stringify(this.get('outputs'))));
46+
}
47+
}
48+
49+
private _outputs: OutputAreaModel;
50+
widget_manager: HTMLManager;
4051
}
4152

4253
export class OutputView extends outputBase.OutputView {

packages/html-manager/test/src/output_test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const newWidget = async (modelState: any): Promise<HTMLElement> => {
2121
model_module_version: '*'
2222
};
2323
const model = await manager.new_model(modelCreate, modelState);
24+
<<<<<<< HEAD
2425
await manager.display_model(
2526
undefined, model, { el: widgetTag }
2627
);
@@ -205,4 +206,49 @@ describe('Output widget', function() {
205206
);
206207
expect(widgetTag.innerText).to.equal('something different');
207208
});
209+
=======
210+
await manager.display_view(manager.create_view(model), widgetTag);
211+
expect(widgetTag.innerText).to.equal('something different');
212+
});
213+
214+
it('renders text output', async () => {
215+
const manager = new HTMLManager();
216+
const modelId = 'u-u-i-d';
217+
const modelCreate: base.IModelOptions = {
218+
model_name: 'OutputModel',
219+
model_id: modelId,
220+
model_module: '@jupyter-widgets/output',
221+
model_module_version: '*',
222+
};
223+
224+
const startingText = 'starting text';
225+
const endingText = 'ending text';
226+
const modelState = {
227+
_view_module: '@jupyter-widgets/output',
228+
outputs: [
229+
{
230+
output_type: 'stream',
231+
name: 'stdout',
232+
text: startingText,
233+
},
234+
],
235+
};
236+
237+
const widgetTag = document.createElement('div');
238+
widgetTag.className = 'widget-subarea';
239+
document.body.appendChild(widgetTag);
240+
const model = await manager.new_model(modelCreate, modelState);
241+
await manager.display_view(manager.create_view(model), widgetTag);
242+
expect(widgetTag.innerText).to.equal(startingText);
243+
244+
model.set('outputs', [
245+
{
246+
output_type: 'stream',
247+
name: 'stdout',
248+
text: endingText,
249+
},
250+
]);
251+
expect(widgetTag.innerText).to.equal(endingText);
252+
});
253+
>>>>>>> 20945261 (Merge pull request #3370 from MrBago/html-ow-update)
208254
});

0 commit comments

Comments
 (0)