- 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