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 20525 - MIDIAccess methods aren't restricted to instances created by requestMIDIAccess
Summary: MIDIAccess methods aren't restricted to instances created by requestMIDIAccess
Status: CLOSED INVALID
Alias: None
Product: AudioWG
Classification: Unclassified
Component: MIDI API (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: TBD
Assignee: Jussi Kalliokoski
QA Contact: public-audio
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-12-27 17:12 UTC by Jussi Kalliokoski
Modified: 2013-01-18 15:47 UTC (History)
2 users (show)

See Also:


Attachments

Description Jussi Kalliokoski 2012-12-27 17:12:25 UTC
The current IDL exposes the MIDIAccess interface as a global, but doesn't prohibit calling those methods on objects that aren't MIDIAccess instances created by navigator.requestMIDIAccess().
Comment 2 Marcos Caceres 2012-12-27 17:38:21 UTC
The object on the global scope is a different object :) This is where WebIDL gets funky. That's called the "interface object" and it does not expose the methods. 

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

(yes, it's freeken complicated and I'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="DOM object constructor cannot be called as a function."   
     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: 

>> Event
function Event() { [native code] }
>>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.
Comment 3 Jussi Kalliokoski 2012-12-27 17:46:43 UTC
(In reply to comment #2)
> The object on the global scope is a different object :) This is where WebIDL
> gets funky. That's called the "interface object" and it does not expose the
> methods. 
> 
> See: 
> http://www.w3.org/TR/WebIDL/#es-interfaces 
> 
> (yes, it's freeken complicated and I'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="DOM object constructor cannot be called as a function."   
>      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: 
> 
> >> Event
> function Event() { [native code] }
> >>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.  

Event doesn't, but Event.prototype does:

typeof Event.prototype.preventDefault === 'function' // true
Comment 4 Jussi Kalliokoski 2012-12-27 17:53:45 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > The object on the global scope is a different object :) This is where WebIDL
> > gets funky. That's called the "interface object" and it does not expose the
> > methods. 
> > 
> > See: 
> > http://www.w3.org/TR/WebIDL/#es-interfaces 
> > 
> > (yes, it's freeken complicated and I'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="DOM object constructor cannot be called as a function."   
> >      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: 
> > 
> > >> Event
> > function Event() { [native code] }
> > >>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.  
> 
> Event doesn't, but Event.prototype does:
> 
> typeof Event.prototype.preventDefault === 'function' // true

But actually, yeah, WebIDL prevents calling the interface methods with a non-platform-object "this" value, so I'll revert this.
Comment 5 Olivier Thereaux 2013-01-18 15:47:39 UTC
Closing.