Type coersion bug and ID breaking assumption.
Names need to be wrapped in something unique since otherwise two unique siblings
can end up having IDs that are subsets of eachother.
There are to reasons to prefer a `persist` method on the event rather than a static method:
- In open source, people do not have access to `AbstractEvent`.
- This will allow people to persist events without requiring another module.
- This will make refactors easier and more flexible.
This improved browser support for the `wheel` event.
- Try to use `wheel` event (DOM Level 3 Specification).
- Fallback to `mousewheel` event.
- Fallback to `DOMMouseWheel` (older Firefox).
Also, since `wheel` is the standard event name, let's use that in React.
NOTE: The tricky part was detecting if `wheel` is supported for IE9+ because `onwheel` does not exist.
Test Plan:
Execute the following in the console on a page with React:
var React = require('React');
React.renderComponent(React.DOM.div({
style: {
width: 10000,
height: 10000
},
onWheel: function() {
console.log('wheel');
}
}, null), document.body);
Verified that mousewheel events are logged to the console.
Verified in IE8-10, Firefox, Chrome, and Safari.
Summary:
This makes a few changes to React Core, most notably `ReactEventEmitter` and `ReactEventTopLevelCallback`.
- Changed `ReactEventEmitter` to use `EventListener` (instead of `NormalizedEventListener`).
- Deleted `NormalizedEventListener` (which was previously broken).
- Created `getEventTarget` which is used to get a normalized `target` from a native event.
- Changed `ReactEventTopLevelCallback` to use `getEventTarget`.
- Renamed `abstractEventType` to `reactEventType` in `AbstractEvent`.
- Reanmed `abstractTargetID` to `reactTargetID` in `AbstractEvent`.
- Removed `originatingTopLevelEventType` from `AbstractEvent` (unused and violates encapsulation).
- Removed `nativeEvent.target === window` check when refreshing authoritative scroll values (unnecessary).
This actually fixes React because `NormalizedEventListener` does not currently do what it promises to do (which is normalizing `target` on the native event). The `target` event is read-only on native events.
This also revises documentation and adds `@typechecks` to a few modules.
NOTE: Most importantly, this sets the stage for replacing `AbstractEvent` with `ReactEvent` and subclasses, piecemeal.
Summary: Since grepping for `update` and `updateAll` is pretty hard, I had these these functions call through but complain loudly. This noisy call through has been in prod for over a week and I haven't heard any complains, so let's take it out altogether.
ReactEvent should be reserved for the actual object created when an
event fires. The current ReactEvent is more like EventEmitter than
anything (e.g. it sets up delegation, provides methods to attach and
remove listeners).
We need to make sure that deleteAllListeners() is invoked before we call
the superclass's unmountComponent() method or else we will lose
this._rootNodeID.
I also added an invariant and unit test to make sure we do not break
this in the future.
If a React component's render() fatals, it may contaminate
ReactCurrentOwner. This will cause the owner to be set improperly for
the next React.renderComponent() invocation (which causes an owner to be
set when there shouldn't be one).
As it turns out, default values are very useful. This implements
getDefaultProps(), a hook for components to provide prop values when
a prop is not specified by the user.
var container = ...; // some DOM node
React.renderComponent(<div />, container);
React.renderComponent(<span />, container);
This should replace the rendered <div> with a <span>, effectively
reconciling at the root level.
Currently we're mutating _key. Mutation here is fine, but it needs to
be idempotent - which it's not. This is causing some issues.
Instead I reassign the _key every time it passes through a flattening.
This means that it's unique and stable for a single pass through a composite
component. When it's repassed another level, it loses it previous
identity and is rekeyed by it's new location.
For auto-generated keys by index, this actually means it has the same
semantics as before flattening.
For explicit keys, it has the effect that keys need to be unique at
every level. Regardless of how the key got there. Every component needs to ensure
that it doesn't combine keys from two different sources that may collide. This
is also inline with the old semantics but less intuitive in the new model.
flattenChildren was only using key when child.mountInContainerNode
exists, which is defined on ReactCompositeComponent, and not
ReactNativeComponent.
This uses the isValidComponent() fn to see if we should use this key.
Some improvements to how style={{x:y}} is handled in React:
* ignores null styles, rather than setting them.
Codez:
var highlighted = false;
<div style={{color: highlighted ? 'red' : null}} />
Before:
<div style="color:;"></div>
After:
<div></div>
Respects that 0 has no units.
This expects static children as additional arguments to the constructor
and flattens any array arguments one level deep.
Component(props, child1, child2, arrayOfChildren, child3) ->
.props.children = [child1, child2, ...arrayOfChildren, child3]
This can avoid an additional heap allocation for the unflat array.
It allows you to pass nested arrays and objects like you used to. Those
aren't immediately flattened. That makes this a fairly safe change.
Passing a dynamic array without key properties will yield a warning
(once). Might consider throwing later.
Once we change the transpiler to use the new syntax, you'll end up with
a single flat array in normal usage.
This doesn't actually update the JSX transform.
When there isn't any React node in the DOM, unmountAndReleaseReactRootNode
threw an exception because component was undefined. Instead, return whether we
were able to unmount the component.
Test Plan:
With the ballmer-peak example (modified to use input), tested that the
percentage updates when adding or deleting text in the field on Chrome
and IE9. After adding es5-shim and es5-sham to the ballmer-peak page,
IE8 works properly too.
'input' is supported in IE9+ and all other browsers according to
https://developer.mozilla.org/en-US/docs/Web/API/window.oninput
Test Plan:
Modified ballmer-peak example to use onInput instead of onKeyUp and
tested that it works properly on latest Chrome.