Data URIs in GWT - html

Is it possible to create data URI's in GWT?
I want to inject a byte array image as an actual image using a data URI.

You should checkout ClientBundle in GWT's trunk. It will create data urls automatically for browsers that support them and fallbacks for that other browser: http://code.google.com/p/google-web-toolkit/wiki/ClientBundle
The feature won't ship until GWT 2.0, but it's in heavy use now.

Yes. It is completely possible to do this. I'd done it for an application until I realized IE6 doesn't handle binary data streams this way. You can do it in several ways. For the purposes of my example, I'm already assuming that you've converted the byte array to a string somewhere, and that it is properly encoded and of the proper type for your data URI. I'm also assuming you know the basic format (or can find it) of your chosen data scheme.
I've taken these examples from the Wikipedia article on data URI scheme.
The first is to just use raw HTML to make the image reference as you normally would and have it inserted into the page.
HTML html = new HTML("<img src=\"data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==\" alt=\"Red dot\">");
You can also just use an image. (Which should produce roughly the same output HTML/JS.)
Image image = new Image("data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==");
This allows you to use the full power of the Image abstraction on top of your loaded image.
I'm still thinking that you may want to expand on this solution and use GWT's deferred binding mechanism to deal with browsers that do not support data URIs. (IE6,IE7)

Related

Is there a way to embed the Firefox JSONView (or similar) inside DRF's BrowseableAPI json nested-renderer?

Django Rest Framework's (DRF) BrowsableAPI renderer is very useful when the JSON to show is "small enough", but it struggles when the JSON is big. For example, in the image below the JSON is hard to read and the user has to scroll a lot(I even had to crop the image).
But when using Firefox's integrated JSONView, we can collapse each attribute and "interactively" read the JSON and I can even filter attributes. For example, in the image below I filter the attributes to show the ones that include the word "Population".
I inspected Firefox's integrated JSONView and apparently it uses a local HTML+JSON+CSS combination to render the JSON viewer, but I couldn't find an easy way to use it in DRF's BrowsableAPI.
Is there a way to embed it? Is there an alternative to make big JSONs more readable?

Is it possible to nest one data: URI inside another?

If I use a data URI to construct a src attribute for an HTML element, can it in turn have another data URI inside it?
I know you can't use data uri's for iframes (I'm actually trying to construct an OSDX document and pass it to the browser with an icon encoded in base64 but that's a really niche use case and this is more of a general question), but assuming you could, my use case would look like:
var iframe = document.createElement('iframe');
var icon = document.createElement('image');
var iSrc = 'data:image/png;base64,/*[REALLY LONG STRING]*/';
iframe.src='data:text/html,<html><body><image src="'+iSrc+'" /></body</html>
document.body.appendChild(iframe);
Basically what I'm after is is there anything in a data uri that would break a parent data uri?
Yes you can. I really thought it was impossible, as did everyone I asked.
Example:
Pasting the following into your browser's URL bar should render a gmail logo in an html page that says hello world.
data:text/html,<html><body><p>hello world</p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAz1BMVEX///+6xs7iTULj5+vW2tzk49TX3+Tq6tz09Orz9/jm7O6wu8aNm6WwMCjfRDnm5ube2Mmos7vt7++jrLP29/eyTk3d4+fj6+foWFLM1t2bNzeZpa2trKPv8/ajo6Xud2f0r6rv7uG3ubvd6eXIysq9s6jeopfSUknx8fHbXGKvTx7Hz9X09PTwhXHw9Pb++/fp7/Xu4d3SZlPSiXjuaFmMkZX39/vZy6/j8+v2+/v76uP7+/v0/Pewl4raMi/f5+7KTjitf4W2rI3/9vDzz8uC91bdAAAAAXRSTlMAQObYZgAAAmBJREFUeF6VldeunDAQQNeF3jvbe729p/f//6aMxzaBKHe5OZiVJY6OBvbBAyTvZaDJSy/xzpJ4pdJzz1tfOme5LD0vly45fETe4/1vUoK26bnPznUPzrPrmSJsgtrPpQnpPCmvp2/gukyE/HX6JtYor9/kpqUcY3ogvUxv5RhlSrbHenFzY/+0cxtYApZlGZod3W9JaqJspuSR1vTqw41U4UZb+S/zMAz35FbJt4QK6sUnW+naxWwoaJXBpBi37bxTjuchyl+0zLGs4npmVK1dHSLBiLhmlg+chLukFiLqV3dQ1i84p1SEv42CgLhYzmR5vqh1XIUXeypGoN+LAMoVz5yBk/EKZfsOQioOsnGFWXr/eXLCMs9EeehK2bab+NKCbQj2/mEymRSjpqzkR5CXOv4AWSqyM3BnRSDKw255CWtBW0BWcILyCmQsMywv5b/xS8WpzGJZzMywPFZjvANTYO10VoNfIxqOW2WlwhU/QnbSMDu1y0yWpSowdiqry6OArEW5ka1GNTaGsWqViwDL4z/lezClu4nBN+K/ypWSIywrNY4NxaqZWZSjThlEkQXLUna8lTZ+unWnDE6T1fbmtZlBxWxbFvHZ5NR8DUeUj5QejQ1mu24cv2C5aJW3R3qv1a4bX8TbIih+wAv6IPvDKCIrAusV8FEpyz5njFUV/ERdWFTBHVWwmGkyKKPcT2kyjvKFy1jPgnJ6IeTMg30vzCUZHBTc52mvzdKhz+GYcJIxTw8ukOKlVmd/SPk4kSdQ4nv8fJh7PriIw7Mn/yxPGW8dm06e269eOTwe/De/AW24fWb7B21TAAAAAElFTkSuQmCC" /></body></html>
or for a shorter example courtesy of Pumbaa80:
data:text/html,<script src="data:text/javascript,alert('hello world')"></script>
MSDN explicitly supports this:
Data URIs can be nested.
An old blog entry talks a little bit more about embedding images within CSS using data: :
Neither dataURI spec nor any other mentions if dataURI’es can not be nested. So here’s the testcase where dataURI’ed CSS has dataURI’ed image embedded. IE8b1, Firefox3 and Safari applied the stylesheet and showed the image, Opera9.50 (build 9613) applies the stylesheet but doesn’t show the embedded image! So it seems that Opera9 doesn’t expect to get anything embedded inside of an already embedded resource! :D
But funny thing, as IE8b1 supports expressions and also supports nested data URI’es, it has the same potential security flaw as Firefox does (as described in the section above). See the testcase — embedded CSS has the following code: body { background: expression(a()); } which calls function a() defined in the javascript of the main page, and this function is called every time the expression is reevaluated. Though IE8b1 has limited expressions support (which is going to be explained in a separate post) you can’t use any code as the expression value, but you can only call already defined functions or use direct string values. So in order to exploit this feature we need to have a ready javascript function already located on the page and then we can just call it from the expression embedded in the stylesheet. That’s not very trivial obviously, but if you have a website that allows people to specify their own stylesheets and you want to be on the safe side, you have to either make sure you don’t have a javascript function that can cause any potential harm or filter expressions from people’s stylesheets.

