- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Tue, 10 Feb 2015 14:01:41 -0500
- To: "public-script-coord@w3.org" <public-script-coord@w3.org>
I'm looking for some feedback, especially from folks familiar with the ES spec and other implementors, for some changes I'd like to propose to how platform objects with named properties work. These changes are meant to address <https://www.w3.org/Bugs/Public/show_bug.cgi?id=26521> and <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25025>. The changes are as follows: 1) Factor out the algorithm currently defined in http://heycam.github.io/webidl/#getownproperty into a PlatformObjectGetOwnProperty abstract operation that takes three arguments: an object O, a property name P and a boolean "ignore" value. Remove the current step 1 of that algorithm, since the "ignore" value is now passed in. 2) Change [[GetOwnProperty]] on platform objects to call PlatformObjectGetOwnProperty(O, P, false), thus preserving its current behavior. 3) Define a [[Set]] on platform objects that does the following: 1. If O == Receiver, then: a. If O supports indexed properties, P is an array index property name, and O implements an interface with an indexed property setter, then: i. Invoke the indexed setter (this will actually be a few more steps). ii. Return true. b. If O supports named properties, P is not an array index property name, Type(P) is String, and O implements an interface with a named property setter, then: i. Invoke the named setter (this will actually be a few more steps). ii. Return true. 2. Let ownDesc be the result of calling PlatformObjectGetOwnProperty(O, P, O == Receiver) 3. Perform steps 3-11 of http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver The idea is to ensure that we call named setters, but only when O == Receiver (this fixes <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25025>) and to ensure that we ignore named properties when looking for a setter for the property (this fixes <https://www.w3.org/Bugs/Public/show_bug.cgi?id=26521>). Apart from that, we just do the default [[Set]] behavior. Thoughts? To make this more concrete, here is a testcase that tests some of these bits, for both overridebuiltins (the dataset) and non-overridebuiltins (Storage) objects: <script> // named setter on proto chain, no overridebuiltins var foo = Object.create(sessionStorage); foo.x = "a"; alert("One: " + foo.x); alert("Two: " + sessionStorage.x); // named setter on object, no overridebuiltins sessionStorage.getItem = "b"; alert("Three: " + sessionStorage.getItem); alert("Four: " + Storage.prototype.getItem.call(sessionStorage, "getItem")); // named setter on proto chain, overidebuiltins var bar = Object.create(document.documentElement.dataset); bar.x = "c"; alert("Five: " + bar.x); alert("Six: " + document.documentElement.dataset.x); // named setter on object, overridebuiltins Object.prototype.z = "d"; document.documentElement.dataset.z = "e"; alert("Seven: " + document.documentElement.dataset.z); alert("Eight: " + document.documentElement.getAttribute("data-z")); </script> You can try it yourself at <http://jsfiddle.net/p6obqavd/>. The above proposal would produce the following alerts: One: "a" (matches, Firefox, Chrome, Safari, IE) Two: undefined ((matches, Firefox, Chrome, Safari, IE) Three: The getItem function (matches Firefox) Four: "b" (matches Firefox, IE) Five: "c" (matches Firefox, Chrome, Safari, IE) Six: undefined (matches Chrome, Safari, IE) Seven: "e" (matches Firefox, Chrome, Safari) Eight: "e" (matches Firefox, Chrome, Safari, IE) Note that the cases in which the new proposal doesn't match IE (cases Seven and Three) seem to be due to it treating dataset as _not_ overridebuiltins while treating sessionStorage as overridebuiltins, unlike every other browser... So modulo that, this proposal actually matches IE exactly. -Boris
Received on Tuesday, 10 February 2015 19:02:12 UTC