Re: Mutation Observers: a replacement for DOM Mutation Events
On 13/10/11 2:33 PM, Ryosuke Niwa wrote: On Wed, Oct 12, 2011 at 8:14 PM, Sean Hogan shogu...@westnet.com.au mailto:shogu...@westnet.com.au wrote: Maybe you can provide concrete examples (i.e. with code snippets, actual instances of use cases, etc...) Actually, it is the proponents of changing the status-quo and of the more complex solution who bear more responsibility for providing these. But if it helps, here's a specific example: MathJax (http://mathjax.org) is a js lib for rendering math in web-pages. One feature it provides is converting LaTeX into (typically) a HTML representation of the math. It is desirable for the LaTeX source to remain available in the document, and MathJax stores it as the content of a script type=math/tex element. MathJax provides an API for changing the LaTeX source and thus the rendered output. It might be desirable if MathJax could update the rendering automatically in response to changes in the script content. Mutation events would be necessary for this. But what is the appropriate way to signal to other consumers of mutation events that the math rendering changes are to be ignored? Why do you assume that all other mutation observers should ignore such changes? If there's a library that's automatically syncing the document with a server, then such an observer certainly needs to know any mutations that happen in the document. - Ryosuke In the case of MathJax, the HTML rendering for math is generated in the browser. It is only the LaTeX that you would want synced on the server. However, my main concern (which I probably haven't emphasized sufficiently) is that the current proposal is more complex than absolutely necessary. Therefore - it will be complex to implement - it is easy to imagine that the preliminary analysis has missed problems, and - it still doesn't allow different mutation event listeners to safely ignore the possibility of each-other. My concerns may be unreasonable. Given there is an implementation just around the corner, we'll soon have a better idea, rather than just speculating. Sean
Re: Mutation Observers: a replacement for DOM Mutation Events
On Wed, Oct 12, 2011 at 7:51 PM, Sean Hogan shogu...@westnet.com.au wrote: It is different to event listeners. The following document.body.**addEventListener(**DOMAttrModified, handler, false); document.getElementById(**target).addEventListener(**DOMAttrModified, preferred_handler, false); What prevents scripts from then doing document.getElementById(**target).addEventListener(**DOMAttrModified, handler, false); ? allows preferred_handler to prevent handler receiving the event. The problem with allowing some event observer to prevent other observers to receive certain mutation events is that we'll then lose any integrity guarantee once we do that. e.g. when an observer is called with some list of mutations, you wouldn't know whether the current DOM state is the result of those mutations or there had been some other mutations. Without this guarantee, you can't unwind mutation lists to restore the original DOM state for example, and it makes mutation observation useless in some use cases. As such, I'll be strongly opposed to allow such a prevention mechanism. On Wed, Oct 12, 2011 at 8:14 PM, Sean Hogan shogu...@westnet.com.au wrote: Another way of phrasing this deficiency is that the proposal provides a way to signal interest in mutations in regions of a page, but doesn't provide a way to ignore mutations within those regions. So the libs using this API may have to provide their own mechanism for this. Right, and I'd argue that we should NOT provide such a mechanism. On Thu, Oct 13, 2011 at 1:32 AM, Sean Hogan shogu...@westnet.com.au wrote: Why do you assume that all other mutation observers should ignore such changes? If there's a library that's automatically syncing the document with a server, then such an observer certainly needs to know any mutations that happen in the document. - Ryosuke In the case of MathJax, the HTML rendering for math is generated in the browser. It is only the LaTeX that you would want synced on the server. No, my use case addresses the case where you want to mirror the exact DOM state (except event handlers and script elements) elsewhere. And for that to work, I need to be able to see whatever MathJax is generating, NOT the LaTeX code. - it still doesn't allow different mutation event listeners to safely ignore the possibility of each-other. I repeat myself again that we shouldn't allow mutation observers to do this. - Ryosuke
Re: Mutation Observers: a replacement for DOM Mutation Events
On 13/10/11 7:58 PM, Ryosuke Niwa wrote: On Thu, Oct 13, 2011 at 1:32 AM, Sean Hogan shogu...@westnet.com.au mailto:shogu...@westnet.com.au wrote: Why do you assume that all other mutation observers should ignore such changes? If there's a library that's automatically syncing the document with a server, then such an observer certainly needs to know any mutations that happen in the document. - Ryosuke In the case of MathJax, the HTML rendering for math is generated in the browser. It is only the LaTeX that you would want synced on the server. No, my use case addresses the case where you want to mirror the exact DOM state (except event handlers and script elements) elsewhere. And for that to work, I need to be able to see whatever MathJax is generating, NOT the LaTeX code. For that use case I think you would be happy with my proposal which doesn't implement any filtering of mutation events at all. By the way, I'm not arguing that the mutation observers proposal should provide a mechanism for hiding some mutations. I'm arguing that whatever solution is provided (even a complex one) still won't make mutation handling straight-forward... so why not just provide the simplest solution and let the js libs sort out the details. Sean
Re: Mutation Observers: a replacement for DOM Mutation Events
On 10/13/2011 05:51 AM, Sean Hogan wrote: My main reservation towards the proposal is its complexity - it promises a lot and I will be surprised if it is as trivial to implement as you have implied. Even then, I'm expecting that it isn't the improvement (over the status-quo) that everyone is speculating. It's great that there is going to be an implementation real-soon-now so that my concerns can be allayed / confirmed. I haven't said this API is trivial to implement. In fact, it is a bit tricky to implement, but while I've been implementing it, the API itself has felt pretty good. -Olli
Re: Mutation Observers: a replacement for DOM Mutation Events
On 10/13/2011 11:32 AM, Sean Hogan wrote: On 13/10/11 2:33 PM, Ryosuke Niwa wrote: On Wed, Oct 12, 2011 at 8:14 PM, Sean Hogan shogu...@westnet.com.au mailto:shogu...@westnet.com.au wrote: Maybe you can provide concrete examples (i.e. with code snippets, actual instances of use cases, etc...) Actually, it is the proponents of changing the status-quo and of the more complex solution who bear more responsibility for providing these. But if it helps, here's a specific example: MathJax (http://mathjax.org) is a js lib for rendering math in web-pages. One feature it provides is converting LaTeX into (typically) a HTML representation of the math. It is desirable for the LaTeX source to remain available in the document, and MathJax stores it as the content of a script type=math/tex element. MathJax provides an API for changing the LaTeX source and thus the rendered output. It might be desirable if MathJax could update the rendering automatically in response to changes in the script content. Mutation events would be necessary for this. But what is the appropriate way to signal to other consumers of mutation events that the math rendering changes are to be ignored? Why do you assume that all other mutation observers should ignore such changes? If there's a library that's automatically syncing the document with a server, then such an observer certainly needs to know any mutations that happen in the document. - Ryosuke In the case of MathJax, the HTML rendering for math is generated in the browser. It is only the LaTeX that you would want synced on the server. However, my main concern (which I probably haven't emphasized sufficiently) is that the current proposal is more complex than absolutely necessary. Therefore - it will be complex to implement If that is the case, it is implementation problem. And the the API isn't *that* complex to implement. It has some complexity, especially, I could imagine, if the browser engine doesn't have its internal mutation observing APIs. But that is all implementation details. Also, I'd rather add some complexity to browser implementations than to each web page using the API. - it is easy to imagine that the preliminary analysis has missed problems, and If you find any such problems, please tell us :) It would be better to improve the API sooner than later. - it still doesn't allow different mutation event listeners to safely ignore the possibility of each-other. Depending on how to interpret this, the API does exactly that. a MutationObserver doesn't know, nor is handled differently, if there are other MutationObservers. The old mutation event listeners affect to each others and some listeners may not be called if a listener happens to call stopPropagation(). And since you can't know where all document tree has mutation event listeners, and in which order, you don't actually always know what all effects calling stopPropagation() / stopImmediatePropagation() has. My concerns may be unreasonable. Given there is an implementation just around the corner, we'll soon have a better idea, rather than just speculating. Yeah, hopefully real soon. -Olli Sean
Re: Mutation Observers: a replacement for DOM Mutation Events
On 12/10/11 3:26 AM, Tab Atkins Jr. wrote: On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. This proposal doesn't entirely avoid the issue of event distribution. There is no equivalent of event.stopPropagation() and hence no way to prevent mutation records being delivered to observers. The observers may have to be written with this is in mind. For example, what if two observers can potentially handle the same mutation - which one should handle it? Alternatively, some code might respond to an attribute by adding content to the DOM. What if there are mutation listeners that could respond to that added content? Is it desired that they ignore or handle it? Another pattern that doesn't seem to be reliably handled is mutations within DOM fragments that are temporarily removed from the document. That is: - if the fragment always remains in the document then all mutations can be monitored by observers on the document (or document.body), but - if the fragment is removed from the document followed by mutation observers being called, then any further mutations won't be delivered to the observers, even when the fragment is reinserted into the document. The exact behavior in this scenario depends on whether mutations complete within one microtask or more than one Sean.
Re: Mutation Observers: a replacement for DOM Mutation Events
On 10/12/2011 02:00 PM, Sean Hogan wrote: On 12/10/11 3:26 AM, Tab Atkins Jr. wrote: On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. This proposal doesn't entirely avoid the issue of event distribution. There is no equivalent of event.stopPropagation() and hence no way to prevent mutation records being delivered to observers. The observers may have to be written with this is in mind. For example, what if two observers can potentially handle the same mutation - which one should handle it? Both. Or the observers need to somehow communicate with each others to decide who handles it. This is no different to event listeners. Event listeners don't know if there are other listeners before them or after them. You can have several listeners in the same target and different script libraries may have added them without knowing about each others. Alternatively, some code might respond to an attribute by adding content to the DOM. What if there are mutation listeners that could respond to that added content? Is it desired that they ignore or handle it? Another pattern that doesn't seem to be reliably handled is mutations within DOM fragments that are temporarily removed from the document. That is: - if the fragment always remains in the document then all mutations can be monitored by observers on the document (or document.body), but - if the fragment is removed from the document followed by mutation observers being called, then any further mutations won't be delivered to the observers, even when the fragment is reinserted into the document. The exact behavior in this scenario depends on whether mutations complete within one microtask or more than one If the modifications to the fragment are done during the same microtask, then the observer will just get notified about those modifications. If in different microtask, then observer should observe that fragment (so when the fragment is removed from document, observer.observe(root_of_fragement, options) should be called.). If there was just a global - per document observers, those wouldn't handle all the cases when node is adopted to and from other documents. Also, such observers would make all the DOM mutations slower, since the callback would need to be called all the time. The proposed API allows one to restrict mutation observing to certain set of nodes. Mutations outside that set can be kept as fast as having no mutationobservers at all. And also, since the observed set can expand, and isn't limited to same document handling, it can easily handle cases when nodes are moved to some other document. -Olli Sean.
Re: Mutation Observers: a replacement for DOM Mutation Events
Hi Sean, I find it hard to reason about cases in the abstract. None of the examples you list seem concerning to me (i.e. I believe they can be properly handled), but perhaps it's a failure of my imagination. Maybe you can provide concrete examples (i.e. with code snippets, actual instances of use cases, etc...) On Wed, Oct 12, 2011 at 4:00 AM, Sean Hogan shogu...@westnet.com.au wrote: On 12/10/11 3:26 AM, Tab Atkins Jr. wrote: On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. This proposal doesn't entirely avoid the issue of event distribution. There is no equivalent of event.stopPropagation() and hence no way to prevent mutation records being delivered to observers. The observers may have to be written with this is in mind. For example, what if two observers can potentially handle the same mutation - which one should handle it? Alternatively, some code might respond to an attribute by adding content to the DOM. What if there are mutation listeners that could respond to that added content? Is it desired that they ignore or handle it? Another pattern that doesn't seem to be reliably handled is mutations within DOM fragments that are temporarily removed from the document. That is: - if the fragment always remains in the document then all mutations can be monitored by observers on the document (or document.body), but - if the fragment is removed from the document followed by mutation observers being called, then any further mutations won't be delivered to the observers, even when the fragment is reinserted into the document. The exact behavior in this scenario depends on whether mutations complete within one microtask or more than one Sean.
Re: Mutation Observers: a replacement for DOM Mutation Events
On 13/10/11 12:34 AM, Olli Pettay wrote: On 10/12/2011 02:00 PM, Sean Hogan wrote: On 12/10/11 3:26 AM, Tab Atkins Jr. wrote: On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. This proposal doesn't entirely avoid the issue of event distribution. There is no equivalent of event.stopPropagation() and hence no way to prevent mutation records being delivered to observers. The observers may have to be written with this is in mind. For example, what if two observers can potentially handle the same mutation - which one should handle it? Both. Or the observers need to somehow communicate with each others to decide who handles it. This is no different to event listeners. Event listeners don't know if there are other listeners before them or after them. You can have several listeners in the same target and different script libraries may have added them without knowing about each others. It is different to event listeners. The following document.body.addEventListener(DOMAttrModified, handler, false); document.getElementById(target).addEventListener(DOMAttrModified, preferred_handler, false); allows preferred_handler to prevent handler receiving the event. The observer solution (something like): handler_observer.observe(document.body, ...); preferred_handler_observer.observe(document.getElementById(target), ...); does not. My argument may be weak, but you don't help this discussion by providing an even weaker argument to counter it. Alternatively, some code might respond to an attribute by adding content to the DOM. What if there are mutation listeners that could respond to that added content? Is it desired that they ignore or handle it? Another pattern that doesn't seem to be reliably handled is mutations within DOM fragments that are temporarily removed from the document. That is: - if the fragment always remains in the document then all mutations can be monitored by observers on the document (or document.body), but - if the fragment is removed from the document followed by mutation observers being called, then any further mutations won't be delivered to the observers, even when the fragment is reinserted into the document. The exact behavior in this scenario depends on whether mutations complete within one microtask or more than one If the modifications to the fragment are done during the same microtask, then the observer will just get notified about those modifications. If in different microtask, then observer should observe that fragment (so when the fragment is removed from document, observer.observe(root_of_fragement, options) should be called.). If there was just a global - per document observers, those wouldn't handle all the cases when node is adopted to and from other documents. I didn't think of that but I don't think it's a good idea anyway. If observing mutations in another document is required then use their per document observer. Or have I missed something? Also, such observers would make all the DOM mutations slower, since the callback would need to be called all the time. Yes, but you have to remember that many DOM mutations necessitate page reflow, and the cost of mutation listeners has to be weighed against that, not the execution time of one DOM operation. In the extreme case, per document observers won't be any slower than observer.observe(document, all_options); The proposed API allows one to restrict mutation observing to certain set of nodes. Mutations outside that set can be kept as fast as having no mutationobservers at all. And also, since the observed set can expand, and isn't limited to same document handling, it can easily handle cases when nodes are moved to some other document. My main reservation towards the proposal is its complexity - it promises a lot and I will be surprised if it is as trivial to implement as you have implied. Even then, I'm expecting that it isn't the improvement (over the status-quo) that everyone is speculating. It's great that there is going to be an implementation real-soon-now so that my concerns can be allayed / confirmed.
Re: Mutation Observers: a replacement for DOM Mutation Events
On 13/10/11 4:50 AM, Rafael Weinstein wrote: Hi Sean, I find it hard to reason about cases in the abstract. None of the examples you list seem concerning to me (i.e. I believe they can be properly handled), but perhaps it's a failure of my imagination. I didn't say they can't be properly handled. I said that the proposal by itself doesn't properly handle them, and I suggested a similar but simpler solution that also doesn't properly handle them by itself. Another way of phrasing this deficiency is that the proposal provides a way to signal interest in mutations in regions of a page, but doesn't provide a way to ignore mutations within those regions. So the libs using this API may have to provide their own mechanism for this. Maybe you can provide concrete examples (i.e. with code snippets, actual instances of use cases, etc...) Actually, it is the proponents of changing the status-quo and of the more complex solution who bear more responsibility for providing these. But if it helps, here's a specific example: MathJax (http://mathjax.org) is a js lib for rendering math in web-pages. One feature it provides is converting LaTeX into (typically) a HTML representation of the math. It is desirable for the LaTeX source to remain available in the document, and MathJax stores it as the content of a script type=math/tex element. MathJax provides an API for changing the LaTeX source and thus the rendered output. It might be desirable if MathJax could update the rendering automatically in response to changes in the script content. Mutation events would be necessary for this. But what is the appropriate way to signal to other consumers of mutation events that the math rendering changes are to be ignored? On Wed, Oct 12, 2011 at 4:00 AM, Sean Hoganshogu...@westnet.com.au wrote: On 12/10/11 3:26 AM, Tab Atkins Jr. wrote: On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. This proposal doesn't entirely avoid the issue of event distribution. There is no equivalent of event.stopPropagation() and hence no way to prevent mutation records being delivered to observers. The observers may have to be written with this is in mind. For example, what if two observers can potentially handle the same mutation - which one should handle it? Alternatively, some code might respond to an attribute by adding content to the DOM. What if there are mutation listeners that could respond to that added content? Is it desired that they ignore or handle it? Another pattern that doesn't seem to be reliably handled is mutations within DOM fragments that are temporarily removed from the document. That is: - if the fragment always remains in the document then all mutations can be monitored by observers on the document (or document.body), but - if the fragment is removed from the document followed by mutation observers being called, then any further mutations won't be delivered to the observers, even when the fragment is reinserted into the document. The exact behavior in this scenario depends on whether mutations complete within one microtask or more than one Sean.
Re: Mutation Observers: a replacement for DOM Mutation Events
On Wed, Oct 12, 2011 at 8:14 PM, Sean Hogan shogu...@westnet.com.au wrote: Maybe you can provide concrete examples (i.e. with code snippets, actual instances of use cases, etc...) Actually, it is the proponents of changing the status-quo and of the more complex solution who bear more responsibility for providing these. But if it helps, here's a specific example: MathJax (http://mathjax.org) is a js lib for rendering math in web-pages. One feature it provides is converting LaTeX into (typically) a HTML representation of the math. It is desirable for the LaTeX source to remain available in the document, and MathJax stores it as the content of a script type=math/tex element. MathJax provides an API for changing the LaTeX source and thus the rendered output. It might be desirable if MathJax could update the rendering automatically in response to changes in the script content. Mutation events would be necessary for this. But what is the appropriate way to signal to other consumers of mutation events that the math rendering changes are to be ignored? Why do you assume that all other mutation observers should ignore such changes? If there's a library that's automatically syncing the document with a server, then such an observer certainly needs to know any mutations that happen in the document. - Ryosuke
Re: Mutation Observers: a replacement for DOM Mutation Events
On Mon, Oct 10, 2011 at 7:51 PM, Sean Hogan shogu...@westnet.com.au wrote: On 24/09/11 7:16 AM, Adam Klein wrote: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. That seems unworkably restrictive. It's very easy to imagine multiple libraries listening for different kinds of things at the same time. Libraries would just end up re-implementing event distribution, which is something we can avoid by doing it correctly now. ~TJ
Re: Mutation Observers: a replacement for DOM Mutation Events
On 24/09/11 7:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) A simpler solution that is free from the faults listed in that email would be to have (at max) one mutation observer for the whole page context. I guess this would be called at the end of the task or immediately before page reflows. If a js lib (or multiple libs) want to provide finer grained mutation handling then let them work out the details. Sean
CfC: adding Mutation Observers to DOM4; deadline Oct 14 [Was: Re: Mutation Observers: a replacement for DOM Mutation Events]
On 10/6/11 9:11 AM, ext Arthur Barstow wrote: On 9/30/11 3:40 PM, ext Ms2ger wrote: On 09/29/2011 04:32 PM, Doug Schepers wrote: Hi, Adam- I'm glad to see some progress on a replacement for Mutation Events. Would you be interested in being the editor for this spec? It's already in our charter, we just need someone to take it up. Olli has offered offlist to be a co-editor, so between the two of you, I think it would be pretty manageable. I'd be happy to help get you started. I repeat my objections to speccing this outside DOM4. I would, of course, welcome Olli or Adam to become co-editors if they would wish that. I scanned the list archive and did not find your objection. Which message(s) includes your objection? Ms2ger responded in IRC that [1] includes his objection (not sure how I could have missed that one ;-)). I don't know why, but I never received the Oct 1 response from Ojan [2] nor the Oct 3 response from Adam [3] and just learned about them today. It appears a next step is to determine if anyone objects to Mutation Observers [4] being added to DOM4. As such, this is a CfC to do so and if anyone has any comments, please reply to this e-mail by October 14. -AB [1] http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0790.html [2] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0029.html [3] http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0003.html [4] http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/1622.html
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/29/2011 04:32 PM, Doug Schepers wrote: Hi, Adam- I'm glad to see some progress on a replacement for Mutation Events. Would you be interested in being the editor for this spec? It's already in our charter, we just need someone to take it up. Olli has offered offlist to be a co-editor, so between the two of you, I think it would be pretty manageable. I'd be happy to help get you started. I repeat my objections to speccing this outside DOM4. I would, of course, welcome Olli or Adam to become co-editors if they would wish that. Ms2ger
Re: Mutation Observers: a replacement for DOM Mutation Events
On Fri, Sep 30, 2011 at 12:40 PM, Ms2ger ms2...@gmail.com wrote: On 09/29/2011 04:32 PM, Doug Schepers wrote: Hi, Adam- I'm glad to see some progress on a replacement for Mutation Events. Would you be interested in being the editor for this spec? It's already in our charter, we just need someone to take it up. Olli has offered offlist to be a co-editor, so between the two of you, I think it would be pretty manageable. I'd be happy to help get you started. I repeat my objections to speccing this outside DOM4. I would, of course, welcome Olli or Adam to become co-editors if they would wish that. I expect Adam and Rafael, the two people on the Google side most appropriate to edit this spec don't care either way. If the rest of the DOM4 editors would like it in DOM4, and Olli is OK with that, then I'm sure we (Google) would be OK with it as well.
Re: Mutation Observers: a replacement for DOM Mutation Events
Hi, Adam- I'm glad to see some progress on a replacement for Mutation Events. Would you be interested in being the editor for this spec? It's already in our charter, we just need someone to take it up. Olli has offered offlist to be a co-editor, so between the two of you, I think it would be pretty manageable. I'd be happy to help get you started. Thanks- -Doug (W3C staff contact for WebApps WG) On 9/23/11 5:16 PM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true, MutationRecords describing changes to // CharacterData nodes should contain the value // of the node before the change. If true without // characterData:
Re: Mutation Observers: a replacement for DOM Mutation Events
On Tue, Sep 27, 2011 at 1:12 PM, Olli Pettay olli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: For each observer, if a registration exists which requests the matching mutation type and whose observed node set contains the target node of the mutation, a MutationRecord is appended to the observer's pending mutation queue. If multiple such registrations exist for a given observer, a single MutationRecord is delivered having the union of the information requested by all registrations (e.g. attributeOldValue). This is actually still ambiguous. What if attributeOldValue is first set to true for document.documentElement, and then false (implicitly or explicitly) for document, should attribute values be reported? Another problematic case is that if we have subtree A and B and both are being observed by same observer but different options. Then some node from A is moved to B. Which options should be used? So, should we define that union means that 'true' values override 'false' values, and attributeFilter values are union'ed the usual way? Yes, I think this is what I actually had in mind: true values override false values. To make API somewhat more consistent, should we change Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. to follow the union-ing. If we're going to do that, I think we need to add the ability to stop listening to a single target (rather than disconnecting from all). But I'm not convinced we need this consistency, as I suspect the above case (covering multiple nodes with different registrations and different options) is quite unusual. - Adam
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/28/2011 07:01 PM, Adam Klein wrote: On Tue, Sep 27, 2011 at 1:12 PM, Olli Pettayolli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: For each observer, if a registration exists which requests the matching mutation type and whose observed node set contains the target node of the mutation, a MutationRecord is appended to the observer's pending mutation queue. If multiple such registrations exist for a given observer, a single MutationRecord is delivered having the union of the information requested by all registrations (e.g. attributeOldValue). This is actually still ambiguous. What if attributeOldValue is first set to true for document.documentElement, and then false (implicitly or explicitly) for document, should attribute values be reported? Another problematic case is that if we have subtree A and B and both are being observed by same observer but different options. Then some node from A is moved to B. Which options should be used? So, should we define that union means that 'true' values override 'false' values, and attributeFilter values are union'ed the usual way? Yes, I think this is what I actually had in mind: true values override false values. Actually attributeFilter is union'ed the usual way only if it is defined always (in all the options). If it is missing, all the attributes should be observed. To make API somewhat more consistent, should we change Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. to follow the union-ing. If we're going to do that, I think we need to add the ability to stop listening to a single target (rather than disconnecting from all). But I'm not convinced we need this consistency, as I suspect the above case (covering multiple nodes with different registrations and different options) is quite unusual. OK, let's keep the re-observe a target the way it is. -Olli - Adam
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/24/2011 12:16 AM, Adam Klein wrote: For each observer, if a registration exists which requests the matching mutation type and whose observed node set contains the target node of the mutation, a MutationRecord is appended to the observer's pending mutation queue. If multiple such registrations exist for a given observer, a single MutationRecord is delivered having the union of the information requested by all registrations (e.g. attributeOldValue). This is actually still ambiguous. What if attributeOldValue is first set to true for document.documentElement, and then false (implicitly or explicitly) for document, should attribute values be reported? Another problematic case is that if we have subtree A and B and both are being observed by same observer but different options. Then some node from A is moved to B. Which options should be used? So, should we define that union means that 'true' values override 'false' values, and attributeFilter values are union'ed the usual way? To make API somewhat more consistent, should we change Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. to follow the union-ing. -Olli
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; Yeah, these methods could return mutationobserver. (Although I don't like the o.observe(foo).observe(bar) kind of coding style, since it doesn't make it clear which instance's method you're calling. But one doesn't need to use that.) where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; s/handleEvent/handleMutations/ Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true, MutationRecords describing changes to // CharacterData nodes should contain the value // of the node before the change. If true without // characterData: true, an Error is thrown. // Filtering DOMString[] attributeFilter; // If provided, only changes to attributes with
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/26/2011 11:47 AM, Olli Pettay wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; Yeah, these methods could return mutationobserver. (Although I don't like the o.observe(foo).observe(bar) kind of coding style, since it doesn't make it clear which instance's method you're calling. But one doesn't need to use that.) where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; s/handleEvent/handleMutations/ Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true, MutationRecords describing changes to // CharacterData nodes should contain the value // of the node before the change. If true without // characterData: true, an Error is thrown. // Filtering DOMString[] attributeFilter; // If provided, only changes to attributes with localName equaling // one of the provided strings will be delivered. If provided without // attribute: true, an Error is thrown. }; Subtree Observation If the subtree option
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. We need to change this name, since per WebIDL 'attribute' can't be used here. I propose we use attr everywhere in the API. MutationRecord has already attrName. attributeOldValue - attrOldValue and attributeFilter - attrFilter -Olli boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true, MutationRecords describing changes to // CharacterData nodes should contain the value // of the node before the change. If true without // characterData: true, an Error is thrown. // Filtering DOMString[] attributeFilter; // If provided, only changes to attributes with localName equaling // one of
Re: Mutation Observers: a replacement for DOM Mutation Events
On Mon, Sep 26, 2011 at 11:05 AM, Olli Pettay olli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. We need to change this name, since per WebIDL 'attribute' can't be used here. I propose we use attr everywhere in the API. MutationRecord has already attrName. attributeOldValue - attrOldValue and attributeFilter - attrFilter Good catch (and I should've caught it when typing this up, as it's pseudo-idl), 'attr' works for me. If that shortening isn't appreciated, we could go with 'attributes' instead. - Adam boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true,
Re: Mutation Observers: a replacement for DOM Mutation Events
On Mon, Sep 26, 2011 at 1:47 AM, Olli Pettay olli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; Yeah, these methods could return mutationobserver. (Although I don't like the o.observe(foo).observe(bar) kind of coding style, since it doesn't make it clear which instance's method you're calling. But one doesn't need to use that.) where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; s/handleEvent/handleMutations/ I've yet to see a WebIDL callback that uses a method other than handleEvent (it's not just EventListeners). Any reason why MutationCallbacks should be different? Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue;
Re: Mutation Observers: a replacement for DOM Mutation Events
On 09/26/2011 09:09 PM, Adam Klein wrote: On Mon, Sep 26, 2011 at 11:05 AM, Olli Pettayolli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; RegistrationObservation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. We need to change this name, since per WebIDL 'attribute' can't be used here. I propose we use attr everywhere in the API. MutationRecord has already attrName. attributeOldValue - attrOldValue and attributeFilter - attrFilter Good catch (and I should've caught it when typing this up, as it's pseudo-idl), 'attr' works for me. If that shortening isn't appreciated, we could go with 'attributes' instead. Apparently I was wrong. In WebIDL one can escape names using _ prefix. But actually, attributes sounds more right than attribute. One really does want to observe all the attributes, unless names are filtered. so: attributes attributeName attributeNamespace attributeOldValue attributeFilter -Olli - Adam boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean
Re: Mutation Observers: a replacement for DOM Mutation Events
On Mon, Sep 26, 2011 at 12:08 PM, Olli Pettay olli.pet...@helsinki.fi wrote: On 09/26/2011 09:09 PM, Adam Klein wrote: On Mon, Sep 26, 2011 at 11:05 AM, Olli Pettayolli.pet...@helsinki.fi wrote: On 09/24/2011 12:16 AM, Adam Klein wrote: Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. We need to change this name, since per WebIDL 'attribute' can't be used here. I propose we use attr everywhere in the API. MutationRecord has already attrName. attributeOldValue - attrOldValue and attributeFilter - attrFilter Good catch (and I should've caught it when typing this up, as it's pseudo-idl), 'attr' works for me. If that shortening isn't appreciated, we could go with 'attributes' instead. Apparently I was wrong. In WebIDL one can escape names using _ prefix. But actually, attributes sounds more right than attribute. One really does want to observe all the attributes, unless names are filtered. so: attributes attributeName attributeNamespace attributeOldValue attributeFilter I like 'attributes' as the type, for readability. I'm not entirely convinced we need to lengthen the rest of the names, but I'm all for consistency, so on that basis I think it's OK. - Adam -Olli - Adam boolean characterData; // If true, mutations affecting the value of CharacterData //nodes
Mutation Observers: a replacement for DOM Mutation Events
Chromium (myself, Rafael Weinstein, Erik Arvidsson, Ryosuke Niwa) and Mozilla (Olli Pettay, Jonas Sicking) have worked together on a proposal for a replacement for Mutation Events. This proposal represents our best attempt to date at making a set of sensible trade offs which allows for a new mutation observation mechanism that: - Is free of the faults of the existing Mutation Events mechanism (enumerated in detail here: http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) - Meets the goal of having the main “questions” that use-cases will need answered about the net-effect of changes, be computable in linear time complexity roughly proportional to the number of changes that occurred. Significant aspects of this design: - Delivery of MutationRecords happens asynchronously, at the end of the current “microtask”. This is between Options 2 and 3 from this discussion http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0780.html. Instead of calling listeners at the end of outermost DOM operation or at the end of a Task, listeners are called at the end of outermost script invocation. If there are no script invocations, listeners are called at the end of Task. - Information about mutations is delivered to observers as an ordered sequence of MutationRecords, representing an observed sequence of changes that have occurred. - Subtree observation properly handles the case where nodes are transiently removed from, mutated outside of and then returned to the subtree. - Observers specify the types of changes they are interested in and (in some cases) level of detail they require. Sample usage: var observer = new MutationObserver(function(mutationRecords) { // Handle mutations }); observer.observe(myNode, { // options: subtree: true; // observe the subtree rooted at myNode childList: true; // include information childNode insertion/removals attribute: true; // include information about changes to attributes within the subtree }); … observer.disconnect(); // Cease observation Details: We introduce a new interface MutationObserver with a constructor on DOMWindow: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; where MutationCallback is [Callback, NoInterfaceObject] interface MutationCallback { void handleEvent(in MutationRecord[] mutations, in MutationObserver observer); }; Registration Observation - A call to observe creates a registration for the observer to be delivered mutations made to |target|, and optionally, its descendants. - Subsequent calls to the same MutationObserver made with the same |target| have the effect of resetting the options associated with the registration. - Subsequent calls to the same MutationObserver made with different |targets| have the effect of expanding the set of nodes which are being observed by the observer. All mutations made to all observed nodes in all registrations for a given observer are delivered, in time-ordered sequence, via a single invocation of the MutationCallback’s handleEvent method. - disconnect ceases observation over the observer’s set of observed nodes. Registration Options The |options| argument provided in observe is defined by the MutationObserverOptions interface: interface MutationObserverOptions { // Mutation types boolean childList; // If true, mutations affecting node’s childNodes are included. boolean attribute; // If true, mutations affecting element’s attributes are included. boolean characterData; // If true, mutations affecting the value of CharacterData //nodes are included. // [Note: If none of the known mutation types is specified, an Error is thrown] // Subtree observation boolean subtree; // If true, the observed set of nodes for this registration should include // descendants of MutationTarget (behavior described below). // Old values boolean attributeOldValue; // If true, MutationRecords describing changes to attributes should // contain the value of the attribute before the change. If true // without attribute: true specified, an Error is thrown. boolean characterDataOldValue; // If true, MutationRecords describing changes to // CharacterData nodes should contain the value // of the node before the change. If true without // characterData: true, an Error is thrown. // Filtering DOMString[] attributeFilter; // If provided, only changes to attributes with localName equaling // one of the provided strings will be delivered. If provided without // attribute: true, an Error is thrown. }; Subtree Observation If the subtree option is requested during registration, the observer is delivered mutations which occur to a set of observed nodes which is computed as follows: - At the time of
Re: Mutation Observers: a replacement for DOM Mutation Events
On Fri, Sep 23, 2011 at 2:16 PM, Adam Klein ad...@chromium.org wrote: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; It would be nice to have both of these return the MutationObserver rather than void, so you can chain calls. ~TJ
Re: Mutation Observers: a replacement for DOM Mutation Events
On Fri, Sep 23, 2011 at 4:46 PM, Adam Klein ad...@chromium.org wrote: On Fri, Sep 23, 2011 at 4:44 PM, Tab Atkins Jr. jackalm...@gmail.com wrote: On Fri, Sep 23, 2011 at 2:16 PM, Adam Klein ad...@chromium.org wrote: [Constructor(in MutationCallback callback)] interface MutationObserver { void observe(in Node target, in MutationObserverOptions options); void disconnect(); }; It would be nice to have both of these return the MutationObserver rather than void, so you can chain calls. I don't think that makes sense for disconnect() (at least the version specced here), since it stops observation of all nodes so chaining wouldn't make sense. But I definitely see that chaining observe could be convenient. // Resetting the observation list observer .disconnect() .observe(node1,{...}) .observe(node2,{...}); ~TJ