Tab CompletionTab Atkins Jr.email@example.com://www.xanthir.comhttp://www.xanthir.com/2013-11-06T18:09:59+00:00All content is published in the public domain, or optionally may be licensed under the CC0 license.http://www.xanthir.com/b4Su0Explaining The Last Clause of the <code>src-n</code> Grammar2013-11-06T18:09:59+00:002013-11-05T22:09:00+00:00<p>Since I've been shopping the <a href="http://tabatkins.github.io/specs/respimg/Overview.html" title="">src-n proposal for responsive images</a> around, people have had some OPINIONS.<p>The first two parts are pretty simple: we got Media Queries, and we got "simple" srcset (a list of image urls and pixel densities). Everyone's behind that stuff, it's easy, no problem.<p>What people have been complaining about is the last part of the grammar, described in the <a href="http://tabatkins.github.io/specs/respimg/Overview.html#viewport" title="">Variable-Sized Images section</a>.<p>People who haven't studied the use-cases gathered by the RespImg folks don't understand what this branch of the syntax does, and decry its complexity. It's really quite easy to defend, though. It's a compact way of expressing all the information you need to handle multi-resolution images of <b>variable size</b>. The image might vary based on the viewport width (for example, it might fill 100% of the viewport), or it might vary based on your layout breakpoints, as you deliver differently styled pages to small and large screens.<p>The spec itself does a good job at defending its usefulness in the simplest case, when your image is a percentage of the viewport. That looks something like this:<pre class='code'><img src-1="100%; 400.jpg 400, 800.jpg 800, 1600.jpg 1600"></pre><p>This isn't too hard to read - the first part, before the semicolon, says that the image's width will be 100% of the viewport's width. The second part is just a list of images, but rather than giving each a density descriptor, it just provides their width in image pixels.<p>The browser uses these two pieces of information to figure out the <i>effective density</i> of each source image, and chooses which to download based on that. For example, on an iPhone with a 320px viewport, the first source is effectively 1.25x, while the second is 2.5x. On the other hand, on a 1000px-wide laptop screen, the second source is .8x and the third is 1.6x.<p>Doing the same thing with srcset is possible, but it's verbose, especially if you want to future-proof things well to cover densities from .5x (potentially useful for downloading things quickly over a slow mobile connection) up to 3x (some devices on the market now are hitting this point now) and higher. The spec has an example of this.<h2>More Complex Examples</h2><p>What the spec <i>doesn't</i> have, because I didn't want to spend the time writing it, is an example of just how verbose <code>srcset</code> gets when you have a more complex example. Here's a pretty basic one:<pre class='code'><img src-1="100% (640px) 50% (960px) 33%;
160.jpg 160, 320.jpg 320, 480.jpg 480, 640.jpg 640,
960.jpg 960, 1280.jpg 1280, 1920.jpg 1920"></pre><p>Here, the first part is a bit more complex. It says that your layout has two breakpoints, at 640px and 960px, where your layout changes. In the smallest layout, this image will be presented at 100% of the viewport width, in the next it'll be 50% (a two-column design, perhaps), and in the largest it'll be 33% (a three-column design).<p>Reading this requires a little bit of knowledge, but nothing crazy. You need to know how the syntax works, but it's easy, and once you do, it's really simple to see what's going on. Importantly, it's also really easy to maintain - if your breakpoints change, or you add more, the necessary modifications to this syntax are small and obvious.<p>Here's the same thing expressed using <code>srcset</code>:<pre class='code'><img srcset="
320.jpg .89x 400w, 480.jpg 1.33x 400w, 640.jpg 1.78x 400w,
480.jpg 1.04x 520w, 640.jpg 1.39x 520w, 960.jpg 2.09x 520w,
640.jpg 1.1x 639w, 960.jpg 1.66x 639w, 1280 2.2x 639w,
320.jpg 0.89x 800w, 480.jpg 1.33x 800w, 640.jpg 1.78x 800w,
480.jpg 1.09x 959w, 640.jpg 1.45x 959w, 960.jpg 2.18x 959w,
320.jpg 0.89x 1200w, 480.jpg 1.33x 1200w, 640.jpg 1.78x 1200w,
480.jpg 1.09x 1440w, 640.jpg 1.45x 1440w, 960.jpg 2.18x 1440w,
480.jpg 0.86x 1920w, 640.jpg 1.14x 1920w, 960.jpg 1.71x 1920w, 1280 2.29x 1920w,
640.jpg 0.86x, 960.jpg 1.29x, 1280 1.71x, 1920 2.57x
"></pre><p>To put it lightly, this is <b>fucking terrible</b>. <br><ol><li>The breakpoints are completely invisible now. (If you look closely, you'll notice the odd width descriptors of 639w and 959w, which is a hint that something different's going on there, but that's an artifact of how they're supposed to match up with the MQs. If they'd been done as 640w and 960w, you wouldn't be able to see the breakpoints at all except by examining the relationship between each segment's max width and the densities of the images.)<li>You have to do non-trivial math to figure out how many divisions to put in each breakpoint (they're split into 3, 2, and 4 sections each).<li>You have to do non-trivial math to figure out the densities at each division - find the average of the min and max viewport widths for the section, then divide the image widths by that value.<li>The knowledge that the image is 100%, 50%, or 33% of the viewport is completely hidden, and can only be recovered by reversing the density back to a width and comparing it to the viewport width limit.<li>It's much less future-proof. This only covers approximately the 1x to 2x range. Smaller and larger densities aren't addressed at all, and doing so makes the markup <i>even more</i> terrible.<li>It's so much less maintainable. Changing any segment limit involves fixing 4-5 NNNw numbers, and adjusting 4-5 densities. changing your layout to use a different image width involves recalculating 10-20 densities, since those are derived quantities.</ol><p>Literally every single aspect of this markup is markedly worse than the <code>src-n</code> alternative. The pain is <i>so great</i> that I don't think it's possible to reasonably argue that forcing authors to do this is better than forcing authors to learn a new microsyntax for <code>src-n</code>.<p>One <i>could</i> try to argue that this use-case isn't valuable enough to address, but I think the use-case gathering by RespImg folks, especially John Mellor for this particular topic, puts the lie to that. This kind of thing is a reasonable thing for authors to do, and which will be done a decent fraction of the time when responsive images are used at all.http://www.xanthir.com/b4S40Apache Allow/Deny/Order Directives2013-09-16T21:46:24+00:002013-09-16T21:33:37+00:00<p>This is mostly just a helpful note to my future self, but hopefully will help others who are frustrated with the shitty documentation of these Apache directives on the net.<p>The Allow directive takes an IP address or a hostname, like <code>Allow from 127.0.0.1</code>. The Deny directive does the same thing, but with the word <code>Deny</code>.<p>If a request matches at least one Allow directive and no Deny directives, it's allowed. If it matches at least one Deny and no Allows, it's denied.<p>If a request matches at least one of each, or matches none of them, the Order directive determines the default action. <code>Order Deny,Allow</code> allows requests in these two situations, while <code>Order Allow,Deny</code> denies them.<p>The ordering of these directives has no effect, but traditionally the <code>Order</code> directive is put first, followed by the Allow and Deny ones.<p>If all you want to do is deny a few IPs, you can get by with just:<pre class='code'>Order Deny,Allow
Deny from 127.0.0.1
Deny from 127.0.0.2
...</pre><p>This'll deny the specific things you want to kill, and then allow everything else by default.<p>Note to self: NearlyFreeSpeech doesn't allow access control via .htaccess, due to their network architecture. Instead, set them up in the Site tab, under "IP Access Control".http://www.xanthir.com/b4Re0Sublime Feature of the Day: Multi-Paste?2013-08-22T00:51:05+00:002013-08-22T00:51:05+00:00<p>(Question mark in title because I'm not sure what to call it.)<p>Sublime Text has a cool niche feature where you can have multiple selections. Just hit Alt+Shift+Up/Down, and you'll spawn a second cursor in the line above/below your current one. This is useful when you have some code or other data organized into a nice structure, and you want to make the same edits across multiple lines.<p>What I just discovered today, though, was that multi-select intelligently handles copy/paste, too.<p>I had a list of urls, and I needed to wrap them in <code><a></code>s so that they both linked to the url and displayed it as their text.<ol><li>Kick off a multi-select for all the lines.<li>Highlight all of the urls (they were all the same length, luckily)<li>Ctrl+C<li>Move back to the beginning of the lines and start typing the <code><a href=""></code> part (every line gets this)<li>Move the cursors to between the <code>""</code> in the attribute.<li>Ctrl+V<li>Boggle.</ol><p>IT JUST MAGICALLY WORKED. Each line pasted the data from its respective line, rather than (as I feared might happen), each pasting in the entire set of urls, or maybe all pasting the first or last url.<p>Sublime is one of those delightful and rare programs that just does what you want a surprising amount of the time.http://www.xanthir.com/b4RS0Translating an old spec to the new processor2013-08-09T23:55:38+00:002013-08-09T02:02:39+00:00<p>This post records the conversion experience of taking a large, complicated older spec (CSS Image Values Level 4) and putting it on my new preprocessor.<ol><li>Adding the metadata, as usual, is easy. Had to look up what the required keys are, but that's what the docs are for. <li>Stripped out a bunch of boilerplate, as usual. Deleting stuff, yay!<li>Spent a long while converting over to Markdown-style paragraphs. This isn't necessary, but it makes the source prettier.<li>Run some regexes to convert older markup patterns into the new shortcuts, like <code>''&lt;foo>''</code> to <code><<foo>></code>. These are simple, but do produce a few bits of weirdness that I fix as I go along.<li>Adjusted all of my function definitions. Previously, they looked like <code><dfn id=foo-type>&lt;foo></dfn> = foo(...)</code>. To make autolinking work better, I switch them to <code><dfn>foo()</dfn> = foo(...)</code>. Still unsure if I want to have a type for functions like this - maybe an auto-genned one, so <code><<foo-function>></code> first tries to autolink to <code><dfn>foo()</dfn></code>?<li>While I'm at it, just remove the manually-specified IDs from nearly every definition. The auto-genned ones are fine. (The main reason I had so many defined was because the old processor didn't include the definition type in the id, so there were more collisions.)<li>Convert all the propdef tables into the <code><pre class=propdef></code> format. Simple and easy, and makes the source prettier.<li>Finally, fix up all the value definitions. Change them all to be just <code><dfn>foo</dfn></code>, and add <code>dfn-type=value dfn-for=foo</code> to their containers, so I don't have to specify that stuff manually on each.<li>All right, reached the bottom, cleared out the last of the boilerplate. Run the processor for the first time... and hit errors. This is expected. Run it with <code>--debug</code> to see how bad it is, and it's <i>bad</i>. Gulp.<li>Actually, not all that bad. I ignore all the warnings at first, and just deal with the errors one by one. They're real errors in my document - things marked up wrong, multiple definitions of the same term, attempted links to terms that aren't defined, etc. A few are attempted links to terms that don't exist <i>in other specs</i>, but should. I mark these as ignored for now by putting them in an "Ignored Terms" metadata, so I can deal with them later. This all takes about 20 minutes to do, but it's useful work.<li>Okay, now time for the warnings, all about the processor having multiple specs defining a term and not being able to decide which to choose. Some were between CSS2.1 and a spec that replaces part of that, so I added those to <code>autolinker-config.md</code> to the "CSS 2.1 Replacements" section. One was split between the real definition and an "additional values" definition, which I don't auto-handle yet, so I added it to the the autolinker config too. Another was split between the real definition and a duplicate definition in another spec, done solely to hack around the lack of cross-links. Another addition to the autolinker config.</ol><p>And that's that! Spec now processes cleanly, with no warnings or errors.http://www.xanthir.com/b4RR0A New SVG for SVG22013-08-08T20:52:52+00:002013-08-08T20:52:52+00:00<p>Cameron McCormack, one of the chairs of the SVG Working Group, just posted <a href="http://dev.w3.org/SVG/proposals/improving-svg-dom/" title="">some proposals for revamping the SVG DOM</a> (Document Object Model - the JS API for interacting with the elements in the page).<p>I think the ideas are pretty great! They boil down to a few basic proposals:<h2>Put all the SVG elements into the HTML namespace</h2><p>This is the core of the idea, and I'm in favor of it for several reasons.<p>For one, it means <b>FUCK NAMESPACES</b>. While the <i>concept</i> of namespaces is great, and the execution of them is good in most languages (see: Python modules), XML namespaces are <i>terrible</i>. They're verbose, hard to remember, and pollute everything with bullshit like <code>createElementNS()</code>. By putting all of the elements into the HTML namespace, we can just <i>ignore</i> the namespace, since the HTML DOM already just assumes everything is there.<p>For two, it gives us a nice hook for attaching brand new interfaces to elements with the same name. Two elements of the same name in different namespaces are technically <i>different elements</i>, and can have different classes representing them. We've been looking for some kind of hook or Big Red Switch to throw away the old SVG DOM for a while, and this particular switch accomplishes that goal, and is a great idea all by itself.<p>For three, it lets us do a little spring cleaning and get SVG to match the conventions of HTML. Way back in the day, SVG and HTML were competing in the standards marketplace to be the language you wrote documents in. That battle was decided a long time ago, though, and HTML won. SVG is now a fancy and useful image format, and integrating itself more tightly into HTML rather than standing on its own will only help it. For example, we can make all the element and attributes names case-insensitive, like HTML, and maybe rename a few attributes that have migrated into CSS properties to match the CSS spelling (using dashes instead of casing to indicate word boundaries).<p>For four, it lets us more easily just slot into the HTML parser. I often end up writing my SVG pages in HTML by just adding a <code><!doctype html></code> to the top of it, because that lets me use unquoted attributes. (Such a small thing, but so annoying to not have...) Since SVG elements are now in the HTML namespace, we can just use the HTML parser <i>all the time</i>, and drop HTML elements directly into the page. (This still isn't trivial, as we have to define the rendering model for non-SVG elements. This is something CSS can do, though, and it's long overdue anyway.)<h2>Throw Away the Old SVG DOM</h2><p>We all know that HTML's DOM is terrible - it was written at a time when Java was expected to be a major web language and JS was just a toy script, so there's tons of super-clumsy idioms which don't make sense today.<p>SVG, though, is a whole 'nother ballpark here. It grew up in the same environment, but got even more attention from standards people back when, so it grew <i>even more</i> arcane and clumsy shit.<p>For example, many SVG attributes can be animated. To handle this, the SVG DOM doesn't expose those attributes as normal values. Instead, they're a special object with <code>.baseVal</code> and <code>.animVal</code> properties. This makes for a really, um, <i>special</i> way of interacting with the DOM. Some properties you can just set directly to a value, while others you have to indirect through <code>baseVal</code>, and you just have to memorize which is which by yourself. (To get around this, I almost always ignore the interface and just read/set attributes via <code>get/setAttribute()</code> calls, because it's predictable.)<p>In the new HTML-namespaced SVG elements, though, we can throw all that away and start fresh. Properties can go back to just reflecting their value, with animation layered on with a separate mechanism, like CSS does.<p>SVG also invented a bunch of <i>bizarre</i> classes for things. For example, there are a bunch of array-like classes which all reflect their length with a <code>.numberOfItems</code> property. Yes. <code>.numberOfItems</code>. Not <code>.length</code>.<p>We've learned a lot about how to design user-friendly interfaces for things like these in the past two decades, and WebIDL (the specialized programming language we use to specify classes and whatnot in DOM) has grown to reflect these. Cameron is the editor of WebIDL, so he's in a great position to redesign this stuff properly.<h2>Innovate in some new Author-friendly APIs</h2><p>Two big things that are planned with the new SVG DOM will make it much easier to interact with some of the most complex bits via CSS.<p>The first is reflecting a bunch of attributes that currently take lengths, angles, and similar values as something more intelligent than strings. It's silly that you have to parse the string <code>"3em"</code> yourself and figure out what the width of an <code>em</code> is if you want to match it with something in pixels - the browser has all of this information already, and can do it for you much more efficiently!<p>This is similar to something we've toyed with for a long time in CSS, which does the same thing - reflecting CSS properties as something more than just a string. I'm going to make sure that SVG and CSS evolve together on this so you don't have to learn two ways to do the same thing.<p>The second is producing a more convenient API for creating/adjusting a <code><path></code> element. <code><path></code> has always used a somewhat bizarre, super-compact format for specifying how it twists and turns. Modifying this directly as a string is horrible, but so was the over-engineered API that you could alternately use.<p>SVG plans to add a new more convenient API for building up a path, possible by taking the existing Canvas API and adding to it as necessary for the missing commands. (Separately from this, we're also adding some new commands to <code><path></code>, particularly for doing circular/elliptical arcs more conveniently. Lessons learned from JS libraries!)<p>Maybe this could lead to just layering the Canvas API directly on top of the new <code><graphics></code> root, so you can easily do retained-mode graphics with the same moderately convenient syntax? TIME WILL TELL.<p>Anyway, I'm uncomfortably excited about all of this.