- From: Aryeh Gregor <Simetrical+w3c@gmail.com>
- Date: Sun, 24 Jul 2011 12:18:27 -0400
- To: W3C WebApps WG <public-webapps@w3.org>
When discussing mutation events use-cases, mostly so far people have been talking about editors. However, I think mutation event replacements would have a much more general appeal if they were easily usable in certain cases with little performance impact. Specifically, one use-case I've run into a lot is "I want to modify some class of node soon after it gets added to the DOM, but before it's actually painted". Examples of where this has come up for me in practice: 1) Some images in Wikipedia articles are offensive to some users, who may want to block them by default. However, we want to serve the same page content to different users for caching reasons, only varying the HTML used for the interface. One way to solve this would be to add classes to potentially offensive images, then have a script run that replaces the image with a placeholder before it's visible to the user. Currently, as far as I can tell, the only way to do this is to put a <script> immediately after the <img>. This could theoretically fail if the <script> winds up getting parsed too long after the <img>, like if it winds up in a different TCP segment that then gets dropped and takes a few seconds to resend while the image loads from cache. More practically, it's incompatible with CSP, which prohibits inline script. It also can't be used in situations like Wikipedia, where administrators can add scripts to the <head> but cannot add inline script. It's also excessively verbose if there are lots of places per page you need to do it. (Actual writeup of requirements, albeit abandoned: <http://www.mediawiki.org/wiki/User:Simetrical/Censorship>) 2) Some pages have content that should be collapsed by default with a way for the user to un-collapse it, but they should be uncollapsed if the user has script disabled, since otherwise the user won't be able to access the contents. This is true for some Wikipedia infoboxes, for instance. <details> might solve this use-case without the need for script, but it might not (e.g., styling might not be flexible enough). Supposing it doesn't, the way you'd currently have to do this is add a <script> right after the opening tag that collapses it and adds the uncollapse button. But again, inline script is incompatible with CSP, and incompatible with setups like Wikipedia where you might not be allowed to add inline script, and excessively verbose if there are many occurrences per page. 3) In current HTML drafts, <details> auto-closes <p>. I just filed a bug asking that it be made an inline element that doesn't auto-close <p>: <http://www.w3.org/Bugs/Public/show_bug.cgi?id=13345>. I want this because smaug complained that my specs didn't contain rationale, and when I pointed out that I had detailed rationale in comments, he said I should make it visible to the reader. So I want to have inline <details> at the end of some <li>'s or <p>'s. If the change I request is made, <details> will still auto-close <p> in current browsers, so I'd want to work around that with a shim for browsers using the current HTML parser. The obvious thing to do would be to run some script after every <details> is added that's the next sibling of a <p>, and move it inside the <p>. Again, this would require a lot of repetitive use of <script>. 4) Prior to the invention of the autofocus attribute, just like in all the cases above, the only way to reliably autofocus inputs was to add a <script> immediately after the <input>. This case is moot now that autofocus exists, but it illustrates that there are more use-cases in the same vein. What would solve all of these use-cases is a way to register a handler that would get notified every time an element is added to the DOM that matches a particular CSS selector, which is guaranteed to run at some point before the element is actually painted. Thus it could be a special type of event that runs when the event loop spins *before* there's any opportunity to paint, or it could be semi-synchronous, or whatever, as long as it runs before paint. Then I could easily solve all the use-cases: 1) Register a handler for "img" that changes the .src of the newly-added Element. 2) Register a handler for ".collapsed" or whatever that sets the appropriate part to display: none and adds the uncollapse button. 3) Register a handler for "p + details" that moves the <details> inside the <p>. (This would be trickier if I sometimes put <details> in the middle of <p>, but still doable, and anyway I don't plan to.) 4) Register a handler for ".autofocus" or whatever that calls focus(). It seems to me this dovetails pretty nicely with some of the proposed mutation events replacement APIs. Specifically, people have been talking about allowing filtering of events, so this use-case should be solved easily enough if you can use CSS selectors as filters. In that case, the perf hit from using such events should be negligible, right? I think there are lots of cases like the four I gave above where this sort of API would be handy for very general-purpose websites, not just special cases like editors. I know there are more times than this that I've wished I had such an API. This will be especially true once CSP becomes more mature and we want to encourage authors to move away from using inline script -- in these use-cases, there's no existing replacement for inline script.
Received on Sunday, 24 July 2011 16:19:13 UTC