New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix binary synchronization and make Image use binary values #1643

Merged
merged 6 commits into from Aug 17, 2017

Conversation

Projects
None yet
2 participants
@jasongrout
Member

jasongrout commented Aug 16, 2017

Fixes #1642 by working around an underscore bug.

This also makes the image use a binary value so that we have at least one core widget using the binary values and messages.

This means that custom deserializers must not return a DataView or ArrayBuffer (other typed arrays like Uint8Array are fine, though).

Test code:

from ipywidgets import Image
from io import BytesIO
import numpy as np
from scipy.misc import imsave
x = np.zeros((255, 255), dtype=np.uint8)
x[:] = np.arange(255)
b = BytesIO()
imsave(b, x, format='png')

im = Image(layout=dict(width='100px', height='100px', border='1px solid red'))
im

Then

im.value=b.getvalue()

and also make sure the image is displayed when the page is refreshed.
CC @maartenbreddels

Convert the image to use a binary value and binary sync.
We do this primarily so that we have a basic widget that exercises the binary messages.

@jasongrout jasongrout modified the milestone: 7.0 Aug 16, 2017

var blob = new Blob([this.model.get('value')], {type: `image/${this.model.get('format')}`});
var url = URL.createObjectURL(blob);
var oldurl = this.el.src;
this.el.src = url;

This comment has been minimized.

@maartenbreddels

maartenbreddels Aug 17, 2017

Member

I think the createObjectURL is deprecated (firefox gives you a warning on that).
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
The proper way would be to use this.el.srcObject = blob I think. We may want to polyfill this with https://github.com/webrtc/adapter , which is what I do in https://github.com/maartenbreddels/ipywebrtc

This comment has been minimized.

@maartenbreddels

maartenbreddels Aug 17, 2017

Member

Sorry for the noise, that was only for HTMLMediaElement, not HTMLImageElement

This comment has been minimized.

@jasongrout

This comment has been minimized.

@maartenbreddels

maartenbreddels Aug 17, 2017

Member

Yes, it's completely correct.

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

@maartenbreddels - our problem is more serious than my simple workaround. Since underscore is doing the deep compare, any arraybuffer or dataview object anywhere nested in the JSON of a deserialized trait is going to have this issue.

I'm tempted to just override the backbone function and insert a special-case call to our own isequal.

@maartenbreddels

This comment has been minimized.

Member

maartenbreddels commented Aug 17, 2017

I guess both Backbone's set and changedAttributes?

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

I think we override set and call our own isEqual.

We're slowly completely reimplementing backbone...

@maartenbreddels

This comment has been minimized.

Member

maartenbreddels commented Aug 17, 2017

Or we fork and publish underscore with a fixed _.isEquals, maybe less work.

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

Note that lodash has specific references to typed arrays, indicating they handle that case: https://github.com/lodash/lodash/blob/8e631dfcd496bc355ee7ceeb959421b0788b9bbc/.internal/baseIsEqualDeep.js#L56

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

Or we fork and publish underscore with a fixed _.isEquals, maybe less work.

And then we have to fork backbone and update its dependency. I really don't want to maintain an underscore fork, especially when lodash seems to work in this case.

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

This indicates that we can replace underscore with lodash for backbone, but requires a special webpack config. We can't do that in jlab, though. Too bad.

@jasongrout jasongrout force-pushed the jasongrout:binaryimage branch from b33ce39 to 5c87a42 Aug 17, 2017

@jasongrout

This comment has been minimized.

Member

jasongrout commented Aug 17, 2017

@maartenbreddels - I think this is ready for review and testing. I could also remove underscore from controls, but that's not pressing.

Patch Backbone’s set method to use our isEqual (from lodash).
Underscore 1.8.3’s _.eq assumes all DataView and ArrayBuffers are the same, so backbone will not trigger a change event when attributes are set (see jashkenas/underscore#2692). Lodash 4 does distinguish between different dataviews or arraybuffers, so we'll use the Lodash isEqual.

@jasongrout jasongrout force-pushed the jasongrout:binaryimage branch from 5c87a42 to 626e73f Aug 17, 2017

@jasongrout jasongrout force-pushed the jasongrout:binaryimage branch from 626e73f to b566bc1 Aug 17, 2017

@jasongrout jasongrout merged commit 1a357c9 into jupyter-widgets:master Aug 17, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment