Re: Mutation events replacement

On 08/04/2011 10:14 PM, David Flanagan wrote:
> On 8/4/11 6:38 AM, Olli Pettay wrote:
>> Hi all,
>>
>> here is a bit different proposal for mutation events replacement.
>> This is using the mostly-sync approach, and batching can make it easier
>> to use with several simultaneous script libraries; each one would use
>> their own batch.
>> For performance reasons it might be useful to have an attribute name
>> filter for AttrChange, but such thing could be added later.
>> One advantage this approach has is that it doesn't pollute Node API.
>>
>>
>> -Olli
>>
>
> I'm intrigued by the idea, but confused by the API (or at least by
> naming issues in the API).
>
> - ModificationBatch is both a batch of modifications and also a set of
> methods for requesting modification batches. Should there be separate
> ModificationBatch and ModificationBatcher interfaces?
Why? You have an object which can listen for some modifications and then
at some point call the callback that some modifications have happened.
But perhaps the interface could be called something else. I'd like it to 
have "batch" or some similar meaning in it.


>
> - The pattern of passing a callback function to a constructor is novel
> in the DOM. Will this confuse people too much?

Well, I don't think new Foo(callback); is more difficult to understand
than say
var foo = new Foo();
foo.onSomething = callback;

> Also, if the callback is
> passed to the constructor, there isn't a deregistration method. I assume
> that you achieve this by calling unbatchAll(),
Yes that, or calling unbatchFoo if you called batchFoo before.

> but that seems
> non-parallel.
Registering the callback doesn't need to have anything parallel.
It is the batch*/unbatch* which are parallel.
And batch/unbatchAll are kind of catch-all.

> What if the ModificationCallback was passed to the
> individual batch/unbatch methods instead?
Well, the whole idea is that the same callback would handle a batch of 
modifications.



>
> - The name batchTextChanges() implies to me that it is expressing a
> preference to receive text changes in batched form, and that if you
> don't call this method you'll still get text changes, just one at a
> time. I don't think that is the intent, but that is what the name
> implies to me. How about something (verbose) like
> addTextChangeBatchListener() (and pass the ModificationCallback to this
> method instead of to the constructor)
As I said, the idea is not to have separate ModificationCallbacks for 
different types, but to have a callback per ModificationBatch.
If you need different callbacks, you can create a new ModificationBatch.

But yes, the naming can be changed, if it is misleading.
Suggestions welcome :)



-Olli



>
> David
>>
>>
>> interface Modification {
>> /**
>> * type is either TextChange, ChildListChange or AttrChange.
>> * (More types can be added later if needed.)
>> */
>> readonly attribute DOMString type;
>>
>> /**
>> * Target of the change.
>> * If an attribute is changed, target is the element,
>> * if an element is added or removed, target is the node
>> * which was added or removed.
>> * If text is changed, target is the CharacterData node which was
>> * changed.
>> */
>> readonly attribute Node target;
>> /**
>> * parent node of the target right before the change happened,
>> * or null.
>> */
>> readonly attribute Node targetParent;
>> /**
>> * The node which is "batching" the change.
>> */
>> readonly attribute Node currentTarget;
>>
>> /**
>> * The name of the attribute which was changed, or null.
>> */
>> readonly attribute DOMString attrName;
>>
>> /*
>> * The previous value of the attribute or CharacterData node, or null.
>> * If a new attribute is added, prevValue is null.
>> */
>> readonly attribute DOMString prevValue;
>>
>> /*
>> * The new value of the attribute or CharacterData node, or null.
>> * If an attribute is removed, newValue is null.
>> */
>> readonly attribute DOMString newValue;
>> };
>>
>> [Callback, NoInterfaceObject]
>> interface ModificationCallback {
>> void handleBatch(in ModificationBatch aBatch);
>> };
>>
>> [Constructor(in ModificationCallback aDoneCallback)]
>> interface ModificationBatch {
>> /**
>> * Modifications is non-empty array only while aDoneCallback
>> * is called. And while that happens, modifications list doesn't
>> * change.
>> */
>> readonly attribute Modification[] modifications;
>>
>> void batchTextChanges(in Node aNode);
>> void unbatchTextChanges(in Node aNode);
>>
>> void batchChildListChanges(in Node aNode);
>> void unbatchChildListChanges(in Node aNode);
>>
>> void batchAttrChanges(in Node aNode);
>> void unbatchAttrChanges(in Node aNode);
>>
>> void batchAll();
>> void unbatchAll();
>> };
>>
>> aDoneCallback is called right before the call which is modifying DOM
>> returns. If aDoneCallback modifies DOM, new modifications list will be
>> collected
>> and callbacks will be called right after the initial aDoneCallback
>> returns.
>> ModificationBatches are always handled in the order they are *created*.
>> Callbacks are never called if modifications list is empty.
>>
>>
>> Example 1:
>> // log all the attribute changes
>> var o = new ModificationBatch(function(b) {
>> for (var i = 0; i < b.modifications.length; ++i) {
>> var m = b.modifications[i];
>> if (m.prevValue == null) {
>> console.log(m.attrName + " added");
>> } else if (m.newValue == null) {
>> console.log(m.attrName + " removed");
>> } else {
>> console.log(m.attrName + " modified");
>> }
>> }
>> }
>> );
>> o.batchAttrChanges(document);
>>
>>
>>
>
>
>

Received on Thursday, 4 August 2011 19:43:47 UTC