Executive summary: I propose amending the documentation as follows:
"When a state contains an attribute with the same name as in the
parent node, the attribute will take on the value specified in the
state when the state is applied. It is an error for the state to
specify any other properties of the attribute that would conflict with
the parent. When the state is removed, the value of the attribute
will remain the value at the time the state is removed."
---
Gory details: if the parent value was a constraint, it will be removed
when the state is applied and replaced with the state value. If the
state value is a constraint, it will be removed when the state is
removed.
If we need to support this feature for _method_ attributes going
forward, we'll have some work to do. Does anyone feel this is
necessary?
Note that (for better or worse) _handler_ attributes do not collide in
this way, since it is perfectly legal to have many handlers with the
same `name` -- the name in a handler attribute is the event that it
handles, not the name of the handler.
More comments interspersed below...
On 2008-02-21, at 11:16 EST, David Temkin wrote:
The docs say:
Everything within a <state> tag acts as if it were written inside
the parent when the state is applied. States can contain
attributes, methods, and other nodes.
The docs are silent on what happens when the state is removed?
This is a clean conceptual model, IMHO. No exceptions.
I would expect elements within the state to be added/removed when
the state is applied/removed. I would not expect elements that are
not specified within in the state (e.g., other attributes, other
methods, other views) to be affected by apply/remove of the state.
(That's what enables what Sarah calls "side effects" below).
The question at hand is: what if the parent _and_ the state specify
the same element? If you take your doc quote literally, this would be
an error. You are not allowed to declare the same attribute twice.
But everyone relies on this being permitted, usually to apply a
constraint to an attribute with a state.
The bug I just fixed was if you had a constraint in the parent and
applied a fixed value in the state. The state has to remove the
parent constraint when applied or you don't get what you want.
I thought it would also be more correct to put those removed
constraints back when the state is removed, but that breaks dragstate
and resizestate (not just in the debugger -- Amazon broke too. There
are probably others. So I am taking the re-applying of removed
constraints back out).
I *am* surprised that methods added when a state is applied aren't
removed when the state is removed -- if that is in fact what Sarah
is saying below. That sounds like a bug.
Her example is another case of the attribute (in this case a method
attribute) being defined in both the parent and the state. When the
state is applied, the method attribute gets a new 'value' (the method
implementation), and when the state is removed, that new value
sticks. You don't get two methods with the same name. If the method
had a different name than any parent method, it would be added and
removed. But ans Henry points out, adding and removing methods is
problematic for JS2 runtimes.
Regarding the proximate issue mentioned by Tucker: Sounds like a bug
in the SWF debugger, and not a general problem with dragstate.
Nope. Many things break if I restore constraints that were removed by
the state.
The comment on LzState#remove says:
/**
* Removes the constraints and views made when the state was
applied. This
* method does not currently restore the previous values of any
attributes that
* were changed by the state
*/
'does not currently' made me think that was a shortcoming, but it
appears it is a feature instead!