<?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>27122</bug_id>
          
          <creation_ts>2014-10-21 17:42:26 +0000</creation_ts>
          <short_desc>MutationObserver.observe(node, {}) should throw</short_desc>
          <delta_ts>2014-10-22 14:11:07 +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>jonas</cc>
    
    <cc>mike</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>113533</commentid>
    <comment_count>0</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 17:42:26 +0000</bug_when>
    <thetext>If nothing would be observed, observe() should just throw.
This was the behavior at some point, but the spec seems to have changed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113535</commentid>
    <comment_count>1</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 18:19:05 +0000</bug_when>
    <thetext>&quot;If either options&apos; attributeOldValue or attributeFilter is present and options&apos; attributes is omitted, set options&apos; attributes to true. &quot;
should also check that attributeFilter has at least one value.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113536</commentid>
    <comment_count>2</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2014-10-21 18:49:55 +0000</bug_when>
    <thetext>Note that this means that if we add the ability to observe more things in the future, like shadow-DOM stuff, that would mean that

MutationObserver.observe(node, { newFeature: true })

would throw in downlevel browsers, whereas

MutationObserver.observe(node, { newFeature: true, childList: true })

would not throw. This seems somewhat inconsistent and could force authors to wrap try/catches around their code just to suppress exceptions.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113537</commentid>
    <comment_count>3</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 19:10:59 +0000</bug_when>
    <thetext>Well, MutationObserver.observe(node, { newFeature: true }) certainly should throw if that newFeature isn&apos;t supported.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113538</commentid>
    <comment_count>4</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2014-10-21 19:22:12 +0000</bug_when>
    <thetext>Do you also think that

MutationObserver.observe(node, { newFeature: true, childList: true })

should throw if newFeature is not supported?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113539</commentid>
    <comment_count>5</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 19:26:51 +0000</bug_when>
    <thetext>Oh, I see.

Yeah, that newFeature shouldn&apos;t cause throwing, unless
having newFeature: true and childList: true doesn&apos;t make sense in the implementations which support newFeature.

That is similar to 
observe(node, {  attributeOldValue: true, attributes: false}); which throws.

So, {} should throw, since it doesn&apos;t cause any node to be observed in anyway.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113540</commentid>
    <comment_count>6</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2014-10-21 19:41:26 +0000</bug_when>
    <thetext>So do you think that

MutationObserver.observe(node, { newFeature: true })

