<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>19463</bug_id>
          
          <creation_ts>2012-10-11 09:58:41 +0000</creation_ts>
          <short_desc>MutationRecord added/removedNodes could return empty array, not null</short_desc>
          <delta_ts>2012-11-20 18:17:00 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebAppsWG</product>
          <component>DOM</component>
          <version>unspecified</version>
          <rep_platform>PC</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Olli Pettay">bugs</reporter>
          <assigned_to name="Anne">annevk</assigned_to>
          <cc>adamk</cc>
    
    <cc>mike</cc>
    
    <cc>rafaelw</cc>
    
    <cc>www-dom</cc>
          
          <qa_contact>public-webapps-bugzilla</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>75955</commentid>
    <comment_count>0</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-11 09:58:41 +0000</bug_when>
    <thetext>This is the behavior in Gecko, and it makes the API, IMO, easier
to use and more consistent with other nodelist getter APIs.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>75982</commentid>
    <comment_count>1</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-10-11 14:22:10 +0000</bug_when>
    <thetext>Sorry WebKit for not catching this sooner. Olli is right, they should never have been allowed to be null to begin with.

https://github.com/whatwg/dom/commit/aad67c8f0cd78f3a9157acd481384ae22b5662de
http://dom.spec.whatwg.org/</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76022</commentid>
    <comment_count>2</comment_count>
    <who name="Adam Klein">adamk</who>
    <bug_when>2012-10-11 18:39:58 +0000</bug_when>
    <thetext>(In reply to comment #1)
&gt; Sorry WebKit for not catching this sooner. Olli is right, they should never
&gt; have been allowed to be null to begin with.

Luckily WebKit already had these empty for type = &apos;childList&apos;; I&apos;d hope that there&apos;s not much code that looks at added/removed nodes for non-childList records. Just curious, what&apos;s the advantage of having those non-null on attributes/characterData records?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76023</commentid>
    <comment_count>3</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-11 18:48:25 +0000</bug_when>
    <thetext>No need to null check if you have some generic stuff handling
MutationRecords.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76161</commentid>
    <comment_count>4</comment_count>
    <who name="Rafael Weinstein">rafaelw</who>
    <bug_when>2012-10-12 20:13:42 +0000</bug_when>
    <thetext>my $.02:

If you are processing every mutation as if it were a childlist, you&apos;re doing something wrong and likely to get the wrong answer. It should be an invariant that a childlist mutation record has at least one node in either of added/removed nodes and code which tolerates both being empty is probably wrong.

I think that having an empty array for added/removed in the case of non-childlist changes suggests something misleading about how the API works.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76162</commentid>
    <comment_count>5</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-10-12 20:17:56 +0000</bug_when>
    <thetext>Olli, do you feel strongly about this? It kinda makes sense I guess to make them null in the non-childList case. (Personally I thought we should have had separate record interfaces...)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76163</commentid>
    <comment_count>6</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-10-12 20:18:35 +0000</bug_when>
    <thetext>Reopening so we can reach some kind of conclusion.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76211</commentid>
    <comment_count>7</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-13 13:56:06 +0000</bug_when>
    <thetext>I don&apos;t feel strongly about this.
But I think returning always an array makes the API more consistent.
addedNodes and removedNodes tell always which nodes where added or removed,
and in cases of non-childList they are empty, since nothing was added or
removed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76212</commentid>
    <comment_count>8</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-13 14:00:30 +0000</bug_when>
    <thetext>Somewhat similar happens for example with
document.querySelectorAll(&quot;foo&quot;).
If there are no foos, it is empty list, not null which is returned.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76481</commentid>
    <comment_count>9</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-10-17 09:08:19 +0000</bug_when>
    <thetext>I think the point is that the other NodeList accessors are never exposed in a context where the NodeList can only be empty.

This is one of the reasons why I would have preferred distinct MutationRecord interfaces.

Anyway, still not sure what to do.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76488</commentid>
    <comment_count>10</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-17 11:11:41 +0000</bug_when>
    <thetext>(In reply to comment #4)
&gt;  It should be an
&gt; invariant that a childlist mutation record has at least one node in either
&gt; of added/removed nodes and code which tolerates both being empty is probably
&gt; wrong.
Why such invariant?

&gt; I think that having an empty array for added/removed in the case of
&gt; non-childlist changes suggests something misleading about how the API works.
I see addedNodes and removedNodes as part of the MutationRecord.
You should always know whether something was added by checking
record.addedNodes.length.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76614</commentid>
    <comment_count>11</comment_count>
    <who name="Rafael Weinstein">rafaelw</who>
    <bug_when>2012-10-18 21:20:14 +0000</bug_when>
    <thetext>(In reply to comment #10)
&gt; (In reply to comment #4)
&gt; &gt;  It should be an
&gt; &gt; invariant that a childlist mutation record has at least one node in either
&gt; &gt; of added/removed nodes and code which tolerates both being empty is probably
&gt; &gt; wrong.
&gt; Why such invariant?

What Anne said. You&apos;re usually the consistency guy =-). You don&apos;t find this to be inconsistent with existing APIs?

&gt; 
&gt; &gt; I think that having an empty array for added/removed in the case of
&gt; &gt; non-childlist changes suggests something misleading about how the API works.
&gt; I see addedNodes and removedNodes as part of the MutationRecord.
&gt; You should always know whether something was added by checking
&gt; record.addedNodes.length.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76619</commentid>
    <comment_count>12</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-10-18 21:39:29 +0000</bug_when>
    <thetext>(In reply to comment #11)
&gt; What Anne said. You&apos;re usually the consistency guy =-). You don&apos;t find this
&gt; to be inconsistent with existing APIs?
&gt; 
No. This is consistent with existing APIs.
You get empty Nodelist all the time from various functions 
(I know, we&apos;re dealing attributes here), but not null.


Also, it would be inconsistent to have empty nodelist in case type
is childList, but null in other cases.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>76625</commentid>
    <comment_count>13</comment_count>
    <who name="Rafael Weinstein">rafaelw</who>
    <bug_when>2012-10-18 22:10:42 +0000</bug_when>
    <thetext>(In reply to comment #12)
&gt; (In reply to comment #11)
&gt; &gt; What Anne said. You&apos;re usually the consistency guy =-). You don&apos;t find this
&gt; &gt; to be inconsistent with existing APIs?
&gt; &gt; 
&gt; No. This is consistent with existing APIs.
&gt; You get empty Nodelist all the time from various functions 
&gt; (I know, we&apos;re dealing attributes here), but not null.
&gt; 
&gt; 
&gt; Also, it would be inconsistent to have empty nodelist in case type
&gt; is childList, but null in other cases.

I don&apos;t have any further defense for my position. I suppose it&apos;s stylistic. My $.02 is that null for the case of non-childlist is correct. I defer to Anne to make the call. FWIW, This doesn&apos;t strike me as &quot;make-or-break&quot; either way.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78044</commentid>
    <comment_count>14</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-11-08 14:12:53 +0000</bug_when>
    <thetext>Resolving as FIXED per comment 1 meaning they are not nullable. Rationale is that when e.g. logging everything to a console obj.addedNodes.length would fail.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78048</commentid>
    <comment_count>15</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-11-08 14:36:07 +0000</bug_when>
    <thetext>Argh. I just noticed that every other member does use the nullable pattern. E.g. either a string or null (rather than simply empty string). Olli?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78055</commentid>
    <comment_count>16</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-11-08 15:38:12 +0000</bug_when>
    <thetext>What has that to do with this bug.
null is ok for string attributes IMO, and even needed in cases like
oldValue, where the oldValue might be &quot;&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78056</commentid>
    <comment_count>17</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2012-11-08 15:40:55 +0000</bug_when>
    <thetext>Meh.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78545</commentid>
    <comment_count>18</comment_count>
    <who name="Rafael Weinstein">rafaelw</who>
    <bug_when>2012-11-20 18:13:48 +0000</bug_when>
    <thetext>Ok. Just to be clear (because it looks like WebKit needs to change), the decision here is that addedNodes and removedNodes must be empty NodeLists in the case of non-childList mutation type?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78546</commentid>
    <comment_count>19</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-11-20 18:16:10 +0000</bug_when>
    <thetext>Yes.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>78548</commentid>
    <comment_count>20</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2012-11-20 18:17:00 +0000</bug_when>
    <thetext>(as they are also in case of childList when no nodes are added or removed.)</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>