Re: WebIDL editorial feedback

Global comment:

s/take no argument/take no arguments/g

> 4.3.13. [TreatNullAs]

> If the [TreatNullAs] extended attribute appears on an attribute or
> operation argument whose type is DOMString,...

I know it isn't mentioned as allowed (and is generally forbidden by
the last line

before the example), but perhaps specific text should be considered for:
[TreatNullAs=EmptyString] attribute DOMString? confused;


interface Dog {
  [TreatNullAs=EmptyString] attribute DOMString? owner;

var d = getDog();
d.owner = null;
d.owner == '';
delete d.owner;
d.owner == null;

I'm not quite sure why someone would want to do that, but I think it's
possible (for

another strange use case, see my combining comment under 4.3.14). And
if you don't

want to let this happen, specific text noting that it isn't allowed is probably


> The following IDL fragment defines an interface that has one attribute
> with the [TreatNullAs] extended attribute,

I don't see this in the following idl blob.

> and one operation with an argument that has the extended attribute:
> interface Dog {
>   attribute DOMString name;
>   attribute DOMString owner;

I think you wanted: [TeatNullAs=EmptyString] attribute DOMString owner;

>   boolean isMemberOfBreed([TreatNullAs=EmptyString] in DOMString breedName);
> };

> An ECMAScript implementation implementing the Dog interface would convert
> a null value assigned to the name property

sure it converts it to something, but what?

> or passed as the argument to the isMemberOfBreed function:
> ECMAScript
> var d = getDog();         // Assume d is a platform object implementing the Dog
>                           // interface.
> = null;            // This assigns the string "null" to the .name
>                           // property.

You aren't using .owner in your example, I'm pretty sure you want to,
and that it

will (once the earlier idl change is made) get a comment that 'This assigns the

string "" to the .owner property

> d.isMemberOfBreed(null);  // This passes the string "" to the isMemberOfBreed
>                           // function.

> 4.3.14. [TreatUndefinedAs]

> The [TreatUndefinedAs] extended attribute MUST take an identifier:
> either EmptyString or Null.

Can I have:
[TreatUndefinedAs=Null,TreatNullAs=EmptyString] attribute DOMString? confused;
and is its processing model different than:
[TreatNullAs=EmptyString,TreatUndefinedAs=Null] attribute DOMString? usedconf;

> The following IDL fragment defines an interface that has one attribute with
> the [TreatUndefinedAs] extended attribute,

The same comments for Dog apply to Cat...

> and one operation with an argument that has the extended attribute:

> 4.3.15. [Unforgeable]

> If the [Unforgeable] extended attribute appears on a read only attribute,
> it indicates that the attribute will be reflected as an ECMAScript property
> in a way that means its behavior cannot be modified and that performing a
> property lookup on the object will always result in the attribute’s property
> value being returned.

This doesn't say that a forging getter isn't fired first before returning the

unforged value.

> The [Unforgeable] extended attribute MUST NOT appear on anything other
> than a read only attribute.

While this is obvious, an example of an invalid instance of this would be


> It also MUST NOT appear on an attribute on interface A if there exists
> another interface B that defines any interface member with the same identifier,

An example of this would be easy to provide.

> and which either has A as an inherited interface

I gave up trying to figure out directionality here, please provide an
invalid example

