Re: [widgets] What is the status and plan for Widget URI spec?
On Fri, Jul 1, 2011 at 5:09 PM, Robin Berjon robin.ber...@gmail.com wrote: On Jul 1, 2011, at 11:22 , Marcos Caceres wrote: Want to add dereferencing model. Can be a new spec layered on top. This would still be in scope of the charter, so it would not be an issue to create a new spec. I reckon this doesn't need to be in a separate spec, it makes more sense to define all of it together. Dereferencing makes no sense outside of the URI scheme, and the URI scheme is less useful without it. Agreed. I'll see if I can get some funding to do work on this. -- Marcos Caceres http://datadriven.com.au
Re: Mutation events replacement
On 03/07/11 04:52, Boris Zbarsky wrote: On 7/2/11 2:27 PM, Dave Raggett wrote: n.b. the current mutation events work nicely for the document editing use cases. Only if you have full control over the set of all registered listeners. If you do not, you're SOL, because current mutation events can be delivered out of order if mutations happen inside mutation event listeners, for example. -Boris Absolutely, for the editing case, such misbehavior would indeed cause problems. However, that does raise a related question. In the proposed approach of asynchronous notification of already applied mutations, how can the observer prevent notifications for any changes to the DOM made by that observer? Is it sufficient to for the observer to unregister itself, make the changes to the DOM and re-register itself before returning? A use case might be cleaning up the DOM after content editable actions, where a developer wants to ensure the DOM is consistent across browsers. -- Dave Raggettd...@w3.org http://www.w3.org/People/Raggett
Test suites and RFC2119
RFC2119 'Key words for use in RFCs to Indicate Requirement Levels' defines the keyword 'SHOULD' as: This word, or the adjective RECOMMENDED, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. Generally, I think we can agree that anything less than MUST or MUST NOT requirements in a spec are pretty useless when it comes to conformance testing. We try to write specs to these keywords but other keywords tend to creep in to most specifications. We currently define tests in test suites for SHOULD requirements. A problem occurs when those tests are used to gauge the overall compliance of an implementation to the full test suite. An implementation could theoretically be 100% compliant without needing to pass non-MUST and non-MUST NOT tests. Perhaps we should introduce 'bonus' points for SHOULD/SHOULD NOT/MAY and RECOMMENDED tests and not have them contribute to overall compliance output, thereby allowing implementations to claim 100% compliance to MUST/MUST NOT tests. An implementation can then optionally collect any available, optional bonus points as available from requirements marked up with other keywords. Wondering if there is any set W3C thinking on this or a way of including SHOULD tests in test suites but clearly indicating that they are, basically, optional and do not count towards the overall compliance score? I couldn't find anything in [1]. - Rich [1] http://www.w3.org/TR/test-methodology/
Re: Test suites and RFC2119
On Mon, Jul 4, 2011 at 10:47 AM, Rich Tibbett ri...@opera.com wrote: RFC2119 'Key words for use in RFCs to Indicate Requirement Levels' defines the keyword 'SHOULD' as: This word, or the adjective RECOMMENDED, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. Generally, I think we can agree that anything less than MUST or MUST NOT requirements in a spec are pretty useless when it comes to conformance testing. We try to write specs to these keywords but other keywords tend to creep in to most specifications. We currently define tests in test suites for SHOULD requirements. A problem occurs when those tests are used to gauge the overall compliance of an implementation to the full test suite. An implementation could theoretically be 100% compliant without needing to pass non-MUST and non-MUST NOT tests. You can usually make those disappear. Or you can use the word OPTIONAL and make the conformance requirement open ended (thus making it untestable)... so, instead of X SHOULD support Y, you can have It is OPTIONAL for X to support other technologies (e.g., Y). The weasels your way out of a testing some things :) Perhaps we should introduce 'bonus' points for SHOULD/SHOULD NOT/MAY and RECOMMENDED tests and not have them contribute to overall compliance output, thereby allowing implementations to claim 100% compliance to MUST/MUST NOT tests. An implementation can then optionally collect any available, optional bonus points as available from requirements marked up with other keywords. Wondering if there is any set W3C thinking on this or a way of including SHOULD tests in test suites but clearly indicating that they are, basically, optional and do not count towards the overall compliance score? I couldn't find anything in [1]. I was intending to modify the test suite and implementation reports template to do that. Some tests in Dig Sig and PC are already marked as type=optional. At the end of the day, it is people that evaluate conformance and ratify specs... so it's not really a technical issue. [1] http://www.w3.org/TR/test-methodology/ [1] needs so love. Will update it soon. -- Marcos Caceres http://datadriven.com.au
Re: Test suites and RFC2119
On Jul 4, 2011, at 11:47 , Rich Tibbett wrote: Wondering if there is any set W3C thinking on this or a way of including SHOULD tests in test suites but clearly indicating that they are, basically, optional and do not count towards the overall compliance score? I couldn't find anything in [1]. I think that the best way of addressing SHOULDs (apart from avoiding them in the first place) is to test them as if they were MUSTs, but put the results for those in a separate table. In that separate table, for each failure ask the implementer why they fail and document that. This gives a) the possibility of 100% conformance to the MUSTS, which is needed to advance the spec; 2) useful feedback about the spec, notably concerning unrealistic SHOULD or potentially something that could be either removed or upgraded to a MUST; and 3) a potential incentive of sorts for some implementers who are driven more by the ability to use a test report in marketing material than they are to make actual users happy to up their game a little bit. -- Robin Berjon - http://berjon.com/ - @robinberjon
Re: Test suites and RFC2119
Rich, Le 4 juil. 2011 à 05:47, Rich Tibbett a écrit : conformance testing. and later on implementations to claim 100% compliance These are entirely two different things. The MUST/SHOULD or any systems of Conformance help articulate the way the technology is organized. The claim of being implemented correctly is entirely another topic. You could create an implementation conformance statement (ICS) which would require an HTML5 document to be conformant only and only if it had !doctype html at the start. Not very useful, but still possible. The documents you are looking for are: * QA Framework: Specification Guidelines http://www.w3.org/TR/qaframe-spec/ * Variability in Specifications http://www.w3.org/TR/spec-variability/ Specifically, 2.1.2 Specify how to make conformance claims. [1] For the testing part, there is no way to assess the technology is fully implemented with a percentage, a number of passed tests. This just doesn't work. It doesn't mean tests are useless. It is just that claiming interoperability and/or conformance is silly. You can claim certification when there is a defined profile. And the certification will just prove that you successfully passed the profile, not that you are fully conformant or fully interoperable. [1]: http://www.w3.org/TR/qaframe-spec/#specify-conformance -- Karl Dubost - http://dev.opera.com/ Developer Relations Tools, Opera Software
Re: Mutation events replacement
On 7/3/2011 10:26 AM, Ryosuke Niwa wrote: On Sun, Jul 3, 2011 at 8:41 AM, John J. Barton johnjbar...@johnjbarton.com mailto:johnjbar...@johnjbarton.com wrote: On 7/2/2011 8:50 PM, Boris Zbarsky wrote: On 7/2/11 1:46 PM, John J. Barton wrote: 2) element transformation. The replacement fires after a mutation. Library or tools that want to transform the application dynamically want to get notification before the mutation. A common solution then is to bracket changes: beforeChange or onModelChanging afterChange or onModelChanged This really only works if you trust the listeners. The browser core can't trust scripted listeners using Web APIs. I don't understand what 'trust' means here. I am not proposing any change to the privileges of listeners. How can the browser core trust an 'onModelChanged' listener but not an 'onModelChanging' listener? If the user agent fires a modelChanging event, then the user agent must verify that the pre-condition of removal is still met after the the event is fired. This is extremely hard to do and very error-prone. In the current proposal, the DOM API is manipulated while the onModelChange mutation listeners run. This manipulation ensures certain properties of the overall mutation process. However the manipulation makes the API unreliable and the overall solution forces some use cases to adopt bizarre solutions. I am not asking you to support onModelChanging with full DOM API access. I am asking you to take an open minded look at onModelChanging with manipulation of the API to maintain the pre-conditions you require. Instead of surreptitiously changing the DOM API (to cause results to appear out of order), I am suggesting that the API be explicit. Rather than silently delaying the results of DOM mutations made in mutation event handlers, make the delay explicit. Force developers to delay mutations. Force developers to operate against your system the way you say they must, rather than pretending that they can mutate in mutation listeners. Let's set the onModelChange/onModelChanging differences aside and focus just on the effective DOM API in mutation listeners. Your proposal is to change the DOM API experienced in listeners from the DOM API experiences outside of listeners. The purpose is to control the order of DOM mutation. You can achieve the same goal in other ways. For example, consider WebWorkers. There we face a similar problem: the browser requires certain restrictions on the worker. Direct DOM mutation must not be allowed. Developers have to work within these restrictions. Developing with WebWorkers is different from developing in web pages. But the differences are clear and predictable. In the present case, imagine that the mutation listeners have only one function call available: onNextTurn(). Their only option is to stage work based on the arguments to the listener. Within this model verifying preconditions is even easier than the current proposal *and* developers will have a reliable API. This approach makes the properties of the platform explicit: no mutations within mutations. jjb
Re: Mutation events replacement
On 7/3/2011 1:23 PM, Boris Zbarsky wrote: On 7/3/11 2:43 PM, John J. Barton wrote: I'm not sure what you're asking... The whole point of the proposed model is that if someone tries to do a mutation the mutation _will_ happen and will complete. _Then_ listeners, if any, will be notified. What are you worried about working or failing? According to Olli, some functions in mutation listeners will fail. The list of functions is not specified directly, but is implicit in the algorithm: some function's actions become asynchronous. This means one cannot write reliable code in mutation listeners and, worse, efforts to debug your failing code will fail. Code examples that work outside of mutation listeners will silently fail inside of mutation listeners. I have experience with these kinds of mysteriously-failing APIs in browser extension systems and that is why I am advocating against their inclusion in Web facing systems. If these already exist in the various browser implementations of Mutation events listeners, that does not mean its replacement should perpetuate the problem. Ok, that's good, whatever it takes. A DOM API that switches between read-only and read-write would much better for developers than a DOM API that partly switches to async. Well, it sounds better to you. I'm not sure it sounds better to developers. If you think it's ok for assigning to a global variable to throw in a mutation listener, and that this is better than some delay in the listener firing (not actually async; Jonas' proposal doesn't really fire things async, if you note), then I suspect developers might disagree with you. The issue is not the delay in the listener firing. The issue is the effectively broken API within the listeners. Some functions called in listeners do not work the same way they do outside of listeners. Developers want a complete DOM API in mutation listeners. They can't have it. So the only question is how to express the restrictions. Silently changing the behavior of the API is not a good choice in my opinion. Consider the alternative. In this use case, the developer wants to modify an execCommand. In the current replacement solution they have to wait for the execCommand to take effect, then undo the execCommand and redo it modified. Creating a good user experience may not be possible. Quite honestly, that's the developer's problem. No, it can't be the developer's problem because the current API does not allow the developer to fix the problem. I want to make it the developer's problem. I want to the developer to be able to reject operations before they commit because the alternative is to undo/redo. Now the developer of course wants to push as much of the cost of this problem onto the UA as possible, and this makes sense: there are a lot fewer UAs than developers. This has nothing to do with my perspective. ... You're missing at least the following options: 4. Restrict any APIs that have this sort of power so they're not usable by untrusted web pages (e.g. move them into browser extension systems). If you can implement onModelChanging for extensions without crashing, then you can implement it for Web pages. 5. Accept that certain levels of the platform just can't be hooked, at least for the time being. There is also: 6. Leave the current Mutation event system as is. Again, I think trying to shoehorn all mutation consumers into the same API is a bad idea that gave us the current mutation events. Some consumers just want to know things have changed and not much more than that. Some want to know details of the changes. Some want to rewrite parts of the browser on the fly. It's not clear to me that the same API for all three sets of consumers is the right solution. By restricting mutation listeners to explicitly avoid DOM mutation, the most sophisticated case is no different than the simple case. Then all three can be accommodated. jjb
Re: Mutation events replacement
Apologies in advance if my comment makes no sense. This is a long thread, I tried to digest it all. :) On Sat, Jul 2, 2011 at 7:07 AM, Boris Zbarsky bzbar...@mit.edu wrote: That may be ok, if the use cases that incur this cost are rare and the common case can be better served by a different approach. Or put another way, if 1% of consumers want the full list because it makes them 4x faster and the other 99% don't want the full list, and the full list is 3x slower for the browser to build than just providing the information the 99% want, what's the right tradeoff? I'm not sure there really is a performance tradeoff. I believe that the proposal Rafael put forward should almost always be faster. Storing the list of changes and doing a JS callback once, for nearly all use-cases, should be faster than frequent, semi-synchronous callbacks. The only bit that might be slower is what data you include in the mutation list. I believe that all the data you'd need is cheap except for possibly the following two: -The index of the child that changed for ChildListChanged (is this actually expensive?) -The old value of an attribute/text node. I know this is expensive in Gecko's engine at least. I'd be fine with excluding that information by default, but having a flag you pass at some point saying to include those. That way, only sites that need it take the performance hit. The numbers above are made up, of course; it would be useful to have some hard data on the actual use cases. Maybe we need both sorts of APIs: one which generates a fine-grained change list and incurs a noticeable DOM mutation performance hit and one which batches changes more but doesn't slow the browser down as much... -Boris
Re: Mutation events replacement
On 07/04/2011 07:23 PM, John J. Barton wrote: On 7/3/2011 1:23 PM, Boris Zbarsky wrote: On 7/3/11 2:43 PM, John J. Barton wrote: I'm not sure what you're asking... The whole point of the proposed model is that if someone tries to do a mutation the mutation _will_ happen and will complete. _Then_ listeners, if any, will be notified. What are you worried about working or failing? According to Olli, some functions in mutation listeners will fail. What? I don't understand this at all. The list of functions is not specified directly, but is implicit in the algorithm: some function's actions become asynchronous. No. Change notifications are queued, and the listeners handling the queue will called at the time when the outermost DOM mutation is about to return. -Olli This means one cannot write reliable code in mutation listeners and, worse, efforts to debug your failing code will fail. Code examples that work outside of mutation listeners will silently fail inside of mutation listeners. I have experience with these kinds of mysteriously-failing APIs in browser extension systems and that is why I am advocating against their inclusion in Web facing systems. If these already exist in the various browser implementations of Mutation events listeners, that does not mean its replacement should perpetuate the problem. Ok, that's good, whatever it takes. A DOM API that switches between read-only and read-write would much better for developers than a DOM API that partly switches to async. Well, it sounds better to you. I'm not sure it sounds better to developers. If you think it's ok for assigning to a global variable to throw in a mutation listener, and that this is better than some delay in the listener firing (not actually async; Jonas' proposal doesn't really fire things async, if you note), then I suspect developers might disagree with you. The issue is not the delay in the listener firing. The issue is the effectively broken API within the listeners. Some functions called in listeners do not work the same way they do outside of listeners. ? Developers want a complete DOM API in mutation listeners. Developers have complete DOM API in mutation listeners. There are no restrictions. They can't have it. So the only question is how to express the restrictions. Silently changing the behavior of the API is not a good choice in my opinion. Consider the alternative. In this use case, the developer wants to modify an execCommand. In the current replacement solution they have to wait for the execCommand to take effect, then undo the execCommand and redo it modified. Creating a good user experience may not be possible. Quite honestly, that's the developer's problem. No, it can't be the developer's problem because the current API does not allow the developer to fix the problem. I want to make it the developer's problem. I want to the developer to be able to reject operations before they commit because the alternative is to undo/redo. Now the developer of course wants to push as much of the cost of this problem onto the UA as possible, and this makes sense: there are a lot fewer UAs than developers. This has nothing to do with my perspective. ... You're missing at least the following options: 4. Restrict any APIs that have this sort of power so they're not usable by untrusted web pages (e.g. move them into browser extension systems). If you can implement onModelChanging for extensions without crashing, then you can implement it for Web pages. 5. Accept that certain levels of the platform just can't be hooked, at least for the time being. There is also: 6. Leave the current Mutation event system as is. Again, I think trying to shoehorn all mutation consumers into the same API is a bad idea that gave us the current mutation events. Some consumers just want to know things have changed and not much more than that. Some want to know details of the changes. Some want to rewrite parts of the browser on the fly. It's not clear to me that the same API for all three sets of consumers is the right solution. By restricting mutation listeners to explicitly avoid DOM mutation, the most sophisticated case is no different than the simple case. Then all three can be accommodated. jjb
Re: Mutation events replacement
On 07/04/2011 07:28 PM, Ojan Vafai wrote: Apologies in advance if my comment makes no sense. This is a long thread, I tried to digest it all. :) On Sat, Jul 2, 2011 at 7:07 AM, Boris Zbarsky bzbar...@mit.edu mailto:bzbar...@mit.edu wrote: That may be ok, if the use cases that incur this cost are rare and the common case can be better served by a different approach. Or put another way, if 1% of consumers want the full list because it makes them 4x faster and the other 99% don't want the full list, and the full list is 3x slower for the browser to build than just providing the information the 99% want, what's the right tradeoff? I'm not sure there really is a performance tradeoff. I believe that the proposal Rafael put forward should almost always be faster. Storing the list of changes and doing a JS callback once, for nearly all use-cases, should be faster than frequent, semi-synchronous callbacks. The only bit that might be slower is what data you include in the mutation list. I believe that all the data you'd need is cheap except for possibly the following two: -The index of the child that changed for ChildListChanged (is this actually expensive?) You may need more than just an index. element.innerHTML = null removes all the child nodes. And element.inserBefore(some_document_fragment, element.lastChild) may insert several child nodes. Depending on whether we want to get notified for each mutation or batch the mutations, simple index may or may not be enough. -The old value of an attribute/text node. I know this is expensive in Gecko's engine at least. Shouldn't be that slow. Mutation listener could easily implement old/new value handling itself, especially if it knows which attributes it is interested in. I'd be fine with excluding that information by default, but having a flag you pass at some point saying to include those. That way, only sites that need it take the performance hit. The numbers above are made up, of course; it would be useful to have some hard data on the actual use cases. Maybe we need both sorts of APIs: one which generates a fine-grained change list and incurs a noticeable DOM mutation performance hit and one which batches changes more but doesn't slow the browser down as much... -Boris
Re: Test suites and RFC2119
On Mon, 04 Jul 2011 11:47:22 +0200, Rich Tibbett ri...@opera.com wrote: RFC2119 'Key words for use in RFCs to Indicate Requirement Levels' defines the keyword 'SHOULD' as: This word, or the adjective RECOMMENDED, mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. Generally, I think we can agree that anything less than MUST or MUST NOT requirements in a spec are pretty useless when it comes to conformance testing. We try to write specs to these keywords but other keywords tend to creep in to most specifications. Hmm. No, I think a spec that uses these correctly has requirements where there are legitimate reasons not to do the usual thing, but a strong case for doing it unless there is a clear reason. We currently define tests in test suites for SHOULD requirements. A problem occurs when those tests are used to gauge the overall compliance of an implementation to the full test suite. An implementation could theoretically be 100% compliant without needing to pass non-MUST and non-MUST NOT tests. I don't think so. RFC 2119 is pretty clear about what must and should mean. As Bjoern said a numerical score for tests is generally not that useful. But compliance is doing all the things you must, and in practical terms that can readily be translated to *at least* passing all the test that test things the spec says must happen. Perhaps we should introduce 'bonus' points for SHOULD/SHOULD NOT/MAY and RECOMMENDED tests and not have them contribute to overall compliance output, thereby allowing implementations to claim 100% compliance to MUST/MUST NOT tests. An implementation can then optionally collect any available, optional bonus points as available from requirements marked up with other keywords. Wondering if there is any set W3C thinking on this or a way of including SHOULD tests in test suites but clearly indicating that they are, basically, optional and do not count towards the overall compliance score? I couldn't find anything in [1]. I don't think it's a good idea to do numerical scoring of conformance. Yu would need to be sure that the things being tested are of equal importance, or work out how to balance the scores. And the cost of that already outweighs the benefit by so much it seems pointless to go there. just my 2 cents chaals - Rich [1] http://www.w3.org/TR/test-methodology/ -- Charles McCathieNevile Opera Software, Standards Group je parle français -- hablo español -- jeg lærer norsk http://my.opera.com/chaals Try Opera: http://www.opera.com
Re: Mutation events replacement
On 7/4/2011 9:38 AM, Olli Pettay wrote: On 07/04/2011 07:23 PM, John J. Barton wrote: On 7/3/2011 1:23 PM, Boris Zbarsky wrote: On 7/3/11 2:43 PM, John J. Barton wrote: I'm not sure what you're asking... The whole point of the proposed model is that if someone tries to do a mutation the mutation _will_ happen and will complete. _Then_ listeners, if any, will be notified. What are you worried about working or failing? According to Olli, some functions in mutation listeners will fail. What? I don't understand this at all. Sorry, it was actually in Jonas' post you quoted: The only undesirable feature is that code that mutates the DOM from inside a callback, say by calling setAttribute, can't rely on that by the time that setAttribute returns, all callbacks have been notified. This is unfortunately required if we want the second desirable property listed above. If I understand correctly, this description understates the problem. Isn't it the case that all DOM mutations will act differently in mutation listeners? Code tested outside of mutation listeners can fail inside of mutation listeners, correct? This is indeed an undesirable feature and I don't believe it is necessary. We can achieve the second desirable property, which is really about avoiding mutation in mutation listeners, in other ways. Instead of special case asynchrony, make it explicit asynchrony. Developers will hate it, just like they hate XHR asynchrony, but it's better than unreliable programs. The list of functions is not specified directly, but is implicit in the algorithm: some function's actions become asynchronous. No. Change notifications are queued, and the listeners handling the queue will called at the time when the outermost DOM mutation is about to return. How can I reconcile your answer with the idea that setAttribute() does not work synchronously in my mutation listener? Can my mutation listener mutate the DOM and expect those mutations to act the way they do outside of the listeners? My understanding is no: the API works differently inside of mutation listeners. jjb
Re: Mutation events replacement
On Mon, Jul 4, 2011 at 10:16 AM, Adam Klein ad...@chromium.org wrote: On Mon, Jul 4, 2011 at 9:57 AM, Olli Pettay olli.pet...@helsinki.fi wrote: On 07/04/2011 07:28 PM, Ojan Vafai wrote: Apologies in advance if my comment makes no sense. This is a long thread, I tried to digest it all. :) On Sat, Jul 2, 2011 at 7:07 AM, Boris Zbarsky bzbar...@mit.edu mailto:bzbar...@mit.edu wrote: That may be ok, if the use cases that incur this cost are rare and the common case can be better served by a different approach. Or put another way, if 1% of consumers want the full list because it makes them 4x faster and the other 99% don't want the full list, and the full list is 3x slower for the browser to build than just providing the information the 99% want, what's the right tradeoff? I'm not sure there really is a performance tradeoff. I believe that the proposal Rafael put forward should almost always be faster. Storing the list of changes and doing a JS callback once, for nearly all use-cases, should be faster than frequent, semi-synchronous callbacks. The only bit that might be slower is what data you include in the mutation list. I believe that all the data you'd need is cheap except for possibly the following two: -The index of the child that changed for ChildListChanged (is this actually expensive?) You may need more than just an index. element.innerHTML = null removes all the child nodes. And element.inserBefore(some_document_fragment, element.lastChild) may insert several child nodes. Depending on whether we want to get notified for each mutation or batch the mutations, simple index may or may not be enough. Would a node reference be better (nextSibling)? Assuming the listeners have access to all inserted/removed nodes along the way, using another as an anchor seems like it would work properly (though the innerHTML case may need something special). That sounds great to me. nextSibling seems sufficient. -The old value of an attribute/text node. I know this is expensive in Gecko's engine at least. Shouldn't be that slow. Mutation listener could easily implement old/new value handling itself, especially if it knows which attributes it is interested in. This only works if listeners don't care about intermediate values, since all they'll have access to is the last value they saw and the current value in the DOM. If it was set several times during a single mutation event (whether that be your or Rafael's definition of a transaction), they'll miss those in-between values. Also, while this would be acceptable for some use cases, the editing/undo use case would need to keep values of all attributes at all nodes, which seems likely to be worse than having the UA take care of this. I'd be fine with excluding that information by default, but having a flag you pass at some point saying to include those. That way, only sites that need it take the performance hit. Given that different use cases seem to have wildly different requirements (some probably only care about one or two attributes while others care about the entire document), this approach to handling the availability of oldValue/newValue is appealing. - Adam
Re: Mutation events replacement
On 07/04/2011 09:01 PM, Dave Raggett wrote: On 04/07/11 17:57, Olli Pettay wrote: Mutation listener could easily implement old/new value handling itself, especially if it knows which attributes it is interested in. How exactly would the listener know the previous state? In the easiest case when the script cares about only one specific attribute: element.addAttributeChangeListener( { prevVal: element.getAttribute(foo), handleMutation: function(node, changeTarget) { if (node == changeTarget) { // do something with this.prevVal ... this.prevVal = element.getAttribute(foo); } } }); For a concurrent editing app, it is important to be able to describe changes reversibly so that you can revert the DOM when a given local edit isn't accepted, or you need to revert before applying accepted changes from other clients. I have been able to get this to work fine with the existing mutation events. Of course, I avoid changing the DOM within a mutation event listener, but it is easy to defer such changes by a call to setTimeout, e.g. with a time of zero. I would be quite happy for the browser to throw an exception when a mutation event listener tries to call an unsafe API, as this way developers would rapidly learn of their mistake and switch to better practices.
Re: Mutation events replacement
On 07/05/2011 12:02 AM, Adam Klein wrote: On Mon, Jul 4, 2011 at 1:45 PM, Olli Pettayolli.pet...@helsinki.fi wrote: On 07/04/2011 08:16 PM, Adam Klein wrote: On Mon, Jul 4, 2011 at 9:57 AM, Olli Pettayolli.pet...@helsinki.fi wrote: On 07/04/2011 07:28 PM, Ojan Vafai wrote: The only bit that might be slower is what data you include in the mutation list. I believe that all the data you'd need is cheap except for possibly the following two: -The index of the child that changed for ChildListChanged (is this actually expensive?) You may need more than just an index. element.innerHTML = null removes all the child nodes. And element.inserBefore(some_document_fragment, element.lastChild) may insert several child nodes. Depending on whether we want to get notified for each mutation or batch the mutations, simple index may or may not be enough. Would a node reference be better (nextSibling)? Assuming the listeners have access to all inserted/removed nodes along the way, using another as an anchor seems like it would work properly (though the innerHTML case may need something special). Where would the node reference be? What would the API look like? In Rafael's API, each mutation is represented by an object, so I'd simply put it there with its own key, something like: interface MutationRecord { // e.g., 'ChildListChanged', 'AttributeChanged' readonly attribute DOMString type; // element whose childNodes changed, or whose attribute was changed readonly attribute Node target; readonly attribute NodeListinsertedNodes; readonly attribute NodeListremovedNodes; // reference to the node before which the above nodes were removed/inserted readonly attribute Node nextSibling; }; And nextSibling would be null in case of appendChild, I guess. (Not related to nextSibling) Handling of insertedNodes/removedNodes becomes tricky if there are several listeners and the first one of those adds or removes child nodes. Should the listeners which will be called later get the same insertedNodes/removedNodes as the first listener, or should the lists be updated to reflect what has actually changed? If the notification just tells that something has changed, it would be up to the JS side to implement the kind of list handling it wants. -Olli With your API, I think you'd want to change from passing nodes to the callback to using something like the above, analogous to the information hanging off of MutationEvent in the current spec. - Adam
Re: Mutation events replacement
On Mon, Jul 4, 2011 at 11:01 AM, Dave Raggett d...@w3.org wrote: How exactly would the listener know the previous state? For a concurrent editing app, it is important to be able to describe changes reversibly so that you can revert the DOM when a given local edit isn't accepted, or you need to revert before applying accepted changes from other clients. I have been able to get this to work fine with the existing mutation events. Of course, I avoid changing the DOM within a mutation event listener, but it is easy to defer such changes by a call to setTimeout, e.g. with a time of zero. I would be quite happy for the browser to throw an exception when a mutation event listener tries to call an unsafe API, as this way developers would rapidly learn of their mistake and switch to better practices. If we wanted, we can have a flag that adds new properties that contain old values, nodes, etc... And if we have a list of all mutations that happened in the order, then you should be able to unapply/reapply the DOM mutations as needed. On Mon, Jul 4, 2011 at 11:14 AM, John J. Barton johnjbar...@johnjbarton.com wrote: Sorry, it was actually in Jonas' post you quoted: The only undesirable feature is that code that mutates the DOM from inside a callback, say by calling setAttribute, can't rely on that by the time that setAttribute returns, all callbacks have been notified. This is unfortunately required if we want the second desirable property listed above. If I understand correctly, this description understates the problem. Isn't it the case that all DOM mutations will act differently in mutation listeners? Code tested outside of mutation listeners can fail inside of mutation listeners, correct? Only if the code expects mutation events be fired synchronously (e.g. the code relies on some mutation event listeners modify DOM synchronously as it mutates DOM). However, all DOM mutations made in mutation listeners will take effect immediately in Jonas' proposal. This is indeed an undesirable feature and I don't believe it is necessary. We can achieve the second desirable property, which is really about avoiding mutation in mutation listeners, in other ways. Instead of special case asynchrony, make it explicit asynchrony. Developers will hate it, just like they hate XHR asynchrony, but it's better than unreliable programs. I agree that mutation observers are called sometimes synchronously and sometimes asynchronously is confusing. The list of functions is not specified directly, but is implicit in the algorithm: some function's actions become asynchronous. No. Change notifications are queued, and the listeners handling the queue will called at the time when the outermost DOM mutation is about to return. How can I reconcile your answer with the idea that setAttribute() does not work synchronously in my mutation listener? Can my mutation listener mutate the DOM and expect those mutations to act the way they do outside of the listeners? My understanding is no: the API works differently inside of mutation listeners. It works synchronously. It just fires mutation events as the result of setAttribute will fire asynchronously. - Ryosuke
Re: Mutation events replacement
On 7/4/11 12:09 PM, John J. Barton wrote: In the current proposal, the DOM API is manipulated while the onModelChange mutation listeners run. Citation please? I see nothing like that in the proposal. In the present case, imagine that the mutation listeners have only one function call available: onNextTurn(). How do you ensure that given that the arguments include DOM nodes which then transitively allow you to reach all of the DOM's functionality? -Boris
Re: Mutation events replacement
On 7/4/11 12:23 PM, John J. Barton wrote: On 7/3/2011 1:23 PM, Boris Zbarsky wrote: On 7/3/11 2:43 PM, John J. Barton wrote: I'm not sure what you're asking... The whole point of the proposed model is that if someone tries to do a mutation the mutation _will_ happen and will complete. _Then_ listeners, if any, will be notified. What are you worried about working or failing? According to Olli, some functions in mutation listeners will fail. Pointer to where Olli said that, please? I don't recall seeing anyone propose that Silently changing the behavior of the API is not a good choice in my opinion. We agree on that. Now the developer of course wants to push as much of the cost of this problem onto the UA as possible, and this makes sense: there are a lot fewer UAs than developers. This has nothing to do with my perspective. I didn't say anything about your perspective; just that this is the perspective of developers, on average, and that this perspective makes sense in general. 4. Restrict any APIs that have this sort of power so they're not usable by untrusted web pages (e.g. move them into browser extension systems). If you can implement onModelChanging for extensions without crashing, then you can implement it for Web pages. We can't implement it for extensions without crashing if the extension misbehaves, imo. The difference is that we can't trust web pages to behave, ever. On the other hand, a misbehaving extension can already cause so much grief that we have to trust it at _some_ level. There is also: 6. Leave the current Mutation event system as is. The current Mutation system is broken by design for consumers and an endless source of pain for implementors. I don't think anyone really wants to keep it as is. By restricting mutation listeners to explicitly avoid DOM mutation, the most sophisticated case is no different than the simple case. Then all three can be accommodated. If such a restriction were feasible, it might be worth looking into. It would involve not passing any DOM nodes to the mutation listener, I suspect. -Boris
Re: Mutation events replacement
On 7/4/11 12:28 PM, Ojan Vafai wrote: I'm not sure there really is a performance tradeoff. I believe that the proposal Rafael put forward should almost always be faster. Storing the list of changes and doing a JS callback once, for nearly all use-cases, should be faster than frequent, semi-synchronous callbacks. That depends on whether your list of changes gets big enough that your start swapping, for example. The only bit that might be slower is what data you include in the mutation list. That's one of the things that could get slower, yes. It's not the only one. -The index of the child that changed for ChildListChanged (is this actually expensive?) It could be. In Gecko's case it's cheap right now because kids are stored in arrays, but WebKit uses doubly linked lists with a cache of some sort for indices last I checked. So for some access patterns this could be pretty expensive in WebKit. -The old value of an attribute/text node. I know this is expensive in Gecko's engine at least. This can be expensive in all engines, if they do it right. Consider having to serialize out values of the 'style' attribute (possibly twice) on every .style.foo set. Or having to serialize out path attributes as the SVG DOM is mutating paths. This is not a Gecko-specific issue. I'd be fine with excluding that information by default, but having a flag you pass at some point saying to include those. That way, only sites that need it take the performance hit. This would be a lot more palatable to me, yes. This brings us back to having ways to ask for different levels of detail in mutation notifications. -Boris
Re: Mutation events replacement
On 7/4/2011 6:34 PM, Boris Zbarsky wrote: On 7/4/11 12:09 PM, John J. Barton wrote: In the current proposal, the DOM API is manipulated while the onModelChange mutation listeners run. Citation please? I see nothing like that in the proposal. http://www.mail-archive.com/public-webapps@w3.org/msg14008.html The only undesirable feature is that code that mutates the DOM from inside a callback, say by calling setAttribute, can't rely on that by the time that setAttribute returns, In the present case, imagine that the mutation listeners have only one function call available: onNextTurn(). How do you ensure that given that the arguments include DOM nodes which then transitively allow you to reach all of the DOM's functionality? By making all such calls fail. jjb -Boris
Re: Mutation events replacement
On 7/4/2011 6:39 PM, Boris Zbarsky wrote: On 7/4/11 12:23 PM, John J. Barton wrote: By restricting mutation listeners to explicitly avoid DOM mutation, the most sophisticated case is no different than the simple case. Then all three can be accommodated. If such a restriction were feasible, it might be worth looking into. It would involve not passing any DOM nodes to the mutation listener, I suspect. All I am asking is a few minutes of reasonable consideration for alternatives before many thousands of person hours become invested in the proposed mutation events replacement. jjb