Best practice for inlining images using data:-URLs?

I have a simple rails app that stores images created by users in an HTML5 site using canvasContext.toDataURL(). There's an index action, which shows a list of thumbnails, and a show action for each image, showing the image.
I'm being absolutely lazy in the backend here, I just store the base64 encoded data:image/png;base64,... Strings of the original image and a thumbnail, which is also generated in the client. The images are included in the page using <img src="data:"/> URIs.
Now, since this isn't fully supported in IE before v9, I will have to implement some kind of workaround, probably by including the URL of the generated image using a data- attribute and then replacing the source attribute after page load using jQuery.
This brings up the question whether it's good practice to inline rather large images into HTML using data: URLs...
Are there any recommendations or best practices? The images might be up to 500 KiB, and each of them is used only once. The page containing the images will not change once created, so it should be cacheable pretty good, including the image. The index page containing the thumbnails (which are around 60 KiB) uses pagination, so the page will hardly be cacheable. You can assume that the HTML pages will be deflated or gzipped in production.
Best-practice is: Don't.
You'll need a workaround anyway, which will completely duplicate the basic functionality, so you've just another place things can go wrong and more cases to test.
You say the images should be very cacheable, but you're sending them in a way that doesn't allow you to include information about caching. However, with the more common approach of sending images over a separate HTTP request, you can send expires and max-age requests to indicate the image won't change for a year. If you're super-confident that the image won't change you can also set a last-modified and an e-tag (you don't even need any logic to decide on the etag, just send "IMMUTABLE" as the tag) and respond to every conditional GET by sending a 304 without even checking (because again, you only do that if you're super-confident, otherwise though you can still implement a more conventional check for 304).
If the image is just used once, then have the image served by something that creates it and writes it based on some identifying features in the query (just what is specific to what you are doing) and writes it to the stream to the browser. You'll still have nicer separation within your application to have this done in its own place.
Even with gzip, you aren't going to beat this on stream size.
This is not a good idea. I would use normal, separate image resources instead.
By using inline images,
you destroy all cacheability for static images - with inlined images, every time the HTML page changes, all the image data has to be reloaded as well.
gzipping/deflating will take longer, and produce sub-optimal results (because image data is much harder and much less efficient to compress).
the rest of the Internet is geared towards HTML documents and images being separate resources: Prefetchers, caching systems, proxies...
then you have browser compatibility, which as you point out, is abysmal for older IEs.
My advice ? Don't do it.
A real file can be modified more easily with backend libraries, so don't.
And if you want use base64 in your page, you can easily do it with HTML5.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'images/myimage.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e){
if(this.status == 200){
var bb = new WebKitBlobBuilder(); // Or MozBlobBuilder, MSBlobBuilder, etc.
bb.append(this.response);
var reader = new FileReader();
reader.readAsDataURL(bb.getBlob('image/png'));
reader.onloadend = function(e){
$("#myimage").attr("src", reader.result);
};
}
};
xhr.send();

Converting d3.js SVG code to a standalone program — Example?

