Bug 742482 - Add support for MutationObserver.takeRecords(), r=sicking

This commit is contained in:
Olli Pettay 2012-04-11 08:24:18 +03:00
parent c1d35d7eaf
commit 8b443bebd8
4 changed files with 75 additions and 17 deletions

View File

@ -585,6 +585,36 @@ nsDOMMutationObserver::Disconnect()
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationObserver::TakeRecords(nsIVariant** aRetVal)
{
*aRetVal = TakeRecords().get();
return NS_OK;
}
already_AddRefed<nsIVariant>
nsDOMMutationObserver::TakeRecords()
{
nsCOMPtr<nsIWritableVariant> mutations =
do_CreateInstance("@mozilla.org/variant;1");
PRInt32 len = mPendingMutations.Count();
if (len == 0) {
mutations->SetAsEmptyArray();
} else {
nsTArray<nsIDOMMutationRecord*> mods(len);
for (PRInt32 i = 0; i < len; ++i) {
mods.AppendElement(mPendingMutations[i]);
}
mutations->SetAsArray(nsIDataType::VTYPE_INTERFACE,
&NS_GET_IID(nsIDOMMutationRecord),
mods.Length(),
const_cast<void*>(
static_cast<const void*>(mods.Elements())));
mPendingMutations.Clear();
}
return mutations.forget();
}
NS_IMETHODIMP
nsDOMMutationObserver::Initialize(nsISupports* aOwner, JSContext* cx,
@ -639,21 +669,8 @@ nsDOMMutationObserver::HandleMutation()
mPendingMutations.Clear();
return;
}
PRInt32 len = mPendingMutations.Count();
nsTArray<nsIDOMMutationRecord*> mods(len);
for (PRInt32 i = 0; i < len; ++i) {
mods.AppendElement(mPendingMutations[i]);
}
nsCOMPtr<nsIWritableVariant> mutations =
do_CreateInstance("@mozilla.org/variant;1");
mutations->SetAsArray(nsIDataType::VTYPE_INTERFACE,
&NS_GET_IID(nsIDOMMutationRecord),
mods.Length(),
const_cast<void*>(
static_cast<const void*>(mods.Elements())));
mPendingMutations.Clear();
nsCOMPtr<nsIVariant> mutations = TakeRecords();
nsAutoMicroTask mt;
sCurrentObserver = this; // For 'this' handling.
mCallback->HandleMutations(mutations, this);

View File

@ -320,6 +320,8 @@ protected:
nsMutationReceiver* GetReceiverFor(nsINode* aNode, bool aMayCreate);
void RemoveReceiver(nsMutationReceiver* aReceiver);
already_AddRefed<nsIVariant> TakeRecords();
void GetAllSubtreeObserversFor(nsINode* aNode,
nsTArray<nsMutationReceiver*>& aObservers);
void ScheduleForRun();

View File

@ -477,7 +477,45 @@ function testModalDialog() {
div.innerHTML = "<span><span>foo</span></span>";
window.showModalDialog("mutationobserver_dialog.html");
ok(didHandleCallback, "Should have called the callback while showing modal dialog!");
then();
then(testTakeRecords);
}
function testTakeRecords() {
var s = "<span>1</span><span>2</span>";
div.innerHTML = s;
var takenRecords;
m = new M(function(records, observer) {
is(records.length, 3, "Should have got 3 records");
is(records[0].type, "attributes", "Should have got attributes");
is(records[0].attributeName, "foo", "");
is(records[1].type, "childList", "Should have got childList");
is(records[1].removedNodes.length, 2, "Should have got removedNodes");
is(records[1].addedNodes.length, 2, "Should have got addedNodes");
is(records[2].type, "attributes", "Should have got attributes");
is(records[2].attributeName, "foo", "");
is(records.length, takenRecords.length, "Should have had similar mutations");
is(records[0].type, takenRecords[0].type, "Should have had similar mutations");
is(records[1].type, takenRecords[1].type, "Should have had similar mutations");
is(records[2].type, takenRecords[2].type, "Should have had similar mutations");
is(records[1].removedNodes.length, takenRecords[1].removedNodes.length, "Should have had similar mutations");
is(records[1].addedNodes.length, takenRecords[1].addedNodes.length, "Should have had similar mutations");
is(m.takeRecords().length, 0, "Shouldn't have any records");
observer.disconnect();
then();
m = null;
});
m.observe(div, { childList: true, attributes: true });
div.setAttribute("foo", "bar");
div.innerHTML = s;
div.removeAttribute("foo");
takenRecords = m.takeRecords();
div.setAttribute("foo", "bar");
div.innerHTML = s;
div.removeAttribute("foo");
}
SimpleTest.waitForExplicitFinish();

View File

@ -56,12 +56,13 @@ dictionary MutationObserverInit
};
//[Constructor(in nsIMutationCallback aDoneCallback)]
[scriptable, builtinclass, uuid(daeba265-9aa7-45ab-8de2-b6b039c13ced)]
[scriptable, builtinclass, uuid(156e2ce4-e44a-45f3-92c2-e6611f391dae)]
interface nsIDOMMozMutationObserver : nsISupports
{
[implicit_jscontext]
void observe(in nsIDOMNode aTarget, in jsval aOptions);
void disconnect();
nsIVariant takeRecords();
};
[scriptable, function, uuid(fb539590-b088-4d07-96ff-2cefbc90a198)]