tl;dr: Click this, type some stuff, watch the URL, and then come back if you’re curious as to what’s going on.
Ok, quick recap:
- Data URIs allow for inline resource inclusion without additional HTTP requests. Among other things, this allows for writing content directly to the address bar, and it’s the way my tmpltr app exports stuff.
- HTML5 has a
contentEditable
attribute that can turn anything into an input. - And somebody clever (@tabatkins, according to @paul_irish) took to combining the two to make “the world’s smallest text editor“:
data:text/html,<pre contenteditable></pre>
I was pretty enamored by that and used a variant of it at work for awhile to jot down my notes during the day. Like all tinkerers, I couldn't leave well enough alone, and so here's my fancier but definitely-not-the-smallest-and-so-not-as-novel version:
Breakdown
Mine uses a textarea
instead of a contenteditable <pre>
, since it's made to be fullscreen and thus doesn't need contenteditable
's auto-adjustment to variably dimensioned content. (Actually, the one regret is that my text editor now won't use any of the HTML5 spec and so is not as trendy... Sniffle, sniffle.)
So we've got a fixed and fullscreen input. We'll use its first line (if it has one) as the document title and bind a debounced* function to its keyup
event. When the function executes successfully, we write a new URL using the existing body's HTML, the input's encoded value, and its caret/selection position, and then we'll redirect the user to it, setting the caret position and repeating the process indefinitely.
* Debouncing is a method of rate limiting. It takes a time duration and waits that long after each firing to run, resetting and delaying execution if fired before the duration is up. Its more common sibling is throttling, which will run at most once per time duration while firing and will not reset.
Unordered, Non-Narrative Findings
- If the software and its data share the same limited storage mechanism, brevity must trump legacy support: no CSS3 vendor prefixes, not a lot of feature sniffing or graceful degradation, etc. All JS is vanilla and doesn't use external libraries.
- Like local files, Data URIs are prohibited from a number of things for security reasons; cookies, localStorage/sessionStorage, and any history manipulation are out the window. Thus, there's no saving beyond the URL and updates happen with old-fashioned redirects instead of the cooler
pushState
. - I'm storing caret position as just a
c
attribute to save some bytes. There may be a better way to do it, and I'm not sure what the technical implications are for arbitrary attributes like that instead of, say, a data attribute. - Dirty/clean save status is handled with a CSS class to gray out the text and use the wait cursor. May be overkill.
textarea
s have bothvalue
andinnerHTML
. At init they are the same, but onlyvalue
changes as the user interacts with it; no HTML is changed. Because we're using the body'sinnerHTML
to rewrite the URL, we must set the input'sinnerHTML
to itsvalue
,encodeURIComponent
ed for safety.- Nobody will call the cops if you don't close your
body
tag.
Still Could Use...
- Different browsers have different URL limits. Ideally, this would have some sort of reservoir meter.
- Code and markup is properly escaped, but trying to save anything with
</textarea>
will effectively close the input and bork all the text thereafter. It escapes me how to get around that at the moment... - Safari takes a couple microseconds to focus an element and won't allow caret setting while it's unfocused, so there's some awkward and redundant
setTimeout
stuff in there to give it some time. I'd like for that to be less crummy.
Unavoidable Gotchas
- Data URIs aren't supported in IE. Tested successfully in Chrome, Firefox, Safari, and Opera.
- Undo and redo can't persist over redirect. (But, interestingly, you can use native back and forward to kind of view the text's history.)
- Browsers can interpret Data URIs, yes, but most software won't automatically turn them into links like traditional HTTP URLs. So copy-and-pasting into chats will always have to be prefaced with "Hey, copypaste this into a new tab, k?"
How is this useful?
Honestly? Probably only as an academic pursuit.
But try this: open it up and write something, copy the URL and paste it into another tab or browser. Your text persisted without a database, any external script, or proprietary Cloud gizmo. No legal order can cease it to exist, and you didn't even need an internet connection. I think that's pretty neat!
5 Responses to An Auto-Updating Data URI Text Editor
Pingback: Convierte tu navegador en un bloc de notas | MolinaSoft