W3C home > Mailing lists > Public > public-script-coord@w3.org > July to September 2010

RE: [WebIDL] interface objects and properties too restrictive?

From: Travis Leithead <travil@microsoft.com>
Date: Mon, 9 Aug 2010 19:30:41 +0000
To: Maciej Stachowiak <mjs@apple.com>
CC: Jonas Sicking <jonas@sicking.cc>, Cameron McCormack <cam@mcc.id.au>, "Sam Weinig (weinig@apple.com)" <weinig@apple.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>
Message-ID: <9768D477C67135458BF978A45BCF9B3817E230@TK5EX14MBXW603.wingroup.windeploy.ntdev.microsoft.com>
Maciej, you make some good points. 

My example for replacing a DOM operation may be somewhat contrived, because the default representation of "appendChild" would not be an accessor property but a data property (field); and changing the configurable property to false, per ES5 does not stop users from changing the value of this property as you note.

  >> From: Maciej Stachowiak [mailto:mjs@apple.com]
  >> [1] http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.206&content-type=text/html; charset=iso-8859-1#es-interfaces

  >> In this case, what's DontDelete is the property on the global object that represents the 
  >> interface object. For example, for the HTMLElement interface, it would be the property 
  >> window.HTMLElement. This should have no effect on making use of the object assigned to 
  >> that property. It just means you can't alter that property of the Window object, other 
  >> than to change its value.

So, this restriction limits script frameworks from removing _existing_ properties on the window object like "HTMLDocument" for example. Note, this might be interesting to do in order to test existing site-compat with the change made in HTML5:

"Because the HTMLDocument interface is now obtained using binding-specific casting methods instead of simply being the primary interface of the document object, it is no longer defined as inheriting from Document." [3]

Having these window properties marked as DontDelete also makes their attributes inconsistent with those other "constructors" defined by ES5 itself: "Object", "Function", "String", etc., all are configurable: true by default.

My argument is: what purpose is there in restricting these type of scenarios? I believe it's not really necessary (more below).

  >> From: Maciej Stachowiak [mailto:mjs@apple.com]
  >> [2] http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.206&content-type=text/html; charset=iso-8859-1#host-objects

  >> And in this case, DontDelete only applies to readonly attributes. It seems correct and 
  >> indeed required that you can't delete a readonly attribute or reconfigure it in other 
  >> ways. An example of a readonly attribute in HTML5 is HTMLDocument.URL. It would 
  >> (obviously I hope) make no sense to delete Document.URL or replace it with a setter.

  >> I don't see how this "completely destroy[s] the ability to set accessors". You can still 
  >> add a setter to HTMLElement.prototype.

Perhaps "completely destroy[s]" was a bit too strong of language here. I did not realize that the DontDelete applied only to readonly attributes. And if I understand you correctly above, you are saying that one can always "override" a readonly attribute by placing a getter/setter on another prototype. For this one point, when you do this, you lose the "scope" at which your override affects that property. For example, (humor me) if an implementation defines the DOM's "tagName" property as an accessor on HTMLElement.prototype, and that accessor was configurable: false, then user code wanting to re-define the behavior of "tagName" (perhaps to force it to be lowercase before returning the value), would be unable to change the getter function directly on this property, but would have to add overrides to prototypes further down the chain from HTMLElement (i.e., HTMLDivElement)--this seems a ridiculous workaround for such a scenario.

Aside from the specific scenario I used above, you have generally stated that you believe the current attributes are "correct and indeed required". Generally I agree with the "correct" idea; that from an interpretation of the DOM spec's readonly attribute, this seems like the right property descriptor attribute to use, but I disagree with "indeed required" because this statement closes the doors on many scenarios that we haven't even dreamed up now and in the future. Setting configurable: false is a one-way operation--user code is unable to undo such a change. From a pure JavaScript programming perspective, why should we be restricting the opportunities for web developers to creatively use these properties for their own purposes? At least if they are configurable: true, some script can come along and mark all these properties as configurable: false anyway, if their need arises.

One scenario that I'd like to be able to do is replace all DOM properties with accessors to track compatibility issues on the web. I can "fix" scripts that do stupid things by changing the behavior of innocent DOM APIs (both data properties and accessors alike). This scenario would be really difficult with readonly properties marked as configurable: false by the implementation.

I simply believe in increased programmability freedom on the web (by default), rather than a more locked-down version of the web platform which is what I am seeing spec'd in WebIDL at the moment.


[3] http://dev.w3.org/html5/spec/Overview.html#documents-in-the-dom

-----Original Message-----
From: Maciej Stachowiak [mailto:mjs@apple.com] 
Sent: Wednesday, August 04, 2010 3:43 PM
To: Travis Leithead
Cc: Jonas Sicking; Cameron McCormack; Sam Weinig (weinig@apple.com); public-webapps@w3.org
Subject: Re: [WebIDL] interface objects and properties too restrictive?

On Aug 4, 2010, at 11:36 AM, Travis Leithead wrote:

> Sure.
> Not only does ES5's configurable: false property prevent deletion, but it also prevents changing a property from a field to an accessor and vice-versa, as well as changing the getter/setters of the property.
> So, the following wouldn't work if the "appendChild" property was configurable:false:
> Object.defineProperty(Node.prototype, 
>                      "appendChild", 
>                      { get: function() { /* custom getter replacement */ }, 
>                        set: function(x) { /* custom setter replacement */ }
>                      });
> ... which is the ES5 way of doing:
> Node.prototype.__defineGetter__("appendChild", function() { /* custom 
> getter replacement */ }); 
> Node.prototype.__defineSetter__("appendChild", function(x) { /* custom 
> setter replacement */ });
> So, configurable: false prevents users from replacing built-in properties with getter/setters. I think this is too restrictive, especially forward-looking considering how much the DOM is changing and evolving.

I don't see why you would want to do that. The common way to override the behavior of DOM operations is: 

Node.prototype.appendChild = function(node) { /* replacement function */ }

I think what you describe is not commonly done, or particularly useful. Furthermore, prototype hacking is primarily used for additions, not replacements, which are not impacted by this at all.

Likewise, I don't think it's common to want to add a setter for the window.Node global interface object.


> -----Original Message-----
> From: Jonas Sicking [mailto:jonas@sicking.cc]
> Sent: Tuesday, August 03, 2010 5:22 PM
> To: Travis Leithead
> Cc: Cameron McCormack; Sam Weinig (weinig@apple.com); 
> public-webapps@w3.org
> Subject: Re: [WebIDL] interface objects and properties too restrictive?
> On Tue, Aug 3, 2010 at 4:57 PM, Travis Leithead <travil@microsoft.com> wrote:
>> Hey folks, just wondering what the justification behind the current 
>> {DontDelete} semantics are in WebIDL 4.4 [1] and 4.5 (second bullet) 
>> [2]. When our IE9 binding ported this to ES5, it translated to
>> "configurable: false", which completely destroyed the ability to set 
>> accessors on the interface objects as well as operations (and in our 
>> case, DOM accessors). Because of this, we actually don't mark our 
>> interface objects OR operations/attributes as configurable: false, 
>> rather configurable: true.*
>> If this seems reasonable, I'd like to see the spec updated.
> Sorry, I'm not very updated on the differences between the ES3 and ES5 worlds. Why does "configurable: false" destroyed the ability to set accessors? Can you give an example of a piece of script that doesn't work but which you'd like to work, and what you'd like it to do?
> / Jonas
Received on Monday, 9 August 2010 19:31:19 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 17:14:02 UTC