 for this case.

> or which is a consequential interface of A.

I suspect this would be easier for me to puzzle out, but since I'm
already asking for

examples, one for this would be appreciated.

And yes, I know that someone has to make a test case for each testable
assertion, on

the bright side, by doing this, you're making their life easier :).

> An ECMAScript implementation of the interface will expose the username

I'm not sure if this is supposed to be `ECMAScript implementation of
the interface`

or just An ECMAScript implementation of WebIDL for an object implementing this

interface ...

To me, the current text implies that if I write:

function MySystem(){}

But normally we're talking about Host/System objects and not
ECMAScript implemented


> attribute as a non-configurable property on the object itself:

> 4.5. Interfaces

> The name of the property is the identifier of the interface,
> and its value is an object called the interface object,

> which provides access to the constants, attributes and operations defined
> on the interface.

This doesn't say how it does this for magic operations.

> The property has the attributes { [[Writable]]: true,
> [[Enumerable]]: false, [[Configurable]]: true }.

I found this statement to be too far from the correct relevant
`property` (which was

the one for the interface, and not for properties of that interface).
I think the

simplest solution is to remove the 'which provides access...' bit.
It's made clear

enough by:

> The characteristics of an interface object is described in section 4.5.1 below.


> The characteristics of a named constructor is described in section 4.5.2 below


This is really:

s/(The characteristics .*) is (.*)/$1 are $2/g;

--in case i forget to tag some other instances...

> 4.5.1. Interface object

> The interface object also has properties that correspond to the
> constants and static operations defined on that interface, as
> described in sections 4.5.4 and 4.5.6 below.

This seemed to conflict with the earlier statement:
| which provides access to the constants, attributes and operations
| defined on the interface.

It's technically correct because some things are on <interface object>
and some are

on <interface object prototype>, but it's confusing.

> This object has properties that correspond to the attributes
> and operations defined on the interface, and is described in
> more detail in section 4.5.3 below.

This doesn't match the style of the previous sections <The
characteristics of...>

> 7-1-2. Depending on the value of argi:
> \-> A platform array object
>     Add to types the object type and an array type that corresponds
> to the type of the IDL array the platform array object represents.

s/the platform/that the platform/

interface A {}
interface B : A {}
interface C {
  void d(A[] a);
  attribute B[] e;

c = new C;

I don't think that this is handled properly (compare with the next
case which tries

to handle inheritance).

> \-> Any other platform object
>     Add to types the object type and an interface type for all
> interfaces that are equal to, or inherit from, at least one of
> the interfaces that the platform object implements.

interface A {};
interface B : A {};
C implements A;

c instanceof C

Call step 7-1-2 with `c`, I think that this prose says that 'B' should
be added to

the list. I don't think that's wanted behavior.

> \-> A native Array object
>     (That is, a native object whose [[Class]] is "Array".)
> Add to types the object type, an interface type for each
> interface annotated with the [Callback] extended attribute
> and all array types.

This puzzles me, I was wondering about [PlatformObject(),
PlatformObject2()]. I'm

also unclear as to why [Callback] is being considered here.

Also note that you use 'for all' and 'for each' in 7-1-2
inconsistently, I think I

expected 'for each' in all cases (although some prose may need to be
adjusted to get

'for each' to fit correctly).

> 7-1-2-4. If there exists an entry in candidates with type list t
> where ti ∈ types, then remove from R all entries with type list
> t where ti ∉ types.

> 8. Return R.

I don't think 'R' is defined in this process, you do have an 'S' from
steps 1, 2, and

3, and you also have 'candidates' (from step 2).

> If S contains more than one entry, then the constructor call is
> ambiguous. Remove all but one entry from S according to rules
> specified in the description of interface I, or arbitrarily if
> no such rules exist.

What do I do when rules exist and they're incomplete/ambiguous? :)

> 7. Let x be the extended attribute that represents the constructor
> and t0..m−1 be the type list of the single entry in S.

You switched to 'm' from 'n', is there a need for this? Shouldn't the
resulting list

in S actually have the same number of arguments as the input to the algorithm?

> 8. Let idlarg0..m−1 be a list of IDL values, where idlargi is the
> result of converting argi to an IDL value. These conversions
> MUST be done in order from arg0 to argm−1.

Note that here you're indexing on 0..m-1 for input 0..n-1.

> 9. Let R be the result of performing the actions listed in the
> description of the constructor represented by x with idlarg0..m−1
> as the argument values.

This process does define `R`!

> If the internal [[Call]] method of the interface object returns
> normally, then it MUST return an object that implements interface I.

And if it somehow decides to do something stupid? :)
(obviously, doing that is a violation of the spec, but violations happen...)

> 4.5.4. Constants

> For each constant defined on an interface A, there MUST be a
> corresponding property on the interface object, if it exists,

I expected any text relating to <interface-prototype-object> getting a
constant to be

here, not later. You can add the special stuff later and still have
the general bit

for <interface-prototype-object> here

> if the identifier of the constant is not “prototype”. The property
> has the following characteristics:

>    The name of the property is the identifier of the constant.
>    The value of the property is that which is obtained by converting the constant’s

IDL value to an ECMAScript value.
>    The property has attributes { [[Writable]]: false, [[Enumerable]]: true,

[[Configurable]]: false }.

> In addition, a property with the same characteristics MUST exist
> on the interface prototype object, unless:

>     the identifier of the constant is “constructor”; or
>     the identifier of the constant is “toString” and the interface
> has a stringifier.

Questions that came up:

[Constructor()] interface B { const short _constructor = 6; }

other than being mostly stupid, that more or less does something?

b=new B; b.constructor===6, b.prototype.constructor===B ?

[Constructor()] interface C { const short _prototype = 3; }
c=new C; c.prototype != 3; c.prototype.prototype === 3 ?

Is this what we want?

Temporary asside to a much earlier section because I needed to try to
apply it in

order to make the preceding comments.
> For all of these constructs, the identifier is the value of the
> identifier token with any single leading U+005F LOW LINE ("_")
> character removed.

It would help if the word 'underscore' was listed in this sentence,
it's perfectly

acceptable to have it in a parenthetical.

Also, it would be helpful if the term 'unescape' was included in this sentence.

Currently underscore and unescape *only* appear here (in a Note):

> Note that while the second attribute on the TextField interface
> need not have been escaped with an underscore (because “value”
> is not a keyword in the IDL grammar), it is still unescaped to
> obtain the attribute’s identifier.
> 4.5.5. Attributes
> For each attribute defined on the interface, there MUST be a
> corresponding property either on the interface prototype object
> or on every object that implements the interface, unless:

This blob doesn't do anything for 'prototype', which is odd. I'm pretty sure:
interface D { readonly attribute short _prototype; } and
interface E { [Unforgeable] readonly attribute short _prototype; }
would be unfortunate. See exclusions:

>    the identifier of the attribute is “constructor”; or
>    the identifier of the attribute is “toString” and the interface
> has a stringifier.

> The attribute setter is undefined if the attribute is declared
> readonly and has neither a [PutForwards] nor a [Replaceable]
> extended attribute declared on it. Otherwise, it is a Function
> object whose behavior when invoked is as follows:
> 3. Let V be the value of the first argument passed to the Function,
> or undefined is no arguments were passed.

> 6. Let idlValue be the result of converting V to an IDL value.

I found that this phrasing didn't clearly indicate that it was applying

<converting...> for the relevant attribute/argument/whatever, which
made me worry

that it could skip any [TreatUndefinedAs=...] decorators. I think "... for this

attribute/argument" would address my concerns.

> 4.5.6. Operations
> The characteristics of such a corresponding property are as follows:
> If O is not a platform object that implements interface I, throw a TypeError.

Can't O be a user object that implements [Callback] interface I?

At least for gecko, when you pass in a user object to a system thingy,
you can later

get back your object as something that looks like a platform object,
but is really

your user object. For the purposes of security checks on later
interfaces, you want

it to fail any check that does not have [Callback], but you should
still be able to

generally make calls to it...

--- this is the first time i'm bringing this up, but it's possible that it has

ramifications throughout the spec.

> 6. If S contains more than one entry, then the operation call is
> ambiguous. Remove all but one entry from S according to rules
> specified in the description of interface I, or arbitrarily if no
> such rules exist.

This blob (and th efollowing statement) exists elsewhere in the
document and I've

commented about it earlier in this post.

> If there would still be conflicting property definitions, then it
> is undefined which consequential interface’s interface member that
> property on A’s interface prototype object corresponds to.

I found this to be hard to read..

Would the following be ok:

s/it.*to/the correspondence to a consequential interface for the
property on A's

interface prototype is undefined/

I'll continue from 4.7 Platform objects implementing interfaces tomorrow, sorry

Received on Wednesday, 13 July 2011 22:41:01 UTC