Here are some tryserver builds.
http://ftp.mozilla.org/pub/mozilla.org/firefox/try-builds/opet...@mozilla.com-e57a1a317f25/

The default is mostly-sync approach,
but if one sets dom.AlmostAsyncModificationBatch to true
(load about:config, right click, add new boolean),
and restarts the browser, callbacks are called at the end of the task.

API is http://hg.mozilla.org/try/file/23ac4760d571/dom/interfaces/core/nsIDOMModificationBatch.idl
and a very simple test page
http://mozilla.pettay.fi/modificationbatchtest.html
The API doesn't have the index of added/removed child node,
but that could be added easily.


-Olli




On 08/10/2011 10:49 PM, Olli Pettay wrote:
FYI, I'm planning to implement the proposal (using vendor prefixed API)
so that I can create "tryserver" builds.
I'll post the links to builds here later, hopefully in a few days, when
I find the time to do the actual implementation.


-Olli


On 08/04/2011 04:38 PM, 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




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);









Reply via email to