This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
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().
Fixed: https://github.com/WebAudio/web-midi-api/commit/16d1d6d61472081cad26282cbd44fd8dccc818e6
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.
(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
(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.
Closing.