<?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>20525</bug_id>
          
          <creation_ts>2012-12-27 17:12:25 +0000</creation_ts>
          <short_desc>MIDIAccess methods aren&apos;t restricted to instances created by requestMIDIAccess</short_desc>
          <delta_ts>2013-01-18 15:47:39 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>AudioWG</product>
          <component>MIDI API</component>
          <version>unspecified</version>
          <rep_platform>PC</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>INVALID</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>TBD</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Jussi Kalliokoski">jussi.kalliokoski</reporter>
          <assigned_to name="Jussi Kalliokoski">jussi.kalliokoski</assigned_to>
          <cc>olivier.thereaux</cc>
    
    <cc>w3c</cc>
          
          <qa_contact>public-audio</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>80639</commentid>
    <comment_count>0</comment_count>
    <who name="Jussi Kalliokoski">jussi.kalliokoski</who>
    <bug_when>2012-12-27 17:12:25 +0000</bug_when>
    <thetext>The current IDL exposes the MIDIAccess interface as a global, but doesn&apos;t prohibit calling those methods on objects that aren&apos;t MIDIAccess instances created by navigator.requestMIDIAccess().</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>80640</commentid>
    <comment_count>1</comment_count>
    <who name="Jussi Kalliokoski">jussi.kalliokoski</who>
    <bug_when>2012-12-27 17:26:28 +0000</bug_when>
    <thetext>Fixed: https://github.com/WebAudio/web-midi-api/commit/16d1d6d61472081cad26282cbd44fd8dccc818e6</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>80641</commentid>
    <comment_count>2</comment_count>
    <who name="Marcos Caceres">w3c</who>
    <bug_when>2012-12-27 17:38:21 +0000</bug_when>
    <thetext>The object on the global scope is a different object :) This is where WebIDL gets funky. That&apos;s called the &quot;interface object&quot; and it does not expose the methods. 

See: 
http://www.w3.org/TR/WebIDL/#es-interfaces 

(yes, it&apos;s freeken complicated and I&apos;ve been trying to grok that for about a year) 

you basically end up with this:
//This one holds constants and statics
var interfaceObject=  function MidiAccess(){
  if(this instanceof MidiAccess){
     var msg=&quot;DOM object constructor cannot be called as a function.&quot;   
     throw new TypeError(msg);
  }
}
//This one makes actual instances
var interfacePrototypeObj = function MIDIAccess(){}   
window.MIDIAccess = interfaceObject; 


You can confirm this in the browser by querying any object. For example: 

&gt;&gt; Event
function Event() { [native code] }
&gt;&gt;Event()
TypeError: DOM object constructor cannot be called as a function.

Note that Event does not expose preventDefault() or any other instance method. Only the constants are exposed.  

Please revert the changes.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>80642</commentid>
    <comment_count>3</comment_count>
    <who name="Jussi Kalliokoski">jussi.kalliokoski</who>
    <bug_when>2012-12-27 17:46:43 +0000</bug_when>
    <thetext>(In reply to comment #2)
&gt; The object on the global scope is a different object :) This is where WebIDL
&gt; gets funky. That&apos;s called the &quot;interface object&quot; and it does not expose the
&gt; methods. 
&gt; 
&gt; See: 
&gt; http://www.w3.org/TR/WebIDL/#es-interfaces 
&gt; 
&gt; (yes, it&apos;s freeken complicated and I&apos;ve been trying to grok that for about a
&gt; year) 
&gt; 
&gt; you basically end up with this:
&gt; //This one holds constants and statics
&gt; var interfaceObject=  function MidiAccess(){
&gt;   if(this instanceof MidiAccess){
&gt;      var msg=&quot;DOM object constructor cannot be called as a function.&quot;   
&gt;      throw new TypeError(msg);
&gt;   }
&gt; }
&gt; //This one makes actual instances
&gt; var interfacePrototypeObj = function MIDIAccess(){}   
&gt; window.MIDIAccess = interfaceObject; 
&gt; 
&gt; 
&gt; You can confirm this in the browser by querying any object. For example: 
&gt; 
&gt; &gt;&gt; Event
&gt; function Event() { [native code] }
&gt; &gt;&gt;Event()
&gt; TypeError: DOM object constructor cannot be called as a function.
&gt; 
&gt; Note that Event does not expose preventDefault() or any other instance
&gt; method. Only the constants are exposed.  

Event doesn&apos;t, but Event.prototype does:

typeof Event.prototype.preventDefault === &apos;function&apos; // true</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>80643</commentid>
    <comment_count>4</comment_count>
    <who name="Jussi Kalliokoski">jussi.kalliokoski</who>
    <bug_when>2012-12-27 17:53:45 +0000</bug_when>
    <thetext>(In reply to comment #3)
&gt; (In reply to comment #2)
&gt; &gt; The object on the global scope is a different object :) This is where WebIDL
&gt; &gt; gets funky. That&apos;s called the &quot;interface object&quot; and it does not expose the
&gt; &gt; methods. 
&gt; &gt; 
&gt; &gt; See: 
&gt; &gt; http://www.w3.org/TR/WebIDL/#es-interfaces 
&gt; &gt; 
&gt; &gt; (yes, it&apos;s freeken complicated and I&apos;ve been trying to grok that for about a
&gt; &gt; year) 
&gt; &gt; 
&gt; &gt; you basically end up with this:
&gt; &gt; //This one holds constants and statics
&gt; &gt; var interfaceObject=  function MidiAccess(){
&gt; &gt;   if(this instanceof MidiAccess){
&gt; &gt;      var msg=&quot;DOM object constructor cannot be called as a function.&quot;   
&gt; &gt;      throw new TypeError(msg);
&gt; &gt;   }
&gt; &gt; }
&gt; &gt; //This one makes actual instances
&gt; &gt; var interfacePrototypeObj = function MIDIAccess(){}   
&gt; &gt; window.MIDIAccess = interfaceObject; 
&gt; &gt; 
&gt; &gt; 
&gt; &gt; You can confirm this in the browser by querying any object. For example: 
&gt; &gt; 
&gt; &gt; &gt;&gt; Event
&gt; &gt; function Event() { [native code] }
&gt; &gt; &gt;&gt;Event()
&gt; &gt; TypeError: DOM object constructor cannot be called as a function.
&gt; &gt; 
&gt; &gt; Note that Event does not expose preventDefault() or any other instance
&gt; &gt; method. Only the constants are exposed.  
&gt; 
&gt; Event doesn&apos;t, but Event.prototype does:
&gt; 
&gt; typeof Event.prototype.preventDefault === &apos;function&apos; // true

But actually, yeah, WebIDL prevents calling the interface methods with a non-platform-object &quot;this&quot; value, so I&apos;ll revert this.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>81562</commentid>
    <comment_count>5</comment_count>
    <who name="Olivier Thereaux">olivier.thereaux</who>
    <bug_when>2013-01-18 15:47:39 +0000</bug_when>
    <thetext>Closing.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>