Either with a headless browser, google filesytem API, or some other way.
This question says you can, but not how.
Converting d3.js SVG code to a standalone program -- any suggestions?
google groups has more hints, but no examples.
I've spent a bunch of time playing with the node-canvas example, as well as the phantomJS svg example. I can't figure out how to make them play together. Apparently in Linux, the x-windows Javascript rendering engine isn't very good anyway.
My API reading list of JavaScript, d3.js, SVG, CSS, and other HTML stuff is already mountainous - all I want to do is save a .svg image that I generate with d3.js.
Help, please.
This will neither be easy nor overtly complicated. Main reason being is that a web browser alone cannot save an SVG file from a DOM rendering, unless it's Chrome version 12.
Thing is that an SVG image is just a plain text file with a bunch of rendering instructions. The solution you point to basically says you would have to do this server side. Though they suggest node.js, you can do this in any server-side language you'd like.
Trick is to take your JavaScript/HTML interface, make it either keep track of all objects you create, or otherwise be able to serialize all of them, and then send that data (ex: via ajax) to a server-side program which would reconstitute that to an SVG file and offer it to be downloaded.
The challenge is that both your programs (client-side, javascript and server-side: php/etc.) will more or less have to re-implement SVG specifications to make this work and have common understanding as to how you serialized it for the transmission. There are virtually no stock components that do this for you.
There are some examples of using node().parentNode.innerHTML with 64B encoding, but I couldn't figure out how to use it.
https://groups.google.com/forum/?fromgroups#!topic/d3-js/aQSWnEDFxIc
The easiest solution I've found so far is FileSaver.js demo here:
http://eligrey.com/demos/FileSaver.js/
It uses the HTML5 filesaver interface.
I came across this today, I've not tried it but perhaps someone will find it useful:
https://github.com/d3-node/d3-node
const D3Node = require('d3-node')
const d3n = new D3Node() // initializes D3 with container element
d3n.createSVG(10,20).append('g') // create SVG w/ 'g' tag and width/height
d3n.svgString() // output: <svg width=10 height=20 xmlns="http://www.w3.org/2000/svg"><g></g></svg>

Is it possible to have a html code and all images in one file?

I want to have a html file with javascript. Then I want to have some images in this file. I want to send this html file to my friends (per e-mail). I want them to see my html file with images but I do not want to send them all files with all images. It would be nice to send them just one file.
I also do not want to have images on a web-server.
I also do not want to send them an archive with all the files (since they then need to open this archive).
Do I want to much or it's possible to do what I want?
ADDED
I do not want my friends to see the html file in a mail-client. I want to send a file as an attachment. So, they can save it and then open with a browser.
Yes, it is possible:
# HTML
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA................." />
# CSS
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA.................)
File source is encoded using Base64 algorithm that allows easily represent binary data as normal text.
Find out more on wikipedia: Data URI scheme.
Depending on whether the mail client supports it, you could in theory use the data URI scheme, like so:
<img src="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />
Again, the support is mail client dependent. Some might not support it at all. Some might truncate after a X amount of bytes. Etcetera. As far as I know there aren't many of them. Further I don't see another ways to inline images in HTML like that. Until the support is widespread, your best bet is really to send the images along as an attachment.
Update as per the OP's update: well, most of the modern webbrowsers supports it. The aforementioned Wikipedia link even mentions them in detail.
Data URIs are currently supported by the following web browsers:
Gecko-based, such as Firefox, XeroBank, Camino, Fennec and K-Meleon
Konqueror, via KDE's KIO slaves input/output system
Opera (including devices such as the Nintendo DSi or Wii)
WebKit-based, such as Safari (including on iPhones), Android's browser, Epiphany and Midori (WebKit is a derivative of Konqueror's KHTML engine, but Mac OS X does not share the KIO architecture so the implementations are different), as well as Webkit/Chromium-based, such as Chrome and Iron
Internet Explorer 8: Microsoft has limited its support to certain "non-navigable" content for security reasons, including concerns that JavaScript embedded in a data URI may not be interpretable by script filters such as those used by web-based email clients. Data URIs must be smaller than 32 KiB.
Note that IE8 truncates the string after 32KB. So, as long as the images aren't that large, you could use the data URI scheme for IE8 users. It's not supported on IE7 and lower.
I am not aware of a way to accomplish what you're after with 100% certainty it will work.
Is there a way to forgo the images? Perhaps an ascii representation instead? (something like this http://www.text-image.com/)
The archive would be the only "single file" option that I'm aware of.
You cant execute javascript from a mail client. You can inline the images, but you will need a library because doing it by hand is non-trivial.
You should just send them a link.
Why don't you just link the images with relative paths, and bundle them in a folder with the html file and send it archived and compressed (zip or tarball, depending on preference)?
If you just want to send one file, just zip it using your favorite compression program.
You should never, under any circumstances, send email whose body is HTML. Send plain text mail with the images as MIME attachments, or better yet, put the images on a website (I hear Flickr is quite good ;-) and send them URLs.
I'm going to say it again, because it needs to be said more often: email must be plain text.