With Data URLs we can incorporate images in layout or CSS.
The schema is really simple:
data:[<mediatype>][;base64],<data>
Since we need to specify a mediatype we could play around creating something unexpected ;-)
My Silly Idea
If we select something in a web page we can perform different actions via right click. So far so good ... but one thing we are missing, at least in Firefox, is a "Save As" option. If we want bring a piece of code, text, something else, into another software or editor we need to select, right click, copy, open or find the editor, right click, paste.The ultra skilled developers goes well with ctrl+c and ctrl+v but there are still 3 operations to do: copy, find the destination, paste
What about making possible to simply save that part and go on reading or surfing in order to do not distract too much our lecture and review eventually later that piece of text or code?
Firefox Inline Download
function download(text){
// Yet Another Silly WebReflection Experiment
var iframe = document.createElement("iframe");
iframe.src = "data:application/octet-stream;base64," + btoa(text);
iframe.style.position = "absolute";
iframe.style.top = "-10000px";
document.documentElement.insertBefore(
iframe,
document.documentElement.firstChild
);
};
download("Hello World :-)");
If we have configured Firefox to ask us where to save files, we can even choose the name. Being the inline data protocol that simple, unfortunately I could not find a way to name the file. The concept in any case is simple, we could create a bookmark or a link able to save the selected text, if any.
In this case we select, and with a click we can directly organize the content in a named file or we can open it with the editor that will be probably the first option in the Open With question.
Side Effects
Well, the first one is that I am not even sure if this could be considered a security problem, and I am testing in Firefox 3.6 beta 2 (so I am not even sure this is possible with other versions).We cannot remove the iframe until the user has saved the content and never before the save dialog will be showed, otherwise a generic onload will remove the content before Firefox can understand what to do.
On the other hand, since the content will be inline, the "Open With" should always work 'cause Firefox, which is a clever browser, saves and eventually remove, even if we cancel the operation.
I really like these tricks. It is working in Firefox 3.5.5 too... In IE8, after enabling ActiveX, I got an error about a connection attempt failing (then after refreshing, I didn't get any messages)...In Opera 10 and 10.01 and Chrome 3.0.195.32 and 3.0.195.33 nothing happened. Worked in Safari 4.0.3 though...
ReplyDeleteNice trick!
ReplyDeleteWhich netbook btw?
ReplyDelete@Brett IE can't work for both missed btoa function and iframe rather than <iframe><iframe/> in document create
ReplyDelete@alsanan, Samsung N510, so far extremely happy about this choice ;)
Besides saving snippets, I can see uses in HTML-based IDEs (e.g., I've added your code to my very primitive and unfinished XML editor at http://www.assembla.com/wiki/show/brettz9 -- I hope the likes of this can allow attribute editing and also be merged with a schema parser at some point) or even saving remote files made available via Ajax. Yes, the latter saving of files can be done with server-side code already, but it could be convenient for a file browser to automatically make the pages of a site easily available for download via its own interface (e.g. Gopher-style, as my column browser also at the above site aims to do).
ReplyDeleteFrom the Xopus codebase, base64 encoding for IE:
ReplyDeletefunction encode(msg)
{
if (typeof btoa == 'function')
return btoa(msg)
var buffer = [],
padCount = msg.length % 3,
padding = ['', '==', '='][padCount],
str = msg + ['', '\0\0', '\0'][padCount],
base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('')
for (var n, i = 0, l = str.length; i < l;) {
n = (str.charCodeAt(i++) << 16)
+ (str.charCodeAt(i++) << 8)
+ str.charCodeAt(i++)
buffer.push(
base64[n >> 18 & 63],
base64[n >> 12 & 63],
base64[n >> 6 & 63],
base64[n & 63]
)
}
return buffer.join('').substring(0, buffer.length - padding.length) + padding
},
I believe this technique has been used in multiple Opera widgets to provide the ability to download or store data from the widget on the hard drive
ReplyDelete