Re: [whatwg] a onlyreplace
On Sat, 31 Oct 2009, Rowan Nairn wrote: I want to provide an animated page transition that doesn't break the back button or the URL bar and degrades gracefully in non-javascript UAs. You can see an example of this at http://mrtaggy.com/ . This is a site I launched last year that uses animations to show transitions between search result pages. Leaving aside whether you like this particular set of animations, I think you'll probably a agree that animations are used well in many applications to help users keep track of change. It would be nice if this was easy to do on the web. This seems like a presentation-level feature -- I'd recommend raising this with the CSS working group. It might make sense to provide the CSS transition module with a hook for page transitions as well as the transitions it does now, for instance. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
[whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 4:30 AM, Ian Hickson ian at hixie.ch wrote: My recomendation would be to follow the process for adding features: http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F In particular the bit about experimental implementations. I think this idea looks very interesting, but it's hard to evaluate without concrete experience with a browser implementing this (or, as Jonas suggests, a library that hacks it in). It seems like the kind of thing that we could adopt early on in the next feature cycle, if it turns out to be a good solid model. Yup, was planning on this. Just wanted to hack it out on the list first before jumping down any rabbit holes. If nobody beats me to it, this should be relatively easy to hack in (and may already be hacked in in some form, via mooTools?). ~TJ Hi Tab, I was just about to propose something similar so I was happy to find the recent discussion of onlyreplace on the mailing list. (Should have gotten around to it before Last Call, doh!) My use case is slightly different than yours. You want to do AJAXy replaces without javascript. I want to provide an animated page transition that doesn't break the back button or the URL bar and degrades gracefully in non-javascript UAs. You can see an example of this at http://mrtaggy.com/ . This is a site I launched last year that uses animations to show transitions between search result pages. Leaving aside whether you like this particular set of animations, I think you'll probably a agree that animations are used well in many applications to help users keep track of change. It would be nice if this was easy to do on the web. I was going to propose a similar attribute on links and forms but I hadn't envisioned the automatic scheme from replacing sections of pages. I think the automatic algorithm is great and necessary but I also think it would be useful to let developers customize the transition from one view to another. One way to do this might be a new event, onpagereplace or something, that fires when an onlyreplace link is clicked. If you don't preventDefault() then the automatic algorithm for replacing sections would run. If you do then you can customize the transition yourself. The way this is implemented in MrTaggy is with a hidden iframe. Certain links target the iframe (btw, this suggests that onlyreplace could instead be target=_replace) and an onload event on the iframe triggers the code that animates the transition from the old view to the new. The page that loads in the iframe is a full results page so without javascript (and no hidden iframe) every thing works fine. Also the back button works on all browsers, old and new (try adding a tag to an existing query and then clicking back). The only problem is that the URL bar does not update. Ultimately I made the difficult decision that back/forward was more important than bookmarking/link sending/etc. You can't have both in legacy browsers. ...which is where the (future) spec comes in. I'd love to see this made easier. pushState is fine but it doesn't degrade gracefully like this and it seems a bit too general even. Part of the attraction of onlyreplace+transitions is it forces developers to think about progressive enhancement of pages that work fine without javascript. Let me know if I can help with your formalization efforts. Rowan
Re: [whatwg] a onlyreplace
Hi there, That onlyreplace attribute is not enough, and trust me, I have spent quite a while on solutions transforming HTML documents using bits contained in external instances... Hixie referenced at some point in the thread my HTMLOverlays proposal [1] and that proposal has a clear plus compared to the onlyreplace attribute: it's not meant to ONLY replace but ALSO to add elements to an existing container, using an order defined by the web author and not only appending overlaid elements. That's a _major_ win compared to onlyreplace. I am not saying here that onlyreplace is a bad idea, it's even a very good one. And I find VERY amusing to read super-positive comments about it that are exactly contrary to comments I received myself on HTMLOverlays while the two proposals are rather similar :-) That said, there are a few problems to solve: - what means exactly replacement here? What's the scope of a script element? - what does it mean for stylesheets and scoped stylesheets? - what does it mean for the root of the replaced subtree? Let's call that the bound element and the binding : how are deferred to the subtree even handlers attached to the bound element? - I don't like a onlyreplace because that works only with elements inside the body of a document. I want a generic mechanism that can apply to elements in head too... - I think a mechanism using a link element is better because it's similar to prefetching. It's also semantically better because it used a _very_ old proposal of mine called link dereferencing [1]. And of course it is better because it can help resolving the progressive rendering issues of a onlyreplace since the head is parsed before the body... [1] http://disruptive-innovations.com/zoo/20040830/HTMLoverlays.html [2] http://www.w3.org/Submission/1997/12/ /Daniel
Re: [whatwg] a onlyreplace
Daniel Glazman schrieb: Hi there, That onlyreplace attribute is not enough, and trust me, I have spent quite a while on solutions transforming HTML documents using bits contained in external instances... Hixie referenced at some point in the thread my HTMLOverlays proposal [1] and that proposal has a clear plus compared to the onlyreplace attribute: it's not meant to ONLY replace but ALSO to add elements to an existing container, using an order defined by the web author and not only appending overlaid elements. That's a _major_ win compared to onlyreplace. I am not saying here that onlyreplace is a bad idea, it's even a very good one. And I find VERY amusing to read super-positive comments about it that are exactly contrary to comments I received myself on HTMLOverlays while the two proposals are rather similar :-) They are crucially different in some points: - HTMLOverlays is a ready-to-use script solution. It does not require any specification nor implementation by UAs. Instead, it requires work on the authoring side; using HTMLOverlays means totally re-writing your websites. - HTMLOverlays does not degrade nicely. If a UA does not support scripting, or the script is not found for any reason, there is no way to render the page in a useable manner. This also applies to search engines, which will not see anything that is part of the overlay - this will typically apply to the whole navigation. That said, there are a few problems to solve: - what means exactly replacement here? What's the scope of a script element? - what does it mean for stylesheets and scoped stylesheets? - what does it mean for the root of the replaced subtree? Let's call that the bound element and the binding : how are deferred to the subtree even handlers attached to the bound element? - I don't like a onlyreplace because that works only with elements inside the body of a document. I want a generic mechanism that can apply to elements in head too... Are you sure about that? I assumed this was valid: html head title id=titleMy title/title style id=mystyle @import url(mystyle.css); #contents h2 { color:red; } /style script alert(This one is not replaced); /script script id=script2 function foo() { alert(bar); } /script base onlyreplace=title mystyle script2 contents /head body ul id=navigation lia href=otherpage.html onlyreplace/li /ul div id=contents pText/p div /body /head Anyway, it might be reasonable to always replace the title element, as it is recommended to have individual titles for every page, and looks like an overkill to give this unique element an id, just to reference it in the onlyreplace list. - I think a mechanism using a link element is better because it's similar to prefetching. It's also semantically better because it used a _very_ old proposal of mine called link dereferencing [1]. And of course it is better because it can help resolving the progressive rendering issues of a onlyreplace since the head is parsed before the body... Can you give a code example how this could look like?
Re: [whatwg] a onlyreplace
Looking at this (simplified) example from Markus: html head title id=titleMy title/title base onlyreplace=title /head body ul id=navigation lia href=otherpage.html onlyreplace/li /ul div id=contents pText/p div /body /head Would it be better to be able to specify multiple onlyload base elements? Like so: html head title id=titleMy title/title base id=onlyreplace1 onlyreplace=title base id=onlyreplace2 onlyreplace=contents /head body ul id=navigation lia href=otherpage1.html onlyreplace=onlyreplace1Replace the title/a/li lia href=otherpage2.html onlyreplace=onlyreplace2Replace the content/a/li /ul div id=contents pText/p pa href=otherpage2.html onlyreplace=onlyreplace2Replace me/a/p div /body /head That way it gives authors much more control over that they choose to be replaced. This does mean that the onlyreplace attribute on links (and forms) should perhaps be renamed onlyreplaceref or similar. Has this idea already been put forward by someone else? (I may have missed it). Chris This message has been scanned for malware by SurfControl plc. www.surfcontrol.com
Re: [whatwg] a onlyreplace
Markus Ernst wrote: They are crucially different in some points: - HTMLOverlays is a ready-to-use script solution. It does not require any specification nor implementation by UAs. Instead, it requires work on the authoring side; using HTMLOverlays means totally re-writing your websites. It's ready as a script, yes, and that is absolutely not satisfactory. It's so simple that it could be specified and implemented by browsers. - HTMLOverlays does not degrade nicely. If a UA does not support scripting, or the script is not found for any reason, there is no way to render the page in a useable manner. This also applies to search engines, which will not see anything that is part of the overlay - this will typically apply to the whole navigation. Agreed, and that's why I think a standardized solution is better. - I think a mechanism using a link element is better because it's similar to prefetching. It's also semantically better because it used a _very_ old proposal of mine called link dereferencing [1]. And of course it is better because it can help resolving the progressive rendering issues of a onlyreplace since the head is parsed before the body... Can you give a code example how this could look like? Sure. That only requires to extend the rel attribute to any element. Semantically, it's perfectly ok since onlyreplace is really establishing a link of some sort to a potentially external resource. head link id=myreplacement rel=prefetch href=http://www.example.com/foo.html#bar/ /head body p rel=replace src=#myreplacement/ /body /Daniel
Re: [whatwg] a onlyreplace
On Thu, Oct 22, 2009 at 1:56 AM, Daniel Glazman daniel.glaz...@disruptive-innovations.com wrote: Hi there, That onlyreplace attribute is not enough, and trust me, I have spent quite a while on solutions transforming HTML documents using bits contained in external instances... Hixie referenced at some point in the thread my HTMLOverlays proposal [1] and that proposal has a clear plus compared to the onlyreplace attribute: it's not meant to ONLY replace but ALSO to add elements to an existing container, using an order defined by the web author and not only appending overlaid elements. That's a _major_ win compared to onlyreplace. I actually consider that a loss. It's addressing a different problem, you see. HTMLOverlays is basically client-side includes. While you can hack it into solving a similar problem to @onlyreplace, that's not its primary purpose and the bookmarkability seems like it would be poor. (Note - bookmarkability of abusing htmloverlays as a navigation mechanism, not of using them as intended.) @onlyreplace is simply a way of specifying slightly different navigation semantics on your links. The original page load is the same as normal (unlike HTMLOverlays, where the initial request is a partially-empty page), and navigation is what's changed (unlike HTMLOverlays, which utilize normal navigation and just slot in the overlays again on pageload). Different solutions to different problems. I am not saying here that onlyreplace is a bad idea, it's even a very good one. And I find VERY amusing to read super-positive comments about it that are exactly contrary to comments I received myself on HTMLOverlays while the two proposals are rather similar :-) I think that's because we're doing different things, like I said. ^_^ There's a very small target in the problem-space I'm working in that's good, while nearly everything else is bad. If people interpreted HTMLOverlays as solving the same problem as what I'm trying to solve with @onlyreplace, then yeah, it's a bad solution. It may be fine at solving its own problem. That said, there are a few problems to solve: - what means exactly replacement here? What's the scope of a script element? replacement is semantically identical to setting outerHTML on the target elements. I'm not sure what you mean by scope of a script element. - what does it mean for stylesheets and scoped stylesheets? Nothing special. - what does it mean for the root of the replaced subtree? Let's call that the bound element and the binding : how are deferred to the subtree even handlers attached to the bound element? The entire subtree is replaced, root and all. Event handlers attached to the root or any child are lost. Either reregister them in the swapIn event, or use event delegation on an ancestor. - I don't like a onlyreplace because that works only with elements inside the body of a document. I want a generic mechanism that can apply to elements in head too... Hm? There's nothing about @onlyreplace that only works for body elements. Where did you get that impression? (I'd like to know so I can reword things if needed.) As long as an element has an id it can be replaced. - I think a mechanism using a link element is better because it's similar to prefetching. It's also semantically better because it used a _very_ old proposal of mine called link dereferencing [1]. And of course it is better because it can help resolving the progressive rendering issues of a onlyreplace since the head is parsed before the body... I think you misunderstand the mechanics of @onlyreplace. It doesn't change anything when you first load a page, and it shouldn't be at all similar to prefetching. It only operates when you click on a link with the @onlyreplace attribute. The browser then makes an ordinary request for the desired page, parses it with scripting disabled, and locates elements with the given ids to swap into the old page. ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. wrote: I actually consider that a loss. It's addressing a different problem, you see. HTMLOverlays is basically client-side includes. While you It's client-side only because I implemented in JS that way! Explain me what prevents from implementing server-side? I think you misunderstand the mechanics of @onlyreplace. It doesn't change anything when you first load a page, and it shouldn't be at all similar to prefetching. It only operates when you click on a link with the @onlyreplace attribute. The browser then makes an ordinary request for the desired page, parses it with scripting disabled, and locates elements with the given ids to swap into the old page. Exactly. And I said this is a good start and not enough. We could do simple AND more powerful than that. /Daniel
Re: [whatwg] a onlyreplace
On Thu, Oct 22, 2009 at 9:47 AM, Daniel Glazman daniel.glaz...@disruptive-innovations.com wrote: Tab Atkins Jr. wrote: I actually consider that a loss. It's addressing a different problem, you see. HTMLOverlays is basically client-side includes. While you It's client-side only because I implemented in JS that way! Explain me what prevents from implementing server-side? Nothing, of course, but then it seems equivalent to any other server-side-include mechanism. It may have a better syntax for many cases (in fact, it looks like it probably does), but it's otherwise relatively unremarkable and doesn't require any changes to browsers. Specifically, it doesn't do anything like what @onlyreplace does. Navigation still involves a complete tear-down and refresh of the page, js state, etc. I think you misunderstand the mechanics of @onlyreplace. It doesn't change anything when you first load a page, and it shouldn't be at all similar to prefetching. It only operates when you click on a link with the @onlyreplace attribute. The browser then makes an ordinary request for the desired page, parses it with scripting disabled, and locates elements with the given ids to swap into the old page. Exactly. And I said this is a good start and not enough. We could do simple AND more powerful than that. Can you elaborate? If you understand @onlyreplace, then you must be hinting at a larger abstraction than I can see currently. To my eyes @onlyreplace and overlays (XUL, HTML, or otherwise) only share some basic surface similarities, in that they both have a replace an element with one from another document with the same id mechanic. The way that mechanic is used, and the effect it has on the page, the UI, the user experience, and the browser is completely different. ~TJ
Re: [whatwg] a onlyreplace
2009/10/19 Schuyler Duveen wha...@graffitiweb.org: I'm starting to think the addressability is the main constraint. What if the original @onlyreplace anchor tag: a onlyreplace=id1 id2 href=page2.html / would be equivalent to something like this: a href=#view(page2.html id1 id2) / which would process onload or onhashchange as we've been describing @onlyreplace and would appear in the browser's location bar. A more complicated one (after two jumps) might look something like: http://example.com/page1.html#view(page2.html id1 id2);view(page3 id3) Then you are putting specific functionality in the hash. And you would have to, to allow bookmarking. But this breaks the semantics of linking, whereby the hash corresponds to a place within the page (which AJAX applications sometimes use to reconstruct some sort of state). What you are suggesting is putting this AJAX pattern in the browser, in a specific format. I'm not keen on solving this problem by changing the way linking works; that was the beauty of the original proposal (other problems notwithstanding). This seems like a fancy way to bookmark frames... Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Mon, Oct 19, 2009 at 5:37 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Mon, Oct 19, 2009 at 1:10 PM, Markus Ernst derer...@gmx.ch wrote: Aryeh Gregor schrieb: But it breaks progressive rendering, which could be extremely annoying. The user might give up after a second or two of no response, as the (possibly quite long) page is fetched and parsed. This is true. So using this as a feature to exclude pages from being onlyreplaced should be discouraged, authors should set onlyreplace to false (resp. not set the onlyreplace attribute) on the links to those pages. The problem I see here (as an author) is that the attribute *will* accidentally get placed where it shouldn't. From the user's point of view, this dramatically slows down clicking the link (making them annoyed at my site), but in a way that's very difficult for me to notice. It's an X% chance that clicking a given link will be inexplicably slow, at random, if I use this feature. The value of X will vary based on all sorts of things, some possibly beyond my control. It's a risk that would definitely count against the feature if I were deciding whether to use it. Actually, though, I think that the problem won't be nearly as bad as you're implying. You're imagining that it takes as long to decide if the requested elements are in the page as it would take to actually render the page. This is *far* from true. Looking at the Net panel data in Firebug for my company's website on a full refresh, actually downloading the page takes only 150-200ms. I'm told that the actual parsing is basically insignificant compared to network latencies. Assuming that the DOM-building proceeds identically to that employed by responseXML (except allowing HTML, as XHR2 says), in the worst-case scenario embedded scripts may run in case of document.write() (though Anne says that he plans to *not* run scripts while parsing HTML into responseXML), but linked scripts won't ever download. And, of course, once the DOM is built checking for ids is trivial. So for a typical page (as I said earlier, my company's page is apparently just on the low end of average) we're looking at response times under half a second. ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. schrieb: On Sun, Oct 18, 2009 at 12:25 PM, Aryeh Gregor simetrical+...@gmail.com wrote: Some attention needs to be given to error handling. What happens if one or more of the requested id's aren't found? Do they silently fail? If so, this could result in the link doing absolutely nothing in hard-to-control situations -- like an error page that occurs sporadically, say a 500. Do they trigger a normal page load? If so, they have to wait until the entire page has loaded, which would be bad user experience but hard to track down -- a long, inexplicable delay followed by everything working normally. This could be mitigated by having an HTTP header to say that id doesn't exist, load the whole page instead, but it would fail in the default case (standard HTTP server unaware of new feature). Also, what happens if some of the given id's are present, but not others? I'll think a bit about these issues today. I'm not sure, off the top of my head, what the best response is. What do you think about: 1. Defining which ids are to be replaced: - The list of IDs to replace is in base tag, as described earlier in this thread. a and form elements can have a boolean @onlyreplace attribute that specifically enables or disables the functionality for the element. - If at least one of the IDs is found in the linked document, replace the IDs that are found. Ignore IDs that are not present in the linked document, or in the document that contains the link (important for dynamic applications, so the head section is not forced to know the state of the body). - If none of the indicated IDs are found, *replace the whole page*. This makes it possible to prevent e.g. a wiki or forum from being @onlyreplaced by just using different IDs. 2. Possible further additions to the base tag: - Explicitly exclude parts of a site from @onlyreplace, e.g.: base onlyreplaceExcludeDir=/wiki /forum /media/downloads - Explicitly specify the links that carry the onlyreplace feature: base onlyreplaceLinkContainers=navigation orderform When we add more attributes to base than just href and target, the sentence There must be no more than one base element per document. in 4.2.3 of the spec should maybe be removed, as for every possible attribute in base there will be a note anyway saying If there are multiple base elements with [attributename] attributes, all but the first are ignored.
Re: [whatwg] a onlyreplace
On Mon, Oct 19, 2009 at 3:49 AM, Markus Ernst derer...@gmx.ch wrote: What do you think about: 1. Defining which ids are to be replaced: - The list of IDs to replace is in base tag, as described earlier in this thread. a and form elements can have a boolean @onlyreplace attribute that specifically enables or disables the functionality for the element. - If at least one of the IDs is found in the linked document, replace the IDs that are found. Ignore IDs that are not present in the linked document, or in the document that contains the link (important for dynamic applications, so the head section is not forced to know the state of the body). - If none of the indicated IDs are found, *replace the whole page*. This makes it possible to prevent e.g. a wiki or forum from being @onlyreplaced by just using different IDs. I'm definitely for the last one. As well, if you recieve any response that indicates the resource you've gotten isn't what you asked for (like a 404 status code), also replace the whole page. Simple things like a 302 status code that then produces a 200 on the redirected request should obviously be fine. 2. Possible further additions to the base tag: - Explicitly exclude parts of a site from @onlyreplace, e.g.: base onlyreplaceExcludeDir=/wiki /forum /media/downloads This doesn't seem necessary if @onlyreplace on links is required to indicate that they carry the onlyreplace semantics. - Explicitly specify the links that carry the onlyreplace feature: base onlyreplaceLinkContainers=navigation orderform Similarly this isn't necessary, but it *might* be helpful. I'd be inclined to just keep things simple for now, though. When we add more attributes to base than just href and target, the sentence There must be no more than one base element per document. in 4.2.3 of the spec should maybe be removed, as for every possible attribute in base there will be a note anyway saying If there are multiple base elements with [attributename] attributes, all but the first are ignored. Nah, the former sentence is an author conformance requirement. The latter is for UAs. Both are required.
Re: [whatwg] a onlyreplace
On Mon, Oct 19, 2009 at 4:49 AM, Markus Ernst derer...@gmx.ch wrote: - If none of the indicated IDs are found, *replace the whole page*. This makes it possible to prevent e.g. a wiki or forum from being @onlyreplaced by just using different IDs. But it breaks progressive rendering, which could be extremely annoying. The user might give up after a second or two of no response, as the (possibly quite long) page is fetched and parsed.
Re: [whatwg] a onlyreplace
Aryeh Gregor schrieb: On Mon, Oct 19, 2009 at 4:49 AM, Markus Ernst derer...@gmx.ch wrote: - If none of the indicated IDs are found, *replace the whole page*. This makes it possible to prevent e.g. a wiki or forum from being @onlyreplaced by just using different IDs. But it breaks progressive rendering, which could be extremely annoying. The user might give up after a second or two of no response, as the (possibly quite long) page is fetched and parsed. This is true. So using this as a feature to exclude pages from being onlyreplaced should be discouraged, authors should set onlyreplace to false (resp. not set the onlyreplace attribute) on the links to those pages.
Re: [whatwg] a onlyreplace
On Mon, Oct 19, 2009 at 1:10 PM, Markus Ernst derer...@gmx.ch wrote: Aryeh Gregor schrieb: But it breaks progressive rendering, which could be extremely annoying. The user might give up after a second or two of no response, as the (possibly quite long) page is fetched and parsed. This is true. So using this as a feature to exclude pages from being onlyreplaced should be discouraged, authors should set onlyreplace to false (resp. not set the onlyreplace attribute) on the links to those pages. The problem I see here (as an author) is that the attribute *will* accidentally get placed where it shouldn't. From the user's point of view, this dramatically slows down clicking the link (making them annoyed at my site), but in a way that's very difficult for me to notice. It's an X% chance that clicking a given link will be inexplicably slow, at random, if I use this feature. The value of X will vary based on all sorts of things, some possibly beyond my control. It's a risk that would definitely count against the feature if I were deciding whether to use it. In short, accidental misuse should be harmless if possible. For something to be just harmless enough that authors won't notice it, but harmful enough to significantly annoy users, is bad. In some ways even worse than catastrophic failure on misuse, although in most ways better.
Re: [whatwg] a onlyreplace
On Sat, Oct 17, 2009 at 12:45 PM, Nelson Menezes flying.mushr...@gmail.com wrote: 2009/10/17 Jonas Sicking jo...@sicking.cc: In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. Well, here's a badly-hacked-together solution that emulates this behaviour... I think it'll be helpful even if it only gets used in a JS library as you mention (change the attribute to a classname then). Still, it can be made to work with today's browsers: http://test.fittopage.org/page1.php Yay, sweet! But why so much cruft in the hash? Also, going back to the original page (where there is no hash) doesn't seem to work (at least in Firefox trunk nightlies). / Jonas
Re: [whatwg] a onlyreplace
On Fri, 16 Oct 2009, Aryeh Gregor wrote: I'm drawn back to my original proposal. The idea would be as follows: instead of loading the new page in place of the new one, just parse it, extract the bit you want, plug that into the existing DOM, and throw away the rest. More specifically, suppose we mark the dynamic content instead of the static. Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. On Fri, 16 Oct 2009, Tab Atkins Jr. wrote: Single-page apps are already becoming common for js-heavy sites. The obvious example is something like Gmail, but it's becoming more common everywhere. The main benefit of doing this is that you never dump the script context, so you only have to parse/execute/apply scripting *once* across the page, making really heavy libraries actually usable. In fact, writing a single-page app was explicitly given as a suggestion in the Global Script thread. Even in contexts with lighter scripts, there can still be substantial run-time rewriting of the page which a single-page app can avoid doing multiple times (frex, transforming a nested list into a tree control). The problem, though, is that single-page apps are currently a bit clunky to write. They require javascript to function, and the necessary code is relatively large and clunky, even in libraries like jQuery which make the process much simpler. It requires you to architect your site around the design, either producing a bunch of single-widget files that you query for and slap into place, or some relatively complex client-side logic to parse data structures into HTML. It's also very hard to get accessibility and graceful degradation right, requiring you to basically completely duplicate everything in a static form. Finally, preserving bookmarkability/general deeplinking (such as from a search engine) requires significant effort with history management and url hacking. Aryeh's suggestion, though, solves *all* of these problems with a single trivial attribute. You first design a static multi-page site like normal, with the only change being this attribute on your navigation links specifying the dynamic/replaceable portions of the page. In a legacy client, then, you have a perfectly serviceable multipage site, with the only problems being the reloading of js and such on each pageload. In a supporting client, though, clicking a link causes the browser to perform an ordinary request for the target page (requiring *no* special treatment from the author), parse/treebuild the new page, and then yank out the relevant fragments and replace bits in the current page with them. The url/history automatically updates properly; bookmarking the page and visiting it later will take you to appropriate static page that already exists. Script context is maintained, listeners stay around, overall page state remains stable across 'pageloads'. It's a declarative, accessible, automatic, and EASY way of creating the commonest form of single-page apps. This brings benefits to more than just the traditional js-heavy apps. My company's web site utilizes jQuery for a lot of small upgrades in the page template (like a hover-expand accordion for the main nav), and for certain things on specific pages. I know that loading the library, and applying the template-affecting code, slows down my page loads, but it's not significant enough to be worth the enormous effort to create an accessible, search-engine friendly single-page app. This would solve my problem trivially, though, providing a better overall UI to my visitors (snappier page loads) without any real effort on my part, and without harming accessibility or SEO. This also trivially replaces most/all uses of bad mechanisms like frameset used to address similar problems (such as maintaining state on a complex nav). The only addition I'd make to this is to allow a tag in the head that specifies default replaceability for all same-origin links. Perhaps just an attribute on base? It would accept a space-separated list of ids, just like the @onlyreplace attribute on as. An @onlyreplace attribute on a link would completely override this default (this would allow me to, frex, have the mainnav only replace the subnav,
Re: [whatwg] a onlyreplace
The cruft in the hash is needed so that we know what IDs to refresh when navigating back (which could be taken away into a JS URL-to-IDs map), and to detect a change if the same URL is accessed several times (that's probably overkill). Still, the point was to show it can work today; it really isn't an elegant solution as-is :) Nelson Menezes http://fittopage.org 2009/10/18 Jonas Sicking jo...@sicking.cc: On Sat, Oct 17, 2009 at 12:45 PM, Nelson Menezes flying.mushr...@gmail.com wrote: 2009/10/17 Jonas Sicking jo...@sicking.cc: In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. Well, here's a badly-hacked-together solution that emulates this behaviour... I think it'll be helpful even if it only gets used in a JS library as you mention (change the attribute to a classname then). Still, it can be made to work with today's browsers: http://test.fittopage.org/page1.php Yay, sweet! But why so much cruft in the hash? Also, going back to the original page (where there is no hash) doesn't seem to work (at least in Firefox trunk nightlies). / Jonas
Re: [whatwg] a onlyreplace
dd0fbad0910161343s277083c7v4eee5197c15bd...@mail.gmail.com Content-Type: text/plain; charset=windows-1255 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 Some comments: I think an optimization that enables the server to strip unnecessary content is a MUST. It seems the browser will need to make a distinction between a regular request and a request invoked by a bookmark. In case of a bookmark the server should not strip content so the browser must let him know that. In a single page application AJAX updates can be originated in 2 roots: 1. The user clicks something in the navigation panel 2. The user clicks an action button inside the content panel An example of use case #2 can be clicking a save button. In this case the a tag is usually not used but a button, this means that other tags the a should have the onlyreplace attribute. In this example the URL should not be remembered by the history. There are other cases of use case #2 where the URL should be remembered - like a next button on a page-able data grid. I think this solution is good for changes of the entire content panel. When a specific widget needs to update a data binding solution may be better. This means the onlyreplace will probably be always the defaults. From: jackalm...@gmail.com Date: Fri, 16 Oct 2009 15:43:25 -0500 To: simetrical+...@gmail.com CC: derer...@gmx.ch; wha...@whatwg.org Subject: Re: [whatwg] A few public responses to issues/questions brought up in IRC: (thanks, Aryeh and Philip!) How is this better than and lt;a targetgt;?lt;br /gt;gt; =lt;br /gt;gt; It's significantly better in multiple ways, actually.lt;br /gt;gt;lt;br /gt;gt; 1. lt;iframegt;s, like frames before them, break bookmarking. If a userlt;br /gt;gt; bookmarks the page and returns to it later, or gets deeplinked via alt;br /gt;gt; search engine or a link from a friend, the lt;iframegt; won't show thelt;br /gt;gt; correct content. The only way around this is some fairly non-triviallt;br /gt;gt; url-hacking with javascript, altering the displayed url as the userlt;br /gt;gt; navigates the iframe, and parsing a deeplink url into an appropriatelt;br /gt;gt; url for the iframe on initial pageload. @onlyreplace, on the otherlt;br /gt;gt; hand, automatically works perfectly with bookmarking. The UA stilllt;br /gt;gt; changes urls and inserts history appropriately as you navigate, and onlt;br /gt ;gt; a fresh pageload it just requests the ordinary static page showing thelt;br /gt;gt; appropriate content.lt;br /gt;gt;lt;br /gt;gt; 2. lt;a targetgt; can only navigate one iframe at a time. Many/mostlt;br /gt;gt; sites, though, have multiple dynamic sections scattered throughout thelt;br /gt;gt; page. The main site for my company, frex, has 3 (content,lt;br /gt;gt; breadcrumbs, and section nav) which *cannot* be combined to display aslt;br /gt;gt; a single lt;iframegt;, at least not without including a whole bunch oflt;br /gt;gt; static content as well. You'd have use javascript to hook the linkslt;br /gt;gt; and manually navigate the additional iframes. @onlyreplace, on thelt;br /gt;gt; other hand, handles this seamlessly - just include multiple ids in thelt;br /gt;gt; attribute value.lt;br /gt;gt;lt;br /gt;gt; 3. lt;iframegt;s require you to architect your site around them. Ratherlt;br /gt;gt; than a series of independen t pages, you must create a single masterlt;br /gt;gt; page and then a number of content-chunk mini-pages. This breakslt;br /gt;gt; normal authoring practices (though in some ways it's easier), andlt;br /gt;gt; requires you to work hard to maintain accessibility and such in thelt;br /gt;gt; face of these atrophied mini-pages. @onlyreplace works on full,lt;br /gt;gt; ordinary pages. It's *possible* to link to a content-chunk mini-pagelt;br /gt;gt; instead, but this will spectacularly break if you ever deeplinklt;br /gt;gt; straight to one of the pages, so it should become automatic forlt;br /gt;gt; authors to do this correctly.lt;br /gt;gt;lt;br /gt;gt; 4. lt;iframegt;s have dubious accessibility and search effects. I don'tlt;br /gt;gt; know if bots can navigate lt;a targetgt; links appropriately. I alsolt;br /gt;gt; believe that this causes problems with screen-readers. While eitherlt;br /gt;gt; of these sets of UAs can be rewritten to handle lt;iframegt;s better (andlt;br /gt;gt; handle @onlyreplace replacement as well), with @onlyreplace theylt;br /gt;gt; *also* have the option of just completely ignoring the attribute andlt;br /gt;gt; navigating the site as an ordinary multi-page app. Legacy UAs willlt;br /gt;gt; automatically do so, providing perfect backwards compatibility.lt;br /gt;gt;lt;br /gt;gt;lt;br /gt;gt; Isn't if inefficient to request the whole page and then throw most oflt;br /gt;gt; it out? With proper AJAX you can just request the bits you
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 4:30 AM, Ian Hickson i...@hixie.ch wrote: My recomendation would be to follow the process for adding features: http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F In particular the bit about experimental implementations. I think this idea looks very interesting, but it's hard to evaluate without concrete experience with a browser implementing this (or, as Jonas suggests, a library that hacks it in). It seems like the kind of thing that we could adopt early on in the next feature cycle, if it turns out to be a good solid model. Yup, was planning on this. Just wanted to hack it out on the list first before jumping down any rabbit holes. If nobody beats me to it, this should be relatively easy to hack in (and may already be hacked in in some form, via mooTools?). ~TJ
Re: [whatwg] a onlyreplace
2009/10/18 Ian Hickson i...@hixie.ch: On Sat, 17 Oct 2009, Schuyler Duveen wrote: One of the big issues we found using it on some other sites is that javascript listeners (rather than onclick= attributes), and other DOM pointers in the system became stale. Thus, only half the problem was solved. Well, you are effectively destroying and regenerating parts of your DOM so whatever JS event handlers you have in place need to be updated on refresh. That is no different from what happens today with AJAX, or indeed multi-frame JS. Also, the problem (as I implemented it) is that XMLHttpRequest.xml has been very finicky in past (and current) browsers. My comments in the code reflect some of the things you need to make sure you're doing to make it work across browsers (at least if you want a DOM vs. regex implementation): * IE 6 needed the Content-type: text/xml * Firefox (?2.x) wants xmlns=http://www.w3.org/1999/xhtml; in html tag * IE and Safari don't handle named entities like nbsp; well in this context and should be numeric (e.g. #160;) I ran into the same problem, but it is possible to invoke in current browsers their HTML parsers by injecting the responseText of XMLHttpRequest (as opposed to responseXml) into a temporary Document (in a temp iframe). I would imagine it would be a requirement for implementing browsers to use the same parsing rules on the onlyreplace document as they would for a normal document. Indeed, it should be no harder to build a onlyreplace document than any other, since the same document would be usable interchangeably in both contexts. Vendors might better serve us by reducing these hoops to jump through so a javascript library could do the job reliably. This method did make it much easier to leverage server template code. But since it largely simplifies server template code, then why not stick with server-side solutions like Ian Bicking's: http://blog.ianbicking.org/2008/09/08/inverted-partials/ The possibility remains to use partial content responses to optimise resource usage (via the proposed onlyreplace HTTP header), but the point of this proposal is that it makes it easy to address the no-UI-refresh requirement without a complex server- and client-side framework, and offers transparent fallback. It is not so much that this can't be done today (it can) but that we would standardise and promote the way to do it right. It's still a bit weird that this proposal, instead of allowing every element to be a link (like XHTML2), would allow every element to be something like an IFRAME (all while a thread remembering how evil framesets are continues). But this doesn't make different elements behave like iframes since every link still corresponds to a single document, so it doesn't break navigation or bookmarking. My recomendation would be to follow the process for adding features: http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F In particular the bit about experimental implementations. I think this idea looks very interesting, but it's hard to evaluate without concrete experience with a browser implementing this (or, as Jonas suggests, a library that hacks it in). http://test.fittopage.org/page1.php ? It seems like the kind of thing that we could adopt early on in the next feature cycle, if it turns out to be a good solid model. Is there a mailing list for HTML 6? :-) [1] http://msdn.microsoft.com/en-us/library/aa155133.aspx [2] http://developer.yahoo.com/yui/examples/treeview/dynamic_tree.html Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sat, Oct 17, 2009 at 2:45 PM, Nelson Menezes flying.mushr...@gmail.com wrote: 2009/10/17 Jonas Sicking jo...@sicking.cc: In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. Well, here's a badly-hacked-together solution that emulates this behaviour... I think it'll be helpful even if it only gets used in a JS library as you mention (change the attribute to a classname then). Still, it can be made to work with today's browsers: http://test.fittopage.org/page1.php Awesome, Nelson! Seems to work pretty cool! I'll hack on it a bit today, see if I can make it a bit more featureful. ~TJ
Re: [whatwg] a onlyreplace
2009/10/18 Nelson Menezes flying.mushr...@gmail.com: [1] http://msdn.microsoft.com/en-us/library/aa155133.aspx [2] http://developer.yahoo.com/yui/examples/treeview/dynamic_tree.html Oops, sorry, I meant to give a couple of examples (above) of existing approaches to maintain user UI state. [1] involves page refresh so it has the flickering problem, and [2] is custom-built data over AJAX, which is neither bookmarkable nor easy to implement. You could add other variants of [2] that are bookmarkable (e.g. Gmail) but all involve a custom, complex, server-and-client framework. Of course, there's also framesets/iframes, but that also requires server content tailored for this interface -- and it breaks bookmarking. Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 6:45 AM, tali garsiel t_gars...@hotmail.com wrote: Some comments: I think an optimization that enables the server to strip unnecessary content is a MUST. Well, as I explained, it's not really a MUST. Doing an ordinary navigation requests an entire page, and without optimizations this does the exact same thing. You're not burning *more* bandwidth than normal; you're just slightly changing the effect of it. That said, such optimizations would be really useful, I agree. It could significantly cut down bandwidth use (on my company's site, the average request would drop from about 20k to about 1.5k). This could *really* improve site performance, and even perhaps be good for the overall net. It seems the browser will need to make a distinction between a regular request and a request invoked by a bookmark. In case of a bookmark the server should not strip content so the browser must let him know that. There's no need to make a distinction. Only requests with onlyreplace semantics trigger the special behavior. Typing an address into your browser won't add those semantics, nor will a bookmark; only links with @onlyreplace (or links on a page with base onlyreplace that don't override their own @onlyreplace with the empty string) carry the semantics. If you're talking about this in terms of optimizations, then the onlyreplace information would be carried by a request header. When the browser doesn't send this header, the server wouldn't strip anything down. In a single page application AJAX updates can be originated in 2 roots: 1. The user clicks something in the navigation panel 2. The user clicks an action button inside the content panel An example of use case #2 can be clicking a save button. In this case the a tag is usually not used but a button, this means that other tags the a should have the onlyreplace attribute. I thought it would be interesting to be able to put @onlyreplace on forms, or perhaps form submission inputs. In this example the URL should not be remembered by the history. Then you should use ordinary AJAX to do so. @onlyreplace is supposed to be merely an optimization on normal navigation. The url *must* be remembered by the history. There are other cases of use case #2 where the URL should be remembered - like a next button on a page-able data grid. Yup, exactly. A paged control is a great use-case! It's extremely simple to set up (just pass paging info in query params), and bookmarking works beautifully! I think this solution is good for changes of the entire content panel. When a specific widget needs to update a data binding solution may be better. Yeah, this is not meant to be a general replacement for AJAX. It just makes a particular set of common cases extremely easy. In many circumstances being explicit with javascript is still the better solution. This means the onlyreplace will probably be always the defaults. I'm not sure what you mean here. ~TJ
Re: [whatwg] a onlyreplace
2009/10/18 Tab Atkins Jr. jackalm...@gmail.com: On Sun, Oct 18, 2009 at 6:45 AM, tali garsiel t_gars...@hotmail.com wrote: It seems the browser will need to make a distinction between a regular request and a request invoked by a bookmark. In case of a bookmark the server should not strip content so the browser must let him know that. There's no need to make a distinction. Only requests with onlyreplace semantics trigger the special behavior. Typing an address into your browser won't add those semantics, nor will a bookmark; only links with @onlyreplace (or links on a page with base onlyreplace that don't override their own @onlyreplace with the empty string) carry the semantics. I guess the base @onlyreplace would probably be an important part of making this truly useful. There might be too many maintainability problems stemming from having @onlyreplace all over the place on links (imagine having 5 sections on the page that need updating and dozens of links... and then adding a 6th section). In a single page application AJAX updates can be originated in 2 roots: 1. The user clicks something in the navigation panel 2. The user clicks an action button inside the content panel An example of use case #2 can be clicking a save button. In this case the a tag is usually not used but a button, this means that other tags the a should have the onlyreplace attribute. I thought it would be interesting to be able to put @onlyreplace on forms, or perhaps form submission inputs. The two traditional triggers for navigation are anchors a and form submissions. The @onlyreplace semantics should not be available anywhere else since that would be changing the semantics of non-navigation elements. Any custom UI wizardry should be handled by Javascript, and the semantics of @onlyreplace would be available via something like window.location.assignOnlyReplace(url, [ids]); In this example the URL should not be remembered by the history. Then you should use ordinary AJAX to do so. �...@onlyreplace is supposed to be merely an optimization on normal navigation. The url *must* be remembered by the history. Agreed, as above. I wonder, though, if there might be a problem with this after all... picture this: ... a onlyreplace=div1 div2 href=ingredients.htmlIngredients/a a onlyreplace=div2 href=nutrition.htmlNutrition/a a onlyreplace=div3 href=preparation.htmlPreparation/a ... div id=div1/div div id=div2/div div id=div3/div ... Let's say I click the links in order (Ingredients, Nutrition, Preparation), and now bookmark the page (it's now preparation.html). When I return to it, #div1 and #div2 will only be populated if preparation.html is guaranteed to contain the same content as the other two documents. There are a lot of testing paths to guarantee that's the case... does this make the mechanism too fragile? Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 10:07 AM, Nelson Menezes flying.mushr...@gmail.com wrote: I guess the base @onlyreplace would probably be an important part of making this truly useful. There might be too many maintainability problems stemming from having @onlyreplace all over the place on links (imagine having 5 sections on the page that need updating and dozens of links... and then adding a 6th section). Yup, my thought exactly. I wonder, though, if there might be a problem with this after all... picture this: ... a onlyreplace=div1 div2 href=ingredients.htmlIngredients/a a onlyreplace=div2 href=nutrition.htmlNutrition/a a onlyreplace=div3 href=preparation.htmlPreparation/a ... div id=div1/div div id=div2/div div id=div3/div ... Let's say I click the links in order (Ingredients, Nutrition, Preparation), and now bookmark the page (it's now preparation.html). When I return to it, #div1 and #div2 will only be populated if preparation.html is guaranteed to contain the same content as the other two documents. There are a lot of testing paths to guarantee that's the case... does this make the mechanism too fragile? Ooh, that... is a problem. I mean, if this is used properly it shouldn't ever happen, obviously, as every page should be a valid page. But the example you described above seems very possible, with authors thinking that it's okay to create 4 nearly identical pages, with the sub-pages containing only particular bits filled in (not just content chunks, but still incomplete). This degrades badly (just following each link gives you only partial recipes). I'd like bookmarking to return you to something as similar as what you were looking at before as possible. The better would be to have only two pages, foo-empty.html and foo-complete.html, with the links grabbing particular bits from foo-complete. Then bookmarking would take you to foo-complete, which isn't horrible. Ideally, though, we should never have this situation at all. Using @onlyreplace for information hiding is stupid; that's what details was made for, and it does it *way* better (instantaneous replacement, no bandwidth waste, bookmarking is fine). So, hmm. Is this enough of a problem that we have to address it? If it is, probably the best thing to do would be to remove the id list from a and only leave it on base, with some attribute on links to indicate whether they should trigger an onlyreplace or a normal navigation. That way all links carrying the onlyreplace semantic will replace the same bits, making the above scenario impossible. This eliminates many useful cases for onlyreplace, though. Frex, say you have a documentation site, with a main-nav up top, a fancy treeview section-nav on the left, and documentation pages on the right. Clicking one of the mainnav links should replace both the section-nav and the doc page, but clicking on a section-nav link should only replace the content. I suppose this is still possible by just making the main-nav links trigger a normal navigation, the section-nav links trigger an onlyreplace navigation, and having base onlyreplace=content. I feel this may still render onlyreplace unusable for more complex single-page apps, though. I dunno, this may be ok - perhaps those apps are complex enough that we can't meet their needs with a mechanism this simple anyway. This limitation wouldn't really hurt the simpler use-cases that I envisioned (ordinary pages which want to enhance their static area with heavy js, but don't want the cost of reloading libraries on every navigation and having things move around as they get manipulated every time). Okay, so possible revision: base onlyreplace=foo carries a list of ids to replace. This automatically makes all links and forms on the page carry the onlyreplace semantics. You can turn this off for specific links by setting @noreplace (a binary attribute) on the link or form; activating/submitting them will trigger a normal navigation. Can anyone think of any concrete cases that were addressed well by the older suggestion, but are now impossible with this newer revision? I'm sure there are some, I just want to assess how valuable they may be before I decide to cut them off. ~TJ
Re: [whatwg] a onlyreplace
Nelson Menezes wrote: 2009/10/18 Ian Hickson i...@hixie.ch: On Sat, 17 Oct 2009, Schuyler Duveen wrote: One of the big issues we found using it on some other sites is that javascript listeners (rather than onclick= attributes), and other DOM pointers in the system became stale. Thus, only half the problem was solved. Well, you are effectively destroying and regenerating parts of your DOM so whatever JS event handlers you have in place need to be updated on refresh. That is no different from what happens today with AJAX, or indeed multi-frame JS. My point (which feeds on Marcus Ernst's point) is that we need some kind of load event. Maybe something like: document.addEventListener('replaceonly') with the event object providing access to the new DOM content and the old DOM node. Also, the problem (as I implemented it) is that XMLHttpRequest.xml has been very finicky in past (and current) browsers. My comments in the code reflect some of the things you need to make sure you're doing to make it work across browsers (at least if you want a DOM vs. regex implementation): * IE 6 needed the Content-type: text/xml * Firefox (?2.x) wants xmlns=http://www.w3.org/1999/xhtml; in html tag * IE and Safari don't handle named entities like nbsp; well in this context and should be numeric (e.g. #160;) I ran into the same problem, but it is possible to invoke in current browsers their HTML parsers by injecting the responseText of XMLHttpRequest (as opposed to responseXml) into a temporary Document (in a temp iframe). I would imagine it would be a requirement for implementing browsers to use the same parsing rules on the onlyreplace document as they would for a normal document. Indeed, it should be no harder to build a onlyreplace document than any other, since the same document would be usable interchangeably in both contexts. Vendors might better serve us by reducing these hoops to jump through so a javascript library could do the job reliably. This method did make it much easier to leverage server template code. But since it largely simplifies server template code, then why not stick with server-side solutions like Ian Bicking's: http://blog.ianbicking.org/2008/09/08/inverted-partials/ The possibility remains to use partial content responses to optimise resource usage (via the proposed onlyreplace HTTP header), but the point of this proposal is that it makes it easy to address the no-UI-refresh requirement without a complex server- and client-side framework, and offers transparent fallback. It is not so much that this can't be done today (it can) but that we would standardise and promote the way to do it right. I like this idea a lot. It seems like a job for the HTTP Content-Range header (using a different word than 'bytes'). One other thought: It might be a good idea to allow the server to explicitly demand a full load. (I.e. a server-side equivalent to window.top=location) There's still seems like a big danger in addressability. Yes, it's a problem in ajax, but it's a problem that authors can solve on their own with hash tags (in ad-hoc ways). When the browser takes over the location value, the author's ability to do that is undermined. Maybe it should all *stay* in the hash tags like your implementation has it. Something like: http://example.com/#id1=page2;id2=page3; where the value is the most recent source URL for that @id. cheers, sky It's still a bit weird that this proposal, instead of allowing every element to be a link (like XHTML2), would allow every element to be something like an IFRAME (all while a thread remembering how evil framesets are continues). But this doesn't make different elements behave like iframes since every link still corresponds to a single document, so it doesn't break navigation or bookmarking. My recomendation would be to follow the process for adding features: http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F In particular the bit about experimental implementations. I think this idea looks very interesting, but it's hard to evaluate without concrete experience with a browser implementing this (or, as Jonas suggests, a library that hacks it in). http://test.fittopage.org/page1.php ? It seems like the kind of thing that we could adopt early on in the next feature cycle, if it turns out to be a good solid model. Is there a mailing list for HTML 6? :-) [1] http://msdn.microsoft.com/en-us/library/aa155133.aspx [2] http://developer.yahoo.com/yui/examples/treeview/dynamic_tree.html Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
bay117-w90f5b859cd291ac4e373b83...@phx.gbl dd0fbad0910180717q60e0c0f5l12e81a337af57...@mail.gmail.com Content-Type: text/plain; charset=windows-1255 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 When I said an optimization is a must I didn't just mean bandwidth. Imagine this use case: You have a page with a chart and a table showing data calculated from complex statistical analysis on your huge database. Both the chart and the table have refresh buttons implemented with a onlyreplace Recalculating the chart when you refresh the table or vice verse will not be acceptable by your project manager :) The server will need to know what is currently requested. The solution is not necessarily to strip the content, but the server must get information of the updated parts and choose what to calculate. From: jackalm...@gmail.com Date: Sun, 18 Oct 2009 09:17:19 -0500 Subject: Re: [whatwg] To: t_gars...@hotmail.com CC: simetrical+...@gmail.com; derer...@gmx.ch; wha...@whatwg.org On Sun, Oct 18, 2009 at 6:45 AM, tali garsiel wrote: Some comments: I think an optimization that enables the server to strip unnecessary content is a MUST. Well, as I explained, it's not really a MUST. Doing an ordinary navigation requests an entire page, and without optimizations this does the exact same thing. You're not burning *more* bandwidth than normal; you're just slightly changing the effect of it. That said, such optimizations would be really useful, I agree. It could significantly cut down bandwidth use (on my company's site, the average request would drop from about 20k to about 1.5k). This could *really* improve site performance, and even perhaps be good for the overall net. It seems the browser will need to make a distinction between a regular request and a request invoked by a bookmark. In case of a bookmark the server should not strip content so the browser must let him know that. There's no need to make a distinction. Only requests with onlyreplace semantics trigger the special behavior. Typing an address into your browser won't add those semantics, nor will a bookmark; only links with @onlyreplace (or links on a page with that don't override their own @onlyreplace with the empty string) carry the semantics. If you're talking about this in terms of optimizations, then the onlyreplace information would be carried by a request header. When the browser doesn't send this header, the server wouldn't strip anything down. In a single page application AJAX updates can be originated in 2 roots: 1. The user clicks something in the navigation panel 2. The user clicks an action button inside the content panel An example of use case #2 can be clicking a save button. In this case the tag is usually not used but a button, this means that other tags the should have the onlyreplace attribute. I thought it would be interesting to be able to put @onlyreplace on forms, or perhaps form submission inputs. In this example the URL should not be remembered by the history. Then you should use ordinary AJAX to do so. @onlyreplace is supposed to be merely an optimization on normal navigation. The url *must* be remembered by the history. There are other cases of use case #2 where the URL should be remembered - like a next button on a page-able data grid. Yup, exactly. A paged control is a great use-case! It's extremely simple to set up (just pass paging info in query params), and bookmarking works beautifully! I think this solution is good for changes of the entire content panel. When a specific widget needs to update a data binding solution may be better. Yeah, this is not meant to be a general replacement for AJAX. It just makes a particular set of common cases extremely easy. In many circumstances being explicit with javascript is still the better solution. This means the onlyreplace will probably be always the defaults. I'm not sure what you mean here. ~TJ _ Keep your friends updatedeven when youre not signed in. http://www.microsoft.com/middleeast/windows/windowslive/see-it-in-action/social-network-basics.aspx?ocid=PID23461::T:WLMTAGL:ON:WL:en-xm:SI_SB_5:092010
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 11:20 AM, Schuyler Duveen wha...@graffitiweb.org wrote: Nelson Menezes wrote: 2009/10/18 Ian Hickson i...@hixie.ch: On Sat, 17 Oct 2009, Schuyler Duveen wrote: One of the big issues we found using it on some other sites is that javascript listeners (rather than onclick= attributes), and other DOM pointers in the system became stale. Thus, only half the problem was solved. Well, you are effectively destroying and regenerating parts of your DOM so whatever JS event handlers you have in place need to be updated on refresh. That is no different from what happens today with AJAX, or indeed multi-frame JS. My point (which feeds on Marcus Ernst's point) is that we need some kind of load event. Maybe something like: document.addEventListener('replaceonly') with the event object providing access to the new DOM content and the old DOM node. I agree, though I think it might be better to follow the current load/unload model with a replaceUnload/replaceLoad event being fired at the appropriate elements. (Or, as was suggested by someone else, just using load/unload on a particular element, since currently it just fires at window. I don't know if there are inherent problems with this or what.) The possibility remains to use partial content responses to optimise resource usage (via the proposed onlyreplace HTTP header), but the point of this proposal is that it makes it easy to address the no-UI-refresh requirement without a complex server- and client-side framework, and offers transparent fallback. It is not so much that this can't be done today (it can) but that we would standardise and promote the way to do it right. I like this idea a lot. It seems like a job for the HTTP Content-Range header (using a different word than 'bytes'). Yup, something like this should emerge at some point. One other thought: It might be a good idea to allow the server to explicitly demand a full load. (I.e. a server-side equivalent to window.top=location) Ah, interesting, a response header that says I know you only asked me for certain parts of the response, but here's the whole thing instead, and please load it all. There's still seems like a big danger in addressability. Yes, it's a problem in ajax, but it's a problem that authors can solve on their own with hash tags (in ad-hoc ways). When the browser takes over the location value, the author's ability to do that is undermined. Maybe it should all *stay* in the hash tags like your implementation has it. Something like: http://example.com/#id1=page2;id2=page3; where the value is the most recent source URL for that @id. Well, the point is that this should generally act as just an optimization of normal navigation. Clicking on a href=foo onlyreplace=bar should give you the same result as clicking on a href=foo, just without the overall page getting flushed. So the address should update to http://example.com/foo;, etc. You can always url-hack on your own, if you need to. ~TJ
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 11:22 AM, tali garsiel t_gars...@hotmail.com wrote: When I said an optimization is a must I didn't just mean bandwidth. Imagine this use case: You have a page with a chart and a table showing data calculated from complex statistical analysis on your huge database. Both the chart and the table have refresh buttons implemented with a onlyreplace Recalculating the chart when you refresh the table or vice verse will not be acceptable by your project manager :) The server will need to know what is currently requested. The solution is not necessarily to strip the content, but the server must get information of the updated parts and choose what to calculate. That's not really an appropriate use of @onlyreplace. Just put the chart and table in iframes with @name and use a target to refresh them. That also automatically optimizes bandwidth, since the subpages that the chart and frame will live on contain *only* them. (Preventing this sort of abuse might be a good reason to do the only base can carry an id list revision.) ~TJ
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 12:28 PM, Tab Atkins Jr. jackalm...@gmail.comwrote: Well, the point is that this should generally act as just an optimization of normal navigation. Clicking on a href=foo onlyreplace=bar should give you the same result as clicking on a href=foo, just without the overall page getting flushed. So the address should update to http://example.com/foo;, etc. I've only been partially following this thread, so this may have been answered previously. Is this an accurate summary of what you're thinking of? Clicking a href=foo and a href=foo onlyreplace=bar would send the exact same headers to the server with the exception of a single extra header for the @onlyreplace version? In the case of @onlyreplace, would the #bar element end up being replaced, or just its content? Would the server be expected to reply with div id=bar.../dv or just what would would become bar.innerHTML?
Re: [whatwg] a onlyreplace
2009/10/18 Scott González scott.gonza...@gmail.com: On Sun, Oct 18, 2009 at 12:28 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: Well, the point is that this should generally act as just an optimization of normal navigation. Clicking on a href=foo onlyreplace=bar should give you the same result as clicking on a href=foo, just without the overall page getting flushed. So the address should update to http://example.com/foo;, etc. I've only been partially following this thread, so this may have been answered previously. Is this an accurate summary of what you're thinking of? Clicking a href=foo and a href=foo onlyreplace=bar would send the exact same headers to the server with the exception of a single extra header for the @onlyreplace version? Yes. In the case of @onlyreplace, would the #bar element end up being replaced, or just its content? The full element. Would the server be expected to reply with div id=bar.../dv or just what would would become bar.innerHTML? The former. As well, the server *can* return the whole document, but is only required to send the requested elements. ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 11:20 AM, Schuyler Duveen wha...@graffitiweb.org wrote: Nelson Menezes wrote: My point (which feeds on Marcus Ernst's point) is that we need some kind of load event. Maybe something like: document.addEventListener('replaceonly') with the event object providing access to the new DOM content and the old DOM node. I agree, though I think it might be better to follow the current load/unload model with a replaceUnload/replaceLoad event being fired at the appropriate elements. (Or, as was suggested by someone else, just using load/unload on a particular element, since currently it just fires at window. I don't know if there are inherent problems with this or what.) I like the first one. I'd rather it be on the document (or window) so we don't have to wait for the first instance of an element to show up. More importantly, then I can write javascript that's more generic rather having to know about which specific elements will be doing the loading/unloading in a particular document. There's still seems like a big danger in addressability. Yes, it's a problem in ajax, but it's a problem that authors can solve on their own with hash tags (in ad-hoc ways). When the browser takes over the location value, the author's ability to do that is undermined. Maybe it should all *stay* in the hash tags like your implementation has it. Something like: http://example.com/#id1=page2;id2=page3; where the value is the most recent source URL for that @id. Well, the point is that this should generally act as just an optimization of normal navigation. Clicking on a href=foo onlyreplace=bar should give you the same result as clicking on a href=foo, just without the overall page getting flushed. So the address should update to http://example.com/foo;, etc. You can always url-hack on your own, if you need to. The problem is that people will make links that refresh different parts of a document, to the point that the current document is no longer addressable. Use cases for this happen often enough (not necessarily good design, but people will do this) In the past, a good way to give (back) addressability to users is with hash tags. But here, the location changes, and the hash goes away. Standard anchor tags (with no javascript) have generally been addressable to users by default. When this hasn't been true, like with framesets, lots of confusion and frustration ensues. If this is, in the longterm, going to work non-dynamically, then things should be addressable by default. It's one of the killer features of the web :-) /skjy ~TJ
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 11:50 AM, Schuyler Duveen wha...@graffitiweb.org wrote: Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 11:20 AM, Schuyler Duveen wha...@graffitiweb.org wrote: Nelson Menezes wrote: My point (which feeds on Marcus Ernst's point) is that we need some kind of load event. Maybe something like: document.addEventListener('replaceonly') with the event object providing access to the new DOM content and the old DOM node. I agree, though I think it might be better to follow the current load/unload model with a replaceUnload/replaceLoad event being fired at the appropriate elements. (Or, as was suggested by someone else, just using load/unload on a particular element, since currently it just fires at window. I don't know if there are inherent problems with this or what.) I like the first one. I'd rather it be on the document (or window) so we don't have to wait for the first instance of an element to show up. More importantly, then I can write javascript that's more generic rather having to know about which specific elements will be doing the loading/unloading in a particular document. As long as the event bubbles, you can always just listen at the document root and then check event.target to see who got updated. That way you don't have to wait, nor do you have to know which specific bits are getting replaced. There's still seems like a big danger in addressability. Yes, it's a problem in ajax, but it's a problem that authors can solve on their own with hash tags (in ad-hoc ways). When the browser takes over the location value, the author's ability to do that is undermined. Maybe it should all *stay* in the hash tags like your implementation has it. Something like: http://example.com/#id1=page2;id2=page3; where the value is the most recent source URL for that @id. Well, the point is that this should generally act as just an optimization of normal navigation. Clicking on a href=foo onlyreplace=bar should give you the same result as clicking on a href=foo, just without the overall page getting flushed. So the address should update to http://example.com/foo;, etc. You can always url-hack on your own, if you need to. The problem is that people will make links that refresh different parts of a document, to the point that the current document is no longer addressable. Use cases for this happen often enough (not necessarily good design, but people will do this) In the past, a good way to give (back) addressability to users is with hash tags. But here, the location changes, and the hash goes away. Standard anchor tags (with no javascript) have generally been addressable to users by default. When this hasn't been true, like with framesets, lots of confusion and frustration ensues. If this is, in the longterm, going to work non-dynamically, then things should be addressable by default. It's one of the killer features of the web :-) You're right, and this makes me think more strongly that restricting the ability to specify the replaceable bits to just base is the right way to do this. ~TJ
Re: [whatwg] a onlyreplace
dd0fbad0910180717q60e0c0f5l12e81a337af57...@mail.gmail.com bay117-w9daba5e3a74376fb4bbfc83...@phx.gbl dd0fbad0910180935i6b07e025t14f4cc5aaacb3...@mail.gmail.com Content-Type: text/plain; charset=windows-1255 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 I'll try to fix my example. The table button is not refresh but a next button that keeps track of the table navigation. That is a valid use case , isn't it? (at least by your first suggestion). You still wouldn't want the server to do any heavy calculation except for the data that needs to be displayed. I tried to find an extreme use case but even showing the navigation panels often evolves lots of server work. Examples can be license and permission checks for an entire tree and parsing xml files containing tab contents. Some of this work can be avoided by using session caching but some is not, mainly security checks. From: jackalm...@gmail.com Date: Sun, 18 Oct 2009 11:35:11 -0500 Subject: Re: [whatwg] To: t_gars...@hotmail.com CC: derer...@gmx.ch; simetrical+...@gmail.com; wha...@whatwg.org On Sun, Oct 18, 2009 at 11:22 AM, tali garsiel wrote: When I said an optimization is a must I didn't just mean bandwidth. Imagine this use case: You have a page with a chart and a table showing data calculated from complex statistical analysis on your huge database. Both the chart and the table have refresh buttons implemented with . Recalculating the chart when you refresh the table or vice verse will not be acceptable by your project manager :) The server will need to know what is currently requested. The solution is not necessarily to strip the content, but the server must get information of the updated parts and choose what to calculate. That's not really an appropriate use of @onlyreplace. Just put the chart and table in s with @name and use lt;a targetgt; to refreshlt;br /gt;gt; them. That also automatically optimizes bandwidth, since the subpageslt;br /gt;gt; that the chart and frame will live on contain *only* them.lt;br /gt;gt;lt;br /gt;gt; (Preventing this sort of abuse might be a good reason to do the onlylt;br /gt;gt; lt;basegt; can carry an id list revision.)lt;br /gt;gt;lt;br /gt;gt; ~TJlt;br /gt; _ Keep your friends updatedeven when youre not signed in. http://www.microsoft.com/middleeast/windows/windowslive/see-it-in-action/social-network-basics.aspx?ocid=PID23461::T:WLMTAGL:ON:WL:en-xm:SI_SB_5:092010
Re: [whatwg] a onlyreplace
2009/10/18 Tab Atkins Jr. jackalm...@gmail.com: As long as the event bubbles, you can always just listen at the document root and then check event.target to see who got updated. That way you don't have to wait, nor do you have to know which specific bits are getting replaced. You would want the event to fire once, though, regardless of how many targets are being replaced. Otherwise you won't be able to distinguish 3 events generated by one response with content for #div1,#div2, and #div3. Event.target should be the original a or form element, or the window object if the request originated via scripting. Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 12:20 PM, Nelson Menezes flying.mushr...@gmail.com wrote: 2009/10/18 Tab Atkins Jr. jackalm...@gmail.com: As long as the event bubbles, you can always just listen at the document root and then check event.target to see who got updated. That way you don't have to wait, nor do you have to know which specific bits are getting replaced. You would want the event to fire once, though, regardless of how many targets are being replaced. Otherwise you won't be able to distinguish 3 events generated by one response with content for #div1,#div2, and #div3. Event.target should be the original a or form element, or the window object if the request originated via scripting. My thoughts were that the event fires at the replaced elements, not the a or form that triggered the navigation. So you *would* be able to distinguish multiple elements, as their event.target would point to each element as appropriate. This isn't a click or whatever event, it's a load/unload event. The a or form isn't doing either. ~TJ
Re: [whatwg] a onlyreplace
On Sat, Oct 17, 2009 at 1:22 AM, Jonas Sicking jo...@sicking.cc wrote: Also, what should happen if the user presses the 'back' button? It should be the same as for regular navigation. If the UA usually stores some page state in a cache when the user navigates, it should store the same state. If it doesn't have the previous contents cache, it should reload, assuming that's what it normally does. On Sun, Oct 18, 2009 at 11:51 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: Okay, so possible revision: base onlyreplace=foo carries a list of ids to replace. This automatically makes all links and forms on the page carry the onlyreplace semantics. You can turn this off for specific links by setting @noreplace (a binary attribute) on the link or form; activating/submitting them will trigger a normal navigation. By all links and forms do you really mean all same-domain links and forms? Even that's too many. Consider a typical site with a forum at /forum and a wiki at /wiki. You don't want links from one to the other to try onlyreplacing. Even within an app it can be complicated. MediaWiki is often installed in both /w (actual files) and /wiki (fake rewrite path), and you'd probably want links to everything in /wiki but only some things in /w to be affected. Perhaps a onlyreplace should be a boolean attribute. Opting links into onlyreplace seems safer than opting them out. In many cases you might be injecting some raw HTML into the page, like using a template system or JavaScript, such that adding noreplace to all links you're unsure about would be tricky or impossible. Opt-in is much easier to verify. In any event, this variant is fairly disastrous for copy-pasting. What you thought meant load only foo and bar from the target might suddenly mean load only baz and quuz from the target, and the result will probably be that the link completely fails. I think sticking only to per-a attributes is a safer idea, one way or another. Also, I anticipate that on many pages that would like to use this feature, only some unpredictable minority of links would actually need it. I don't think there will be any way to identify which ones without some kind of case-by-case human intervention, so I don't think base would be terribly useful. Some attention needs to be given to error handling. What happens if one or more of the requested id's aren't found? Do they silently fail? If so, this could result in the link doing absolutely nothing in hard-to-control situations -- like an error page that occurs sporadically, say a 500. Do they trigger a normal page load? If so, they have to wait until the entire page has loaded, which would be bad user experience but hard to track down -- a long, inexplicable delay followed by everything working normally. This could be mitigated by having an HTTP header to say that id doesn't exist, load the whole page instead, but it would fail in the default case (standard HTTP server unaware of new feature). Also, what happens if some of the given id's are present, but not others? One final observation is that this method isn't ideal for fixing flickering, because often you'll want to change everything at once -- you just don't want it to flicker. For instance, consider a case where you have a navigation pane and a content pane. Changing pages will change the content pane, but also sometimes cause a different item to be highlighted in the navigation pane, or cause some contextual items to disappear and reappear, etc. However, a solution to that has all the advantages of the onlyreplace proposal, that's simple to describe using existing functionality, and works well with URLs, but doesn't kill all script handlers and such, seems hard. On Sun, Oct 18, 2009 at 12:22 PM, tali garsiel t_gars...@hotmail.com wrote: Imagine this use case: You have a page with a chart and a table showing data calculated from complex statistical analysis on your huge database. Both the chart and the table have refresh buttons implemented with a onlyreplace Recalculating the chart when you refresh the table or vice verse will not be acceptable by your project manager :) I don't think the scenario is realistic. You can't usually get away with calculating anything very expensive on page load, because then page load would take unacceptably long. Calculations like this that you want to run as infrequently as possible are normally cached on the server side, in my experience. If they weren't you'd re-run the calculations every time the user navigates away and then back, or reloads the page. I don't see why that would be acceptable if the behavior you describe isn't.
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 12:25 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Sun, Oct 18, 2009 at 11:51 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: Okay, so possible revision: base onlyreplace=foo carries a list of ids to replace. This automatically makes all links and forms on the page carry the onlyreplace semantics. You can turn this off for specific links by setting @noreplace (a binary attribute) on the link or form; activating/submitting them will trigger a normal navigation. By all links and forms do you really mean all same-domain links and forms? Yes. Even that's too many. Consider a typical site with a forum at /forum and a wiki at /wiki. You don't want links from one to the other to try onlyreplacing. Even within an app it can be complicated. MediaWiki is often installed in both /w (actual files) and /wiki (fake rewrite path), and you'd probably want links to everything in /wiki but only some things in /w to be affected. Perhaps a onlyreplace should be a boolean attribute. Opting links into onlyreplace seems safer than opting them out. In many cases you might be injecting some raw HTML into the page, like using a template system or JavaScript, such that adding noreplace to all links you're unsure about would be tricky or impossible. Opt-in is much easier to verify. I think the opposite. If I upgraded my site to this, I'd want nearly all the links to onlyreplace. There's only a handful of same-origin links that I'd instead want to trigger a full load. In any event, this variant is fairly disastrous for copy-pasting. What you thought meant load only foo and bar from the target might suddenly mean load only baz and quuz from the target, and the result will probably be that the link completely fails. I think sticking only to per-a attributes is a safer idea, one way or another. It's true that this could be bad on copypasta, but is your failure scenario going to be common? Are people going to often use different bases on different pages in the same origin? I think more usually a single origin will have the same base onlyreplace everywhere, or else not have base onlyreplace at all. In the latter case, you'd presumably want all links to trigger full navigation, since that's what you're indicating with the lack. (Also, the same problem you note happens similarly with per-a onlyreplace - what if you copy a link from one page to another, and the new page has *different* elements with the same #ids as elements in the old page? Then you'd be replacing random bits of the page. Is this situation more/less likely than the one you brought up?) Also, I anticipate that on many pages that would like to use this feature, only some unpredictable minority of links would actually need it. I don't think there will be any way to identify which ones without some kind of case-by-case human intervention, so I don't think base would be terribly useful. I disagree, and think that most links would use it on a typical page. Some attention needs to be given to error handling. What happens if one or more of the requested id's aren't found? Do they silently fail? If so, this could result in the link doing absolutely nothing in hard-to-control situations -- like an error page that occurs sporadically, say a 500. Do they trigger a normal page load? If so, they have to wait until the entire page has loaded, which would be bad user experience but hard to track down -- a long, inexplicable delay followed by everything working normally. This could be mitigated by having an HTTP header to say that id doesn't exist, load the whole page instead, but it would fail in the default case (standard HTTP server unaware of new feature). Also, what happens if some of the given id's are present, but not others? I'll think a bit about these issues today. I'm not sure, off the top of my head, what the best response is. One final observation is that this method isn't ideal for fixing flickering, because often you'll want to change everything at once -- you just don't want it to flicker. For instance, consider a case where you have a navigation pane and a content pane. Changing pages will change the content pane, but also sometimes cause a different item to be highlighted in the navigation pane, or cause some contextual items to disappear and reappear, etc. However, a solution to that has all the advantages of the onlyreplace proposal, that's simple to describe using existing functionality, and works well with URLs, but doesn't kill all script handlers and such, seems hard. You'd just hook the links with javascript and use that to change the navigation-pane highlight. (Or, in some cases, harness CSS, such as by using the proposed pseudoclass that matches links to the current document.) ~TJ
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 1:37 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: I think the opposite. If I upgraded my site to this, I'd want nearly all the links to onlyreplace. There's only a handful of same-origin links that I'd instead want to trigger a full load. It's very common for several web apps to be installed under a single domain, with links from one to the others: the wiki, forum, and CMS all linking to each other, say. These links are often added to templates by admins as static HTML that the app doesn't even look at. Having them break horribly when the next version of the software uses onlyreplace isn't helpful. Basically, if you're outputting *any* HTML without parsing and sanitizing it, opt-out isn't acceptable, since you *can't* opt out of links in that HTML. And every web app I'm familiar with (admittedly that's about two) does output some HTML without parsing and sanitizing it. Keep in mind that if you can't opt out when you need to, the link will fail. If you can't opt in when you need to, the link will work, just trigger a full reload. Opt-in is a much better idea for that reason alone, given that many apps won't be able to sanitize some of the links they output. It's true that this could be bad on copypasta, but is your failure scenario going to be common? Are people going to often use different bases on different pages in the same origin? I think more usually a single origin will have the same base onlyreplace everywhere, or else not have base onlyreplace at all. In the latter case, you'd presumably want all links to trigger full navigation, since that's what you're indicating with the lack. I didn't remember that it would only be same-domain. You're right that that's a mitigation. But yes, I'd very much expect the same domain to often use different onlyreplace. Different web apps will have different onlyreplaces, and different web apps are often on the same domain. (Also, the same problem you note happens similarly with per-a onlyreplace - what if you copy a link from one page to another, and the new page has *different* elements with the same #ids as elements in the old page? Then you'd be replacing random bits of the page. Is this situation more/less likely than the one you brought up?) I'd hope id collision would be rare enough that this isn't a huge issue. MediaWiki tries to prefix all new classes and id's with mw- for this sort of reason. id's like content are likely to show up pretty often, though, you're right. (And in fact MediaWiki does have an id=content in the default skin.) I disagree, and think that most links would use it on a typical page. I'm not sure anymore. It depends how it's used. You'd just hook the links with javascript and use that to change the navigation-pane highlight. (Or, in some cases, harness CSS, such as by using the proposed pseudoclass that matches links to the current document.) Well, okay. That completely defeats the ease of use of this proposal, though.
Re: [whatwg] a onlyreplace
2009/10/18 Tab Atkins Jr. jackalm...@gmail.com: On Sun, Oct 18, 2009 at 12:20 PM, Nelson Menezes flying.mushr...@gmail.com wrote: 2009/10/18 Tab Atkins Jr. jackalm...@gmail.com: As long as the event bubbles, you can always just listen at the document root and then check event.target to see who got updated. That way you don't have to wait, nor do you have to know which specific bits are getting replaced. You would want the event to fire once, though, regardless of how many targets are being replaced. Otherwise you won't be able to distinguish 3 events generated by one response with content for #div1,#div2, and #div3. Event.target should be the original a or form element, or the window object if the request originated via scripting. My thoughts were that the event fires at the replaced elements, not the a or form that triggered the navigation. So you *would* be able to distinguish multiple elements, as their event.target would point to each element as appropriate. This isn't a click or whatever event, it's a load/unload event. The a or form isn't doing either. Sorry, I had in mind being able to re-apply event listeners to the DOM once the new content was loaded. Of course you can do that in several localised places rather than overall on the whole document (it will be more efficient anyway). Still, it would be nice to be able to identify that all my bits of content are now loaded and being able to have an event handler that gets called once, rather than having to account for all the IDs loading independently: I might want to do something that involves several parts of the new content (e.g. highlight it to make the change obvious to the user). Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 2:31 PM, Nelson Menezes flying.mushr...@gmail.com wrote: Sorry, I had in mind being able to re-apply event listeners to the DOM once the new content was loaded. Of course you can do that in several localised places rather than overall on the whole document (it will be more efficient anyway). Well, the best way to do this is probably to use event delegation in the first place, so you don't have to reinitialize listeners every time. jQuery makes this extremely easy with the $(target).live(event, callback) functionality, but it's pretty simple to do by hand as well. Still, it would be nice to be able to identify that all my bits of content are now loaded and being able to have an event handler that gets called once, rather than having to account for all the IDs loading independently: I might want to do something that involves several parts of the new content (e.g. highlight it to make the change obvious to the user). Worst case, you just have a listener on body which notes the id of the target as each swapIn event bubbles up to it, and calls some function when it's received all of them. This would be really easy to automate. ~TJ
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 1:15 PM, Aryeh Gregor simetrical+...@gmail.com wrote: On Sun, Oct 18, 2009 at 1:37 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: I think the opposite. If I upgraded my site to this, I'd want nearly all the links to onlyreplace. There's only a handful of same-origin links that I'd instead want to trigger a full load. It's very common for several web apps to be installed under a single domain, with links from one to the others: the wiki, forum, and CMS all linking to each other, say. These links are often added to templates by admins as static HTML that the app doesn't even look at. Having them break horribly when the next version of the software uses onlyreplace isn't helpful. Basically, if you're outputting *any* HTML without parsing and sanitizing it, opt-out isn't acceptable, since you *can't* opt out of links in that HTML. And every web app I'm familiar with (admittedly that's about two) does output some HTML without parsing and sanitizing it. Keep in mind that if you can't opt out when you need to, the link will fail. If you can't opt in when you need to, the link will work, just trigger a full reload. Opt-in is a much better idea for that reason alone, given that many apps won't be able to sanitize some of the links they output. This seems compelling. I agree, then. @onlyreplace on base defines the id-list, and then @onlyreplace on links/forms says I should carry the onlyreplace semantics. In the former case it's a space-separated list of IDREFs, in the latter it's a binary attribute. You'd just hook the links with javascript and use that to change the navigation-pane highlight. (Or, in some cases, harness CSS, such as by using the proposed pseudoclass that matches links to the current document.) Well, okay. That completely defeats the ease of use of this proposal, though. Hmm? No it doesn't. The @onlyreplace still makes the page *way* easier to handle. Needing a little bit more js to hook extra behavior around doesn't seem unreasonable. (It's better than refreshing the navlist just to highlight a new section.) ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 11:50 AM, Schuyler Duveen wha...@graffitiweb.org wrote: The problem is that people will make links that refresh different parts of a document, to the point that the current document is no longer addressable. Use cases for this happen often enough (not necessarily good design, but people will do this) In the past, a good way to give (back) addressability to users is with hash tags. But here, the location changes, and the hash goes away. Standard anchor tags (with no javascript) have generally been addressable to users by default. When this hasn't been true, like with framesets, lots of confusion and frustration ensues. If this is, in the longterm, going to work non-dynamically, then things should be addressable by default. It's one of the killer features of the web :-) You're right, and this makes me think more strongly that restricting the ability to specify the replaceable bits to just base is the right way to do this. I'm starting to think the addressability is the main constraint. What if the original @onlyreplace anchor tag: a onlyreplace=id1 id2 href=page2.html / would be equivalent to something like this: a href=#view(page2.html id1 id2) / which would process onload or onhashchange as we've been describing @onlyreplace and would appear in the browser's location bar. A more complicated one (after two jumps) might look something like: http://example.com/page1.html#view(page2.html id1 id2);view(page3 id3) /sky
Re: [whatwg] a onlyreplace
On Sun, Oct 18, 2009 at 9:42 PM, Schuyler Duveen wha...@graffitiweb.org wrote: Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 11:50 AM, Schuyler Duveen wha...@graffitiweb.org wrote: The problem is that people will make links that refresh different parts of a document, to the point that the current document is no longer addressable. Use cases for this happen often enough (not necessarily good design, but people will do this) In the past, a good way to give (back) addressability to users is with hash tags. But here, the location changes, and the hash goes away. Standard anchor tags (with no javascript) have generally been addressable to users by default. When this hasn't been true, like with framesets, lots of confusion and frustration ensues. If this is, in the longterm, going to work non-dynamically, then things should be addressable by default. It's one of the killer features of the web :-) You're right, and this makes me think more strongly that restricting the ability to specify the replaceable bits to just base is the right way to do this. I'm starting to think the addressability is the main constraint. What if the original @onlyreplace anchor tag: a onlyreplace=id1 id2 href=page2.html / would be equivalent to something like this: a href=#view(page2.html id1 id2) / which would process onload or onhashchange as we've been describing @onlyreplace and would appear in the browser's location bar. A more complicated one (after two jumps) might look something like: http://example.com/page1.html#view(page2.html id1 id2);view(page3 id3) Hmm, that's interesting. So, rather than simply changing the url and hoping that the author is maintaining the correct semantics (so that visiting the url fresh gives you same/similar results), you just explicitly express that the page is a combination of multiple pages. I suppose that if, in your example, you then clicked a a href=page4.html onlyreplace=id3, the url would change to http://example.com/page1.html#view(page2.html id1 id2);view(page4.html id3); that is, it would record the location each segment was drawn from, but not the full history, as that is irrelevant for regenerating the page. Then bookmarking that url and visiting it again would presumably make 3 separate requests, once for page1 for most of the page, and then for page2 and page4 for the particular ids. Right? ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 9:42 PM, Schuyler Duveen wha...@graffitiweb.org wrote: Tab Atkins Jr. wrote: On Sun, Oct 18, 2009 at 11:50 AM, Schuyler Duveen wha...@graffitiweb.org wrote: The problem is that people will make links that refresh different parts of a document, to the point that the current document is no longer addressable. Use cases for this happen often enough (not necessarily good design, but people will do this) In the past, a good way to give (back) addressability to users is with hash tags. But here, the location changes, and the hash goes away. Standard anchor tags (with no javascript) have generally been addressable to users by default. When this hasn't been true, like with framesets, lots of confusion and frustration ensues. If this is, in the longterm, going to work non-dynamically, then things should be addressable by default. It's one of the killer features of the web :-) You're right, and this makes me think more strongly that restricting the ability to specify the replaceable bits to just base is the right way to do this. I'm starting to think the addressability is the main constraint. What if the original @onlyreplace anchor tag: a onlyreplace=id1 id2 href=page2.html / would be equivalent to something like this: a href=#view(page2.html id1 id2) / which would process onload or onhashchange as we've been describing @onlyreplace and would appear in the browser's location bar. A more complicated one (after two jumps) might look something like: http://example.com/page1.html#view(page2.html id1 id2);view(page3 id3) Hmm, that's interesting. So, rather than simply changing the url and hoping that the author is maintaining the correct semantics (so that visiting the url fresh gives you same/similar results), you just explicitly express that the page is a combination of multiple pages. I suppose that if, in your example, you then clicked a a href=page4.html onlyreplace=id3, the url would change to http://example.com/page1.html#view(page2.html id1 id2);view(page4.html id3); that is, it would record the location each segment was drawn from, but not the full history, as that is irrelevant for regenerating the page. Then bookmarking that url and visiting it again would presumably make 3 separate requests, once for page1 for most of the page, and then for page2 and page4 for the particular ids. Right? Exactly. These are the use cases I think we're targeting with such addressability: (when considering some server-side request filter, as well) 1. Avoid flicker and state-reinitialization between similar pages. 2. preserve scroll context across loading similar pages. 3. robots crawling ajax-states reliably (and efficiently) 4. standardize addressability of (most) ajax states 5. Provide AJAX features to static pages that are low-hanging fruit. (considered as those mentioned above) 6. AJAX pages could also use more structure in the hash-tag e.g. to preserve their own state in the hash even while a user visits a specific part of the page 7. simplify very standard behavior in AJAX sites, especially in contexts that affect accessibility (like dynamic form submission) /sky
Re: [whatwg] a onlyreplace
On Fri, Oct 16, 2009 at 4:43 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: [snip] Isn't if inefficient to request the whole page and then throw most of it out? With proper AJAX you can just request the bits you want. == This is a valid complaint, but one which I don't think is much of a problem for several reasons. [snip] 3. Because this is a declarative mechanism (specifying WHAT you want, not HOW to get it), it has great potential for transparent optimizations behind the scenes. [snip] Yes— A HTTP request header that gives the only-replace IDs requested, and the server is free to pare the page down to that (or not). I hit reply to point out this possibility but then saw you already basically thought of it, but a query parameter is not a good method: it'll break bookmarking ... and preserving bookmarking is one of the most attractive aspects of this proposal. [snip] What about document.write()? What if the important fragment of the page is produced by document.write()? Then you're screwed. document.write()s contained in script blocks inside the target fragment will run when they get inserted into the page, but document.write()s outside of that won't. Producing the target fragment with document.write() is a no-go from the start. Don't do that anyway; it's a bad idea. I'm guessing that the rare case where you need to write into a replaced ID you can simply have a JS hook that fires on the load and fixes up the replaced sections as needed.
Re: [whatwg] a onlyreplace
2009/10/17 Jonas Sicking jo...@sicking.cc: On Fri, Oct 16, 2009 at 11:06 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: Promoting this reply to top-level because I think it's crazy good. On Fri, Oct 16, 2009 at 11:09 AM, Aryeh Gregor simetrical+...@gmail.com wrote: On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: As well, this still doesn't answer the question of what to do with script links between the static content and the original page, like event listeners placed on content within the static. Do they get preserved? How would that work? If they don't, then some of the benefit of 'static' content is lost, since it will be inoperable for a moment after each pageload while the JS reinitializes. Script links should be preserved somehow, ideally. I would like to see this be along the lines of AJAX reload of some page content, without JavaScript and with automatically working URLs. [snip] I'm drawn back to my original proposal. The idea would be as follows: instead of loading the new page in place of the new one, just parse it, extract the bit you want, plug that into the existing DOM, and throw away the rest. More specifically, suppose we mark the dynamic content instead of the static. Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. This. Is. BRILLIANT. [snip] Thoughts? We actually have a similar technology in XUL called overlays [1], though we use that for a wholly different purpose. Anyhow, this is certainly an interesting suggestion. You can actually mostly implement it using the primitives in HTML5 already. By using pushState and XMLHttpRequest you can download the page and change the current page's URI, and then use the DOM to replace the needed parts. The only thing that you can't do is stream in the new content since mutations aren't dispatched during parsing. For some reason I'm still a bit uneasy about this feature. It feels a bit fragile for some reason. One thing I can think of is what happens if the load stalls or fails halfway through the load. Then you could end up with a page that contains half of the old page and half the new. Also, what should happen if the user presses the 'back' button? Don't know how big of a problem these issues are, and they are quite possibly fixable. I'm definitely curious to hear what developers that would actually use this think of the idea. I have spent most of last night trying to figure out what's wrong with this proposal. I can't think of anything important except for the back button behaviour. The suggestions I had have already been mentioned: the base tag extension and the marker HTTP headers. You'd obviously also need a JS hook to be able to invoke this functionality programmatically (location.onlyreplace...?) Another plus point for this idea is that it is implementable on existing browsers with some JS (I'm trying something simple at the moment and it works, albeit only for XML documents). As for the back button, there are a few possibilities: - Reload the full page - Load process the document using the same onlyreplace behaviour as explained in the original email - Allow a response header that specifies which of the above the browser should do on clicking the back button (backwards-navigation-safe: True?) - The browser remembers the state of the document as it was prior to each history point and resets it to that state before applying the point in history we are jumping to (yikes!) Any concerns about caching that aren't covered by the above? Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
On Sat, Oct 17, 2009 at 12:22 AM, Jonas Sicking jo...@sicking.cc wrote: On Fri, Oct 16, 2009 at 11:06 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: Promoting this reply to top-level because I think it's crazy good. On Fri, Oct 16, 2009 at 11:09 AM, Aryeh Gregor simetrical+...@gmail.com wrote: On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: As well, this still doesn't answer the question of what to do with script links between the static content and the original page, like event listeners placed on content within the static. Do they get preserved? How would that work? If they don't, then some of the benefit of 'static' content is lost, since it will be inoperable for a moment after each pageload while the JS reinitializes. Script links should be preserved somehow, ideally. I would like to see this be along the lines of AJAX reload of some page content, without JavaScript and with automatically working URLs. [snip] I'm drawn back to my original proposal. The idea would be as follows: instead of loading the new page in place of the new one, just parse it, extract the bit you want, plug that into the existing DOM, and throw away the rest. More specifically, suppose we mark the dynamic content instead of the static. Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. This. Is. BRILLIANT. [snip] Thoughts? We actually have a similar technology in XUL called overlays [1], though we use that for a wholly different purpose. Interesting. It does seem like nearly the same idea in practice. Anyhow, this is certainly an interesting suggestion. You can actually mostly implement it using the primitives in HTML5 already. By using pushState and XMLHttpRequest you can download the page and change the current page's URI, and then use the DOM to replace the needed parts. The only thing that you can't do is stream in the new content since mutations aren't dispatched during parsing. Yup, it's basic AJAX (or AHAH if you want to be specific, I guess) with some history hacking. Doing this in JS is completely possible (it's done today), it's just non-trivial and, duh, requires js. (However, I'm still not sure what the accessibility/searchability story is for AJAXy single-page apps that operate similarly. I'm concerned that it's suboptimal, but I'm pretty sure that @onlyreplace solves those issues by allowing such clients to just perform ordinary navigation if they don't want to/don't know how to deal with @onlyreplace properly. The fact that @onlyreplace is a simple declarative mechanism, however, may allow such clients to finally handle this sort of interaction properly, as they can predict in advance which parts of the page will change; something that is difficult/impossible to do in AJAX apps without actually running the JS and watching for mutation.) For some reason I'm still a bit uneasy about this feature. It feels a bit fragile for some reason. One thing I can think of is what happens if the load stalls or fails halfway through the load. Then you could end up with a page that contains half of the old page and half the new. I imagine a browser could stall on swapping in the new bits until it's found all of them? I'm not sure if that would give too much of a penalty in common situations or not. This same sort of situation can occur with an AJAX load too. There you have error callbacks, though. Does it feel like something similar might be necessary? I'd prefer to keep this as transparent as possible. Heck, though, this situation can occur with an *ordinary* load. When that happens you just get a partial page. We don't have special handling for that; we just expect the user to hit Refresh and carry on. @onlyreplace is supposed to be robust against refreshing, so do we expect partial-page loads to be any worse under it than under ordinary navigation? Also, what should happen if the user presses the 'back' button? If the browser can remember what the page state was previously, just swap in the old parts. If not, but it at least remembers what parts were replaced, make a fresh request for the previous page and substitute in just those bits. If it can't remember anything, just do an ordinary navigation with a full page swap. It should act as exactly like current Back behavior as
Re: [whatwg] a onlyreplace
Tab Atkins Jr. schrieb: On Sat, Oct 17, 2009 at 12:22 AM, Jonas Sicking jo...@sicking.cc wrote: Also, what should happen if the user presses the 'back' button? If the browser can remember what the page state was previously, just swap in the old parts. If not, but it at least remembers what parts were replaced, make a fresh request for the previous page and substitute in just those bits. If it can't remember anything, just do an ordinary navigation with a full page swap. It should act as exactly like current Back behavior as possible. We're not really playing with the semantics of navigation, so that shouldn't be difficult. I agree to that. I click a link on a page with an URI, and after clicking I get a new page with another URI - so if I hit the back button, I expect getting back the page I had seen before clicking the link. (Of course with the browser-specific peculiarities - Firefox e.g. remembers the scroll position, others may not...) The user experience when using the back button should not differ whether a browser supports @onlyreplace or not. On Sat, Oct 17, 2009 at 3:53 AM, Gregory Maxwell gmaxw...@gmail.com wrote: I'm guessing that the rare case where you need to write into a replaced ID you can simply have a JS hook that fires on the load and fixes up the replaced sections as needed. The functioning of load events here confuses me a bit, because I've never done any hacking in that area and so don't understand the mechanics well enough to know what's reasonable. Should the new page still fire a load event once its replaceable content has loaded? I'm guessing that the old page never fires an unload event? I really don't know what should happen in this area. (After giving it a little thought, though, I think we shouldn't change the semantics of load/unload/etc. These are still useful, after all, for when the page *is* completely unloaded or loaded, such as on first visit or when the user hits Refresh. We'd probably want a new set of events that fire at the elements being swapped out, and then at the new elements once they've been pushed in.) I admit I don't fully understand load events either. If I get it correctly, this is about functions called on load, that access elements in the replaceable parts of the page. A common use case for this is setting the focus on the first input element of a form. I don't think that this can be solved at the UA side, some authoring will be necessary; some possible workarounds are: - Put page-specific scripts into a separate script element with an id, and include it in the @onlyreplace list; - make one script that fits for all pages, by checking if an element exists before doing actions on it; - instead of using body onLoad=foo(), put the function call into a script element at the bottom of the replaceable element. Anyway such things would be much easier (with or without @onlyreplace) if the onLoad event handler would be allowed on every HTML element rather than on window and body only: input type=text name=Name onLoad=this.focus() But this looks that trivial to me - element.onLoad must have been suggested long ago and been declined for good reasons, I assume?
Re: [whatwg] a onlyreplace
This feels like really nice sugar, but maybe the first step should be to get the shim out that gets it working using JS now and then see how it works in practice. I totally understand why this looks exciting, but I have the same uneasiness as Jonas. It feels like a LOT of magic to go grab a page and grab out the id and . and I am sure there are edges. Cool idea for sure! It also feels like this should work nicely with the history/state work that already exists. On Sat, Oct 17, 2009 at 9:57 AM, Markus Ernst derer...@gmx.ch wrote: Tab Atkins Jr. schrieb: On Sat, Oct 17, 2009 at 12:22 AM, Jonas Sicking jo...@sicking.cc wrote: Also, what should happen if the user presses the 'back' button? If the browser can remember what the page state was previously, just swap in the old parts. If not, but it at least remembers what parts were replaced, make a fresh request for the previous page and substitute in just those bits. If it can't remember anything, just do an ordinary navigation with a full page swap. It should act as exactly like current Back behavior as possible. We're not really playing with the semantics of navigation, so that shouldn't be difficult. I agree to that. I click a link on a page with an URI, and after clicking I get a new page with another URI - so if I hit the back button, I expect getting back the page I had seen before clicking the link. (Of course with the browser-specific peculiarities - Firefox e.g. remembers the scroll position, others may not...) The user experience when using the back button should not differ whether a browser supports @onlyreplace or not. On Sat, Oct 17, 2009 at 3:53 AM, Gregory Maxwell gmaxw...@gmail.com wrote: I'm guessing that the rare case where you need to write into a replaced ID you can simply have a JS hook that fires on the load and fixes up the replaced sections as needed. The functioning of load events here confuses me a bit, because I've never done any hacking in that area and so don't understand the mechanics well enough to know what's reasonable. Should the new page still fire a load event once its replaceable content has loaded? I'm guessing that the old page never fires an unload event? I really don't know what should happen in this area. (After giving it a little thought, though, I think we shouldn't change the semantics of load/unload/etc. These are still useful, after all, for when the page *is* completely unloaded or loaded, such as on first visit or when the user hits Refresh. We'd probably want a new set of events that fire at the elements being swapped out, and then at the new elements once they've been pushed in.) I admit I don't fully understand load events either. If I get it correctly, this is about functions called on load, that access elements in the replaceable parts of the page. A common use case for this is setting the focus on the first input element of a form. I don't think that this can be solved at the UA side, some authoring will be necessary; some possible workarounds are: - Put page-specific scripts into a separate script element with an id, and include it in the @onlyreplace list; - make one script that fits for all pages, by checking if an element exists before doing actions on it; - instead of using body onLoad=foo(), put the function call into a script element at the bottom of the replaceable element. Anyway such things would be much easier (with or without @onlyreplace) if the onLoad event handler would be allowed on every HTML element rather than on window and body only: input type=text name=Name onLoad=this.focus() But this looks that trivial to me - element.onLoad must have been suggested long ago and been declined for good reasons, I assume?
Re: [whatwg] a onlyreplace
On Sat, Oct 17, 2009 at 11:16 AM, Dion Almaer d...@almaer.com wrote: This feels like really nice sugar, but maybe the first step should be to get the shim out that gets it working using JS now and then see how it works in practice. I totally understand why this looks exciting, but I have the same uneasiness as Jonas. It feels like a LOT of magic to go grab a page and grab out the id and . and I am sure there are edges. Cool idea for sure! It also feels like this should work nicely with the history/state work that already exists. Yeah, I think this puts the finger on my uneasiness nicely. There's simply a lot of stuff going on with very little control for the author. I'd love to see a JS library developed on top of pushState/XMLHttpRequest that implements this functionality, and then see that JS library deployed on websites, and see what the experiences from that are. If it turns out that this works well then that would be a strong case for adding this to browsers natively. In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. / Jonas
Re: [whatwg] a onlyreplace
2009/10/17 Jonas Sicking jo...@sicking.cc: In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. Well, here's a badly-hacked-together solution that emulates this behaviour... I think it'll be helpful even if it only gets used in a JS library as you mention (change the attribute to a classname then). Still, it can be made to work with today's browsers: http://test.fittopage.org/page1.php Nelson Menezes http://fittopage.org
Re: [whatwg] a onlyreplace
If you'd like to see what this looks like in Javascript, I implemented this technique several years ago. One place you can see it publicly is the swapFromHttp() function at: http://havel.columbia.edu/media_panels/js/MochiPlus.js You can see it in action on some pages like: http://havel.columbia.edu/media_panels/video_window/?material=abrams where it adds in the page on the left from this file http://havel.columbia.edu/media_panels/materials/abrams.html One of the big issues we found using it on some other sites is that javascript listeners (rather than onclick= attributes), and other DOM pointers in the system became stale. Thus, only half the problem was solved. Also, the problem (as I implemented it) is that XMLHttpRequest.xml has been very finicky in past (and current) browsers. My comments in the code reflect some of the things you need to make sure you're doing to make it work across browsers (at least if you want a DOM vs. regex implementation): * IE 6 needed the Content-type: text/xml * Firefox (?2.x) wants xmlns=http://www.w3.org/1999/xhtml; in html tag * IE and Safari don't handle named entities like nbsp; well in this context and should be numeric (e.g. #160;) Vendors might better serve us by reducing these hoops to jump through so a javascript library could do the job reliably. This method did make it much easier to leverage server template code. But since it largely simplifies server template code, then why not stick with server-side solutions like Ian Bicking's: http://blog.ianbicking.org/2008/09/08/inverted-partials/ It's still a bit weird that this proposal, instead of allowing every element to be a link (like XHTML2), would allow every element to be something like an IFRAME (all while a thread remembering how evil framesets are continues). cheers, sky Date: Sat, 17 Oct 2009 11:34:25 -0700 From: Jonas Sicking jo...@sicking.cc To: Dion Almaer d...@almaer.com Cc: Markus Ernst derer...@gmx.ch, Tab Atkins Jr. jackalm...@gmail.com, Aryeh Gregor simetrical+...@gmail.com, whatwg wha...@whatwg.org Subject: Re: [whatwg] a onlyreplace Message-ID: 63df84f0910171134j193e35exf4d79dcddc5de...@mail.gmail.com Content-Type: text/plain; charset=ISO-8859-1 On Sat, Oct 17, 2009 at 11:16 AM, Dion Almaer d...@almaer.com wrote: This feels like really nice sugar, but maybe the first step should be to get the shim out that gets it working using JS now and then see how it works in practice. I totally understand why this looks exciting, but I have the same uneasiness as Jonas. ?It feels like a LOT of magic to go grab a page and grab out the id and . and I am sure there are edges. Cool idea for sure! It also feels like this should work nicely with the history/state work that already exists. Yeah, I think this puts the finger on my uneasiness nicely. There's simply a lot of stuff going on with very little control for the author. I'd love to see a JS library developed on top of pushState/XMLHttpRequest that implements this functionality, and then see that JS library deployed on websites, and see what the experiences from that are. If it turns out that this works well then that would be a strong case for adding this to browsers natively. In fact, you don't even need to use pushState. For now this can be faked using onhashchange and fragment identifier tricks. It's certainly not as elegant as pushState (that is, after all, why pushState was added), but it's something that can be tried today. / Jonas -- ___ whatwg mailing list whatwg@lists.whatwg.org http://lists.whatwg.org/listinfo.cgi/whatwg-whatwg.org End of whatwg Digest, Vol 67, Issue 81 **
[whatwg] a onlyreplace
Promoting this reply to top-level because I think it's crazy good. On Fri, Oct 16, 2009 at 11:09 AM, Aryeh Gregor simetrical+...@gmail.com wrote: On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: As well, this still doesn't answer the question of what to do with script links between the static content and the original page, like event listeners placed on content within the static. Do they get preserved? How would that work? If they don't, then some of the benefit of 'static' content is lost, since it will be inoperable for a moment after each pageload while the JS reinitializes. Script links should be preserved somehow, ideally. I would like to see this be along the lines of AJAX reload of some page content, without JavaScript and with automatically working URLs. [snip] I'm drawn back to my original proposal. The idea would be as follows: instead of loading the new page in place of the new one, just parse it, extract the bit you want, plug that into the existing DOM, and throw away the rest. More specifically, suppose we mark the dynamic content instead of the static. Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. This. Is. BRILLIANT. Single-page apps are already becoming common for js-heavy sites. The obvious example is something like Gmail, but it's becoming more common everywhere. The main benefit of doing this is that you never dump the script context, so you only have to parse/execute/apply scripting *once* across the page, making really heavy libraries actually usable. In fact, writing a single-page app was explicitly given as a suggestion in the Global Script thread. Even in contexts with lighter scripts, there can still be substantial run-time rewriting of the page which a single-page app can avoid doing multiple times (frex, transforming a nested list into a tree control). The problem, though, is that single-page apps are currently a bit clunky to write. They require javascript to function, and the necessary code is relatively large and clunky, even in libraries like jQuery which make the process much simpler. It requires you to architect your site around the design, either producing a bunch of single-widget files that you query for and slap into place, or some relatively complex client-side logic to parse data structures into HTML. It's also very hard to get accessibility and graceful degradation right, requiring you to basically completely duplicate everything in a static form. Finally, preserving bookmarkability/general deeplinking (such as from a search engine) requires significant effort with history management and url hacking. Aryeh's suggestion, though, solves *all* of these problems with a single trivial attribute. You first design a static multi-page site like normal, with the only change being this attribute on your navigation links specifying the dynamic/replaceable portions of the page. In a legacy client, then, you have a perfectly serviceable multipage site, with the only problems being the reloading of js and such on each pageload. In a supporting client, though, clicking a link causes the browser to perform an ordinary request for the target page (requiring *no* special treatment from the author), parse/treebuild the new page, and then yank out the relevant fragments and replace bits in the current page with them. The url/history automatically updates properly; bookmarking the page and visiting it later will take you to appropriate static page that already exists. Script context is maintained, listeners stay around, overall page state remains stable across 'pageloads'. It's a declarative, accessible, automatic, and EASY way of creating the commonest form of single-page apps. This brings benefits to more than just the traditional js-heavy apps. My company's web site utilizes jQuery for a lot of small upgrades in the page template (like a hover-expand accordion for the main nav), and for certain things on specific pages. I know that loading the library, and applying the template-affecting code, slows down my page loads, but it's not significant enough to be worth the enormous effort to create an accessible, search-engine friendly single-page app. This would solve my problem trivially, though, providing a better overall UI to my visitors (snappier page loads) without
Re: [whatwg] a onlyreplace
A few public responses to issues/questions brought up in IRC: (thanks, Aryeh and Philip!) How is this better than iframe seamless and a target? = It's significantly better in multiple ways, actually. 1. iframes, like frames before them, break bookmarking. If a user bookmarks the page and returns to it later, or gets deeplinked via a search engine or a link from a friend, the iframe won't show the correct content. The only way around this is some fairly non-trivial url-hacking with javascript, altering the displayed url as the user navigates the iframe, and parsing a deeplink url into an appropriate url for the iframe on initial pageload. @onlyreplace, on the other hand, automatically works perfectly with bookmarking. The UA still changes urls and inserts history appropriately as you navigate, and on a fresh pageload it just requests the ordinary static page showing the appropriate content. 2. a target can only navigate one iframe at a time. Many/most sites, though, have multiple dynamic sections scattered throughout the page. The main site for my company, frex, has 3 (content, breadcrumbs, and section nav) which *cannot* be combined to display as a single iframe, at least not without including a whole bunch of static content as well. You'd have use javascript to hook the links and manually navigate the additional iframes. @onlyreplace, on the other hand, handles this seamlessly - just include multiple ids in the attribute value. 3. iframes require you to architect your site around them. Rather than a series of independent pages, you must create a single master page and then a number of content-chunk mini-pages. This breaks normal authoring practices (though in some ways it's easier), and requires you to work hard to maintain accessibility and such in the face of these atrophied mini-pages. @onlyreplace works on full, ordinary pages. It's *possible* to link to a content-chunk mini-page instead, but this will spectacularly break if you ever deeplink straight to one of the pages, so it should become automatic for authors to do this correctly. 4. iframes have dubious accessibility and search effects. I don't know if bots can navigate a target links appropriately. I also believe that this causes problems with screen-readers. While either of these sets of UAs can be rewritten to handle iframes better (and handle @onlyreplace replacement as well), with @onlyreplace they *also* have the option of just completely ignoring the attribute and navigating the site as an ordinary multi-page app. Legacy UAs will automatically do so, providing perfect backwards compatibility. Isn't if inefficient to request the whole page and then throw most of it out? With proper AJAX you can just request the bits you want. == This is a valid complaint, but one which I don't think is much of a problem for several reasons. 1. One of the big beneficiaries of @onlyreplace will be fairly ordinary sites that are currently using an ordinary multi-page architecture. All they have to do is add a single tag to the head of their pages, and they automatically get the no-flicker refresh of a single-page app. These sites are *already* grabbing the whole page on each request, so @onlyreplace won't make them take any *additional* bandwidth. It will merely make the user experience smoother by reducing flicker and keeping js-heavy elements of the page template alive. 2. Even though site templates are usually weighter than the dynamic portions of a site, it's still not a very significant wasteage. For comparison, my company's main site is roughly 16kb of template, and somewhere around 2-3k of dynamic page content. (Aryeh - I gave you slightly different numbers in chat because I was counting wrong.) So that's a good 85% of each request being thrown away as irrelevant. However, it's also *only 16kb*, and that's UNCOMPRESSED - after standard gzip compression the template is worth maybe 5kb. So I waste 5kb of bandwidth per request. Big deal. (According to Philip`, my company's site's weight is just on the low side of average.) 3. Because this is a declarative mechanism (specifying WHAT you want, not HOW to get it), it has great potential for transparent optimizations behind the scenes. For example, the browser could tell the server which bits it's interested in replacing, and the server could automatically strip full pages down to only those chunks. This would eliminate virtually all bandwidth waste, while still being completely transparent to the author - they just create ordinary full static pages. Heck, you could even handle this yourself with JS and a bit of server-side coding, intercepting clicks and rewriting the urls to pass the @onlyreplace data in a query parameter, and have a server-side script determine what to return based on that. Less automatic, but fairly simple, and still easier than using JS to do
Re: [whatwg] a onlyreplace
Tab Atkins Jr. schrieb: Promoting this reply to top-level because I think it's crazy good. [...] Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. This. Is. BRILLIANT. Yes it looks like an AJAX killer. The only problem I can see with this is that it's possible for authors to believe that they only need to actually write a single full page, and can just link to fragments containing only the chunk of content to be replaced. This would mostly break bookmarking and deeplinking, as visitors would just receive a chunk of unstyled content separated from the overall page template. However, because it breaks so *visibly* and reliably (unlike, say, framesets, which just break bookmarking by sending you to the 'main page'), I think there would be sufficient pressure for authors to get this right, especially since it's so *easy* to get it right. Actually the problem I mentioned for Aryehs first proposal remains - still, a web designer could go wrong, for example when making a static website by changing another one he/she has made earlier: The body of page1.html could look like: div id=pageHeaderRecipies for vegetarians/div div id=content h1Lovely broccoli/h1 pTake the broccoli and do the following:/p ... /div ul id=navigation lispanBroccoli/span/li lia href=page2.html onlyreplace=contentLeak/a/li /ul The body of page2.html: div id=pageHeaderRecipies for meat eaters/div div id=content h1Lovely leak/h1 pTake the leak and do the following:/p ... /div ul id=navigation lia href=page1.html onlyreplace=contentBroccoli/a/li lispanLeak/span/li /ul Note that the author forgot to change the page header of the meat eaters site he/she had used as raw material. The author will test the site and always see it correctly, while someone who comes from a deep link will see the meat eaters header. Anyway I think that this error is much less likely to be made with the a onlyreplace solution. In many cases, such as template-based CMS sites, the static elements are made in one place only, anyway. I think this is a problem we could live with, in view of the benefits that this solution brings.
Re: [whatwg] a onlyreplace
On Fri, Oct 16, 2009 at 4:10 PM, Markus Ernst derer...@gmx.ch wrote: Yes it looks like an AJAX killer. Well, for a particular common, useful pattern. AJAX will still be alive and well for solving more general classes of problems. Actually the problem I mentioned for Aryehs first proposal remains - still, a web designer could go wrong, for example when making a static website by changing another one he/she has made earlier: The body of page1.html could look like: div id=pageHeaderRecipies for vegetarians/div div id=content h1Lovely broccoli/h1 pTake the broccoli and do the following:/p ... /div ul id=navigation lispanBroccoli/span/li lia href=page2.html onlyreplace=contentLeak/a/li /ul The body of page2.html: div id=pageHeaderRecipies for meat eaters/div div id=content h1Lovely leak/h1 pTake the leak and do the following:/p ... /div ul id=navigation lia href=page1.html onlyreplace=contentBroccoli/a/li lispanLeak/span/li /ul Note that the author forgot to change the page header of the meat eaters site he/she had used as raw material. The author will test the site and always see it correctly, while someone who comes from a deep link will see the meat eaters header. Anyway I think that this error is much less likely to be made with the a onlyreplace solution. In many cases, such as template-based CMS sites, the static elements are made in one place only, anyway. I think this is a problem we could live with, in view of the benefits that this solution brings. Ah, right, that is a potential issue. A non-obvious change that can missed even by an author doing proper checks. Still, as you say, most sites these days are produced by CMSes that centralize the static template, so a change in one place would be properly reflected everywhere. (Also, in your examples you probably want @onlyreplace=content navigation, since your nav is changing from page to page as well. That's a bug that would be found out immediately, though.) ~TJ
Re: [whatwg] a onlyreplace
Tab Atkins Jr. schrieb: [...] The body of page1.html could look like: div id=pageHeaderRecipies for vegetarians/div div id=content h1Lovely broccoli/h1 pTake the broccoli and do the following:/p ... /div ul id=navigation lispanBroccoli/span/li lia href=page2.html onlyreplace=contentLeak/a/li /ul The body of page2.html: div id=pageHeaderRecipies for meat eaters/div div id=content h1Lovely leak/h1 pTake the leak and do the following:/p ... /div ul id=navigation lia href=page1.html onlyreplace=contentBroccoli/a/li lispanLeak/span/li /ul [...] (Also, in your examples you probably want @onlyreplace=content navigation, since your nav is changing from page to page as well. Indeed. Or, maybe I'd do it slightly differently, somehow like: ul id=navigation lia href=page1.html onlyreplace=content class=thisPage onClick=resetNavigation(this)Broccoli/a/li lia href=page2.html onlyreplace=content onClick=resetNavigation(this)Leak/a/li /ul The resetNavigation() function then takes the class attribute from the old link and adds it to the clicked one. So the navigation can be static, and though its appearance remains consistent, whether page2.html is completely loaded, or only the parts defined in @onlyreplace.
Re: [whatwg] a onlyreplace
On Fri, Oct 16, 2009 at 5:08 PM, Markus Ernst derer...@gmx.ch wrote: (Also, in your examples you probably want @onlyreplace=content navigation, since your nav is changing from page to page as well. Indeed. Or, maybe I'd do it slightly differently, somehow like: ul id=navigation lia href=page1.html onlyreplace=content class=thisPage onClick=resetNavigation(this)Broccoli/a/li lia href=page2.html onlyreplace=content onClick=resetNavigation(this)Leak/a/li /ul The resetNavigation() function then takes the class attribute from the old link and adds it to the clicked one. So the navigation can be static, and though its appearance remains consistent, whether page2.html is completely loaded, or only the parts defined in @onlyreplace. Yup, that'd work too. ~TJ
Re: [whatwg] a onlyreplace
On Fri, Oct 16, 2009 at 11:06 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: Promoting this reply to top-level because I think it's crazy good. On Fri, Oct 16, 2009 at 11:09 AM, Aryeh Gregor simetrical+...@gmail.com wrote: On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: As well, this still doesn't answer the question of what to do with script links between the static content and the original page, like event listeners placed on content within the static. Do they get preserved? How would that work? If they don't, then some of the benefit of 'static' content is lost, since it will be inoperable for a moment after each pageload while the JS reinitializes. Script links should be preserved somehow, ideally. I would like to see this be along the lines of AJAX reload of some page content, without JavaScript and with automatically working URLs. [snip] I'm drawn back to my original proposal. The idea would be as follows: instead of loading the new page in place of the new one, just parse it, extract the bit you want, plug that into the existing DOM, and throw away the rest. More specifically, suppose we mark the dynamic content instead of the static. Let's say we add a new attribute to a, like a onlyreplace=foo, where foo is the id of an element on the page. Or better, a space-separated list of elements. When the user clicks such a link, the browser should do something like this: change the URL in the navigation bar to the indicated URL, and retrieve the indicated resource and begin to parse it. Every time an element is encountered that has an id in the onlyreplace list, if there is an element on the current page with that id, remove the existing element and then add the element from the new page. I guess this should be done in the usual fashion, first appending the element itself and then its children recursively, leaf-first. This. Is. BRILLIANT. [snip] Thoughts? We actually have a similar technology in XUL called overlays [1], though we use that for a wholly different purpose. Anyhow, this is certainly an interesting suggestion. You can actually mostly implement it using the primitives in HTML5 already. By using pushState and XMLHttpRequest you can download the page and change the current page's URI, and then use the DOM to replace the needed parts. The only thing that you can't do is stream in the new content since mutations aren't dispatched during parsing. For some reason I'm still a bit uneasy about this feature. It feels a bit fragile for some reason. One thing I can think of is what happens if the load stalls or fails halfway through the load. Then you could end up with a page that contains half of the old page and half the new. Also, what should happen if the user presses the 'back' button? Don't know how big of a problem these issues are, and they are quite possibly fixable. I'm definitely curious to hear what developers that would actually use this think of the idea. / Jonas [1] https://developer.mozilla.org/en/XUL_Overlays