This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27320 - Need some clarification around MutationObserver stuff.
Summary: Need some clarification around MutationObserver stuff.
Status: RESOLVED INVALID
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: DOM (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Anne
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-13 21:03 UTC by Arkadiusz Michalski (Spirit)
Modified: 2014-11-14 11:45 UTC (History)
3 users (show)

See Also:


Attachments

Description Arkadiusz Michalski (Spirit) 2014-11-13 21:03:45 UTC
I tried analyze dependencies across all algorithms and other prose for MutationObserver oposite to how browsers works, but every time something is wrong. Here are some inaccuracies:

=== 

callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);

In practice mutations and observer are optional (Firefox/Chrome/IE), so maybe add "optional" to IDL? And maybe cover this somehow in prose (step 3.4 in "notify mutation observers").

<script>
	var new_MO = new MutationObserver(function(){});
	alert(new_MO); // create without any problem
</script>

===

Next is more complicated, but I'm not sure whether it is browsers problem or DOM. This affects mainly to "notify mutation observers" alghoritm and proper support takeRecords() method. Important thing is that if we operete on orginal or copy of something (like list or other object).

Look this:
2. Let notify list be a copy of unit of related similar-origin browsing contexts's list of MutationObserver objects. 

Per spec. callback get only copy of MO (as second argument) but all browsers operate on original.

<script>

	var new_MO = new MutationObserver(function(records, observer){

		alert(new_MO === observer);
		alert(new_MO === this);
		alert(this === observer);
		
	});
	
	var new_P = document.createElement("P");
	new_MO.observe(new_P, {attributes: true});
	
	new_P.id = "setID";
	
</script>

Above is important for takeRecords() method because we can use this method for original (new_MO in our example) and for copy (observer in our example as second argument for callback or "this" value) directly in callback. takeRecords() method should clear "record queue", but if we have different object we have different "record queue" too.

<script>

	var new_MO = new MutationObserver(function(records, observer){

		// All browsers trate new_MO and observer as the same object (instance) and clear its record queue before invoke callback
		// its correct per step 3.2, but in generaly not per step 2. (algo "notify mutation observers") because its operate on copy

		var takeFrom_MO = new_MO.takeRecords().length; //  record queue is empty
		var takeFrom_observer = observer.takeRecords().length; //  record queue is empty
		
		document.documentElement.innerHTML += "new_MO.takeRecords().length: " + takeFrom_MO
			+ "<br>" + "observer.takeRecords().length: " + takeFrom_observer
			
			// This was only copy so we still get 1
			+ "<br>" + "records.length: " + records.length
	});
	
	var new_P = document.createElement("P");
	new_MO.observe(new_P, {attributes: true});
	
	new_P.id = "setID";

</script>

What do you think?
Comment 1 Olli Pettay 2014-11-13 21:22:13 UTC
(In reply to Arkadiusz Michalski (Spirit) from comment #0)
> I tried analyze dependencies across all algorithms and other prose for
> MutationObserver oposite to how browsers works, but every time something is
> wrong. Here are some inaccuracies:
> 
> === 
> 
> callback MutationCallback = void (sequence<MutationRecord> mutations,
> MutationObserver observer);
> 
> In practice mutations and observer are optional (Firefox/Chrome/IE), so
> maybe add "optional" to IDL? And maybe cover this somehow in prose (step 3.4
> in "notify mutation observers").

No need for optional there. That is just how callbacks work. 
Similar to event listeners.
callback interface EventListener {
  void handleEvent(Event event);
};
yet you don't have to define the parameter if you're not going to use it anywhere.


> Per spec. callback get only copy of MO (as second argument) but all browsers
> operate on original.
Nothing says observer should be copy.
In fact, there is the following as a note:
"the constructed MutationObserver object as second argument. "
and there is also
"If queue is non-empty, call mo's callback with queue as first argument, and mo (itself) as second argument and callback this value. "


> 
> 	var new_MO = new MutationObserver(function(records, observer){
> 
> 		// All browsers trate new_MO and observer as the same object (instance)
> and clear its record queue before invoke callback
> 		// its correct per step 3.2, but in generaly not per step 2. (algo "notify
> mutation observers") because its operate on copy
Step 2 says to take a copy of the list. Not copy the MutationObserver objects.
Comment 2 Arkadiusz Michalski (Spirit) 2014-11-13 23:54:26 UTC
Ok, callback case its clear.

Ehh... around "copy" I waste some time:), didn't realize that "copy list" just copy list (where content of list is still original). But still don't understand why list must be copy. In this alghoritm we don't modificate list but touch only its content (MutationObserver objects), so contents of list and copy of list looks/are the same.

To thank you for your explanation, this can be correct in "queue a mutation record":

4.7 If observer has a paired string, set record's oldValue to observer's paired string. << for /oldValue/ you can use reference (as we have in previous steps)
Comment 3 Anne 2014-11-14 11:45:25 UTC
The previous steps are different. Paired string is already set to oldValue earlier on. I have linked oldValue now though...