should throw in current browsers? Or is it specifically *only* empty objects that should cause an exception?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113541</commentid>
    <comment_count>7</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 20:05:19 +0000</bug_when>
    <thetext>if observe(foo, { ... something...}) doesn&apos;t end up doing anything (not observe any changes), that should throw. Scripts should know asap that something is going wrong, not wait later to figure out that the expected MutationRecords won&apos;t be there.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113542</commentid>
    <comment_count>8</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-10-21 20:13:29 +0000</bug_when>
    <thetext>(In reply to Olli Pettay from comment #0)
&gt; This was the behavior at some point, but the spec seems to have changed.

[citation needed]


(In reply to Olli Pettay from comment #1)
&gt; should also check that attributeFilter has at least one value.

No, I recall we decided that checking for presence was what we wanted here.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113543</commentid>
    <comment_count>9</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 20:23:59 +0000</bug_when>
    <thetext>(In reply to Anne from comment #8)
&gt; (In reply to Olli Pettay from comment #0)
&gt; &gt; This was the behavior at some point, but the spec seems to have changed.
&gt; 
&gt; [citation needed]
Gecko&apos;s current behavior follows an older version of the spec.


&gt; (In reply to Olli Pettay from comment #1)
&gt; &gt; should also check that attributeFilter has at least one value.
&gt; 
&gt; No, I recall we decided that checking for presence was what we wanted here.

[citation needed] ;)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113546</commentid>
    <comment_count>10</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2014-10-21 22:49:09 +0000</bug_when>
    <thetext>(In reply to Olli Pettay from comment #7)
&gt; if observe(foo, { ... something...}) doesn&apos;t end up doing anything (not
&gt; observe any changes), that should throw. Scripts should know asap that
&gt; something is going wrong, not wait later to figure out that the expected
&gt; MutationRecords won&apos;t be there.

You seem to consider &quot;observing fewer things than expected&quot; to be different from &quot;observing nothing&quot;. Is that true?

I.e. in both of

MutationObserver.observe(node, { newFeature: true })
MutationObserver.observe(node, { newFeature: true, childList: true })

the newFeature observations won&apos;t be fired in a downlevel browser. Are you saying that&apos;s worse in the first case than in the second case?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113549</commentid>
    <comment_count>11</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 23:11:50 +0000</bug_when>
    <thetext>That is mostly hypothetical, and if new features is to be added, we should make
sure that backwards compatibility is sane.

Is there any reason to not throw early if observe() doesn&apos;t do anything sane?
(and it used to do that)

Why would newFeature be handled differently to existing properties where we throw in some cases.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113550</commentid>
    <comment_count>12</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-21 23:19:56 +0000</bug_when>
    <thetext>Other option is to never throw from observe() (but that would be just a bad API).
Either we throw in all the cases observe() doesn&apos;t do anything sane, or we never throw.
No special cases. Consistency, pretty please.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113552</commentid>
    <comment_count>13</comment_count>
    <who name="Jonas Sicking (Not reading bugmail)">jonas</who>
    <bug_when>2014-10-21 23:45:24 +0000</bug_when>
    <thetext>(In reply to Olli Pettay from comment #11)
&gt; Is there any reason to not throw early if observe() doesn&apos;t do anything sane?

The reason is that &quot;doesn&apos;t do anything sane&quot; is going to vary from use-case to use-case. I.e. in some cases it might be quite sane to simply not receive certain notifications if the browser doesn&apos;t support them, in others not.

For example if we add notifications for Shadow DOM, then not firing those in browsers that doesn&apos;t support Shadow DOM might be just fine. In such browsers the website might use a Shadow DOM polyfill which provides its own notification mechanism.

The other reason is that we can&apos;t really be consistent. I.e. we can&apos;t make both of these throw, so it might be more consistent to make neither throw:

MutationObserver.observe(node, { newFeature: true })
MutationObserver.observe(node, { newFeature: true, childList: true })

The reason we can&apos;t make both throw is that JS doesn&apos;t provide a good way to check that &quot;no unknown properties are provided&quot;. Things like non-enumerable properties, properties on prototype objects, and proxies simply make checking for lack of unknown properties too hard/complex.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113560</commentid>
    <comment_count>14</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-22 11:20:31 +0000</bug_when>
    <thetext>We&apos;re not adding any shadow DOM specific options atm. That is hypothetical still
(observing changes in Shadow DOM would make its encapsulation weaker and weaker, though since it pretty much doesn&apos;t any any encapsulation, perhaps that doesn&apos;t really matter.)

If one is using options which don&apos;t cause any observing would be a 
bug in application logic, and in such case there should be an exception thrown as early as possible.

(In reply to Jonas Sicking from comment #13)
&gt; (In reply to Olli Pettay from comment #11)

&gt; The other reason is that we can&apos;t really be consistent. I.e. we can&apos;t make
&gt; both of these throw, so it might be more consistent to make neither throw:
&gt; 
&gt; MutationObserver.observe(node, { newFeature: true })
&gt; MutationObserver.observe(node, { newFeature: true, childList: true })
I&apos;m not saying they both should throw. The latter is perfectly valid.

This is no different to
XHR.open(&quot;foobar&quot;, &quot;http://www.w3.org&quot;);
Maybe in the future we&apos;ll support &quot;foobar&quot; method, but for now open() throws if invalid method name is passed to it as the first parameter.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113561</commentid>
    <comment_count>15</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-10-22 11:28:26 +0000</bug_when>
    <thetext>That seems like a bad example. It shouldn&apos;t throw, and I don&apos;t think it does.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113563</commentid>
    <comment_count>16</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-22 11:50:20 +0000</bug_when>
    <thetext>&quot;If method is not a method, throw a SyntaxError exception.&quot;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113564</commentid>
    <comment_count>17</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-10-22 12:37:56 +0000</bug_when>
    <thetext>Right, and &quot;foobar&quot; is a method per that definition.

Anyway, I&apos;m not sure why we&apos;d start throwing here. Is that what any implementation does?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113565</commentid>
    <comment_count>18</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-22 12:49:45 +0000</bug_when>
    <thetext>Make it &quot; foo bar something which doesn&apos;t look like the current token in http1&quot; ;)


Gecko throws in this case
var mo = new MutationObserver(function() {});
mo.observe(document, {});
since the spec used to require throwing in that case.

http://hg.mozilla.org/mozilla-central/annotate/ae4d9b4ff2ee/content/base/src/nsDOMMutationObserver.cpp#l456

And I don&apos;t know why the spec removed throwing in that case but kept throwing
in some other cases.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113566</commentid>
    <comment_count>19</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-10-22 13:03:07 +0000</bug_when>
    <thetext>You are correct. Originally we had

https://github.com/whatwg/dom/commit/5527027d71d72293f1e5cbafbf5e938f026a3b50

which got changed in

https://github.com/whatwg/dom/commit/a770b11981f4c147f98753cf726e44b14d17affc

based on discussion in bug 23189.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113567</commentid>
    <comment_count>20</comment_count>
    <who name="Olli Pettay">bugs</who>
    <bug_when>2014-10-22 13:06:38 +0000</bug_when>
    <thetext>And https://www.w3.org/Bugs/Public/show_bug.cgi?id=23189#c3

* If none of options&apos; childList, attributes, and characterData is true, throw a TypeError.

Something else what committed to the spec.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>113568</commentid>
    <comment_count>21</comment_count>
    <who name="Anne">annevk</who>
    <bug_when>2014-10-22 14:11:07 +0000</bug_when>
    <thetext>https://github.com/whatwg/dom/commit/4bf29a4ae4a1e5e4f1a5249f5fc7aa40d37b3f51

Thanks Olli!</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>