Commit Graph

41 Commits

Author SHA1 Message Date
Sebastian Markbage e3f95ea293 Hot fix cyclic dependency
We accidentally created an unfortunate cyclic dependency because of the
auto-wrapper hack that uses ReactClass.

Making it injected instead.
2015-02-02 23:55:34 -08:00
Rick Beerendonk 3e0750a4ad Update copyright headers for 2015 2015-01-31 20:18:25 +01:00
Sebastian Markbage 766a79c695 Move component class instantiation into ReactCompositeComponent
We need to move instantiation into the mount phase for context purposes.

To do this I moved the shallow rendering stuff into ReactTestUtils and
reused more of the existing code for it by instantiating a noop child.

Everywhere we refer to the "type" we should pass it to ReactNativeComponent
to resolve any string value into the underlying composite.
2015-01-23 10:09:45 -08:00
Paul O’Shannessy df64a67b7f codemod "use strict" to 'use strict' for better linting 2015-01-13 15:26:32 -08:00
Sebastian Markbage 9c3e2d833d Wrap every DOM node in a Composite Component
...unless they already have a wrapper. Also, add tagName to every wrapper.

This ensures that refs are consistent. They always look like composite
components. This effectively hides the internal implementation details of
real DOM components since you can no longer get a ref to one.

In the future we might want to drop this wrapper and have refs refer
directly to the DOM node.

I currently use a hacky way of auto-wrapping inside of ReactNativeComponent
so that any given string can be wrapped. Better suggestions are welcome.
2014-11-16 10:32:46 -08:00
Ben Alpert 230115da92 Make ReactTextComponent properly injectable
ReactTextComponent's implementation is DOM-specific; instead of flattenChildren creating the ReactTextComponent instances, ReactNativeComponent now takes care of having ReactTextComponent injected and creating the component instance. I also renamed ReactTextComponent to ReactDOMTextComponent and moved it to browser/ui/ where it belongs. ReactDOMTextComponent no longer inherits directly from ReactComponent and instead implements construct and {mount,receive,unmount}Component directly.

This diff removes `ReactTestUtils.isTextComponent` which should have previously never returned true when using public APIs.

Test Plan: jest, use ballmer-peak example.
2014-11-15 12:30:42 -08:00
Alexandre Gaudencio 6379342b71 Trailing commas break old IE versions 2014-11-03 02:54:23 +01:00
Sebastian Markbåge cb50a8698b Remove unrelated comment
This is no longer unwrapping a legacy factory (which are gone).
2014-10-31 12:39:38 -07:00
Sebastian Markbage 9b36b04d75 Drop internal uses of .type on the class 2014-10-28 15:08:52 -07:00
Sebastian Markbage 8210beeef4 Hide Object.assign polyfill behind a module
Because the JS community's polyfilling infrastructure sucks and we'll
have to fix it for them before we require this.

JSX spread uses React.__spread
(which might get special behavior for key/ref, not sure yet)

This never uses the native implementation and throws for prototype chains.
Once the native implementations are faster, we'll start using them.
2014-10-16 09:21:10 -07:00
Paul O’Shannessy dcf415c2b9 BSD + PATENTS 2014-10-10 13:34:07 -07:00
Sebastian Markbage 096360db03 Use Object.assign instead of merge, mergeInto, mixInto and copyProperties
This makes it easier to contribute without having to learn a bunch of
slightly different helpers and remember their slightly different
signatures and semantics.

We'll probably start using ES7 spread properties instead of merge in the
future when at least one more transpiler supports it.
2014-10-08 11:32:40 -07:00
Sebastian Markbage 3aaccd2dc9 Use strings as the type for DOM elements
This makes ReactDOM a simple helper for creating ReactElements with the string tag as the type. The actual class is internal and created by instantiateReactComponent. Configurable using injection.

There's not a separate class for each tag. There's just a generic ReactDOMComponent which could take any tag name.

Invididual tags can be wrapped. When wrapping happens you can return the same tag again. If the wrapper returns the same string, then we fall back to the generic component. This avoids recursion in a single level wrapper.
2014-10-02 23:05:11 -07:00
Paul O'Shannessy f43449d333 ReactNativeComponent -> ReactDOMComponent
In an effort to break the DOMy parts of React away from the non-DOMy parts, I'm renaming this.
2013-10-01 16:31:32 -07:00
Paul O’Shannessy f20626f17a Merge pull request #378 from spicyj/html-reconciliation
Fix reconciling when switching to/from innerHTML
2013-10-01 13:38:08 -07:00
Pete Hunt 58de758a32 Sort batched updates by owner depth
If we reconcile components higher in the hierarchy they will likely reconcile components lower in the
hierarchy. If we sort by depth then when we reach those components there will be no more pending state or
props and it will no op.
2013-10-01 13:33:12 -07:00
Ben Alpert 3ca507d73f Fix reconciling when switching to/from innerHTML
There's no way that this can work if _updateDOMChildren doesn't know about dangerouslySetInnerHTML, so tell it.

Fixes #377.
2013-09-27 16:22:46 -07:00
Danny Ben-David fce57abeca Benchmarking tool for React application performance
ReactAppPerf wraps core methods and logs info from them; there's no real
UI at this point
2013-08-23 14:05:11 -07:00
Tim Yung 5ef3c1b09b Fix Reconciling Components to Content
This fixes a reconciliation bug introduced by adffa9b0f4.

The new unit test case exhibits the bug. When a component that has rendered child components is updated to render inline text, we usually:

 # Unmount and remove all child components.
 # Set the new inline text content.

However, with batched child operations, we do not **remove all child components** until later. The current implementation will set the inline text content and blow away those nodes, causing a fatal when `ReactMultiChild` later tries to find and remove those nodes.

This fixes the bug by ensuring that text content changes are also enqueued.
2013-07-29 16:15:30 -07:00
Tim Yung adffa9b0f4 Batch Child Markup Generation
Setting `innerHTML` is slow: http://jsperf.com/react-child-creation/2

This reduces the number of times we set `innerHTML` by batching markup generation in a component tree.

As usual, I cleaned up the `ReactMultiChild` module significantly.

== Children Reconciliation ==

When a `ReactNativeComponent` reconciles, it compares currently rendered children, `prevChildren`, with the new children, `nextChildren`. It figures out the shortest series of updates required to render `nextChildren` where each update is one of:

 - Create nodes for a new child and insert it at an index.
 - Update an existing node and, if necessary, move it to an index.
 - Remove an existing node.

This serializable series of updates is sent to `ReactDOMIDOperations` where the actions are actually acted on.

== Problem ==

There are two problems:

 # When a `ReactNativeComponent` renders new children, it sets `innerHTML` once for each contiguous set of children.
 # Each `ReactNativeComponent` renders its children in isolation, so two components that both render new children will do so separately.

For example, consider the following update:

  React.renderComponent(<div><p><span /></p><p><span /></p></div>, ...);
  React.renderComponent(<div><p><img /><span /><img /></p><p><img /><span /><img /></p></div>, ...);

This will trigger setting `innerHTML` four times.

== Solution ==

Instead of enqueuing the series of updates per component, this diff changes `ReactMultiChild` to enqueue updates per component tree (which works by counting recursive calls to `updateChildren`). Once all updates in the tree are accounted for, we render all markup using a single `innerHTML` set.
2013-07-26 12:48:07 -07:00
Jordan Walke 2ee66262db Remove circular dependencies in React Core.
There is a circular dependency between `ReactID`, `ReactMount` and
`ReactInstanceHandles`. Ben and I talked about this today. It seems like the
simplest solution is to consolidate a lot of the code that Ben recently wrote
into `ReactMount`. We can later find ways to trim code out of this module
without causing circular deps.
2013-07-24 17:40:57 -07:00
Tim Yung 83a840656c Fix Markup Rendering in IE
This fixes known browser bugs with rendering markup using `innerHTML` in IE ([[http://support.microsoft.com/kb/276228 | here is an example of one]]).

This is a subset of what `HTML` (and jQuery) does, and we should eventually consider pulling it out into a separate module to reduce code duplication. For now, this is the minimal set of changes needed to unbreak React in production.

We can afford to use a subset of what `HTML` does because we have the luxury of knowing that the markup is generated sanely with proper closing tags, etc.
2013-07-16 11:37:26 -07:00
Tim Yung 7b68fcd408 Short-circuit updatePropertyByID
When `ReactNativeComponent` updates, it calls `updatePropertyByID` in `ReactDOMIDOperations` which calls `DOMPropertyOperations`. However, in `ReactDOMIDOperations`, we will lookup the node for an ID using `ReactID.getNode`. This wastes time looking for nodes when we may not need to ever update it (e.g. `children`).

This changes `ReactNativeComponent` to bail out sooner.
2013-07-10 15:04:23 -07:00
Ben Alpert d9e99d4688 Batch together calls to setState, setProps, etc
The end of ReactUpdates-test.js is probably most illuminating for seeing how this works.
2013-07-02 00:04:50 -07:00
Paul O’Shannessy f39a0f8e40 Merge branch 'no-content' of git://github.com/spicyj/react into spicyj-no-content
Conflicts:
	src/core/ReactNativeComponent.js
2013-06-28 16:42:59 -07:00
CommitSyncScript 15272f30f4 Don't keep the HTML escaped ID internally, only in HTML generation
A dynamic value can be provided as a key to a child. Either as part of an object
or key property. This becomes part of the component's ID.

We have to be careful to escape this key before inserting it into the DOM since
it could become a vulnerability. We fixed this by escaping just the keys.

However, the current implementation breaks when you used escaped keys. The
internal value is escaped and the value used by getAttributeNode and
getElementById are both unescaped.

This fixes that by keeping the unescaped value internally but escaping it right
before the HTML is generated (like any other attribute).

This is important since business logic IDs (that should be used as keys)
contains characters that need to be escaped.
2013-06-28 16:35:45 -07:00
yungsters 43358157cf Merge branch 'textarea-update-value' of git://github.com/spicyj/react
Conflicts:
	src/core/ReactDefaultInjection.js
2013-06-28 14:30:47 -07:00
Ben Alpert e998041229 Remove content property
Fixes #119.
2013-06-28 11:14:59 -07:00
CommitSyncScript a9b024330c Make @typechecks static-only 2013-06-25 14:01:15 -07:00
CommitSyncScript c1886c6513 Use ReactID.ATTR_NAME as the React-specific ID attribute name.
Another step in the plan towards making `ReactID.ATTR_NAME` the central
source of truth regarding the React-specific ID attribute name.
2013-06-24 18:28:29 -07:00
Ben Alpert 0493b27222 Don't update value or textContent unnecessarily
_updateDOMChildren was already updating textContent so we don't need to
do it in _updateDOMProperties. Additionally, don't update .value if
it'll be a noop because it has side-effects (like moving the cursor) in
some browsers (like IE 9).

Refactor tests to be a bit more robust and a bit cleaner too.
2013-06-18 23:31:15 -07:00
CommitSyncScript 770ec5946a Unbreaking falsy check on style values
Style values can be the number zero which is an actual value. So we check for
null instead. The empty string case falls through.
2013-06-13 17:49:04 -07:00
CommitSyncScript b525a0c061 Unnecessary this._rootNodeID Invariant
Summary: This invariant is unnecessary because `ReactComponent.Mixin.receiveProps` already asserts that this component is mounted. (Being mounted guarantees you have a DOM ID, look at `ReactComponent` and see when `this._rootNodeID` is mutated.)
2013-06-13 17:48:09 -07:00
CommitSyncScript 01511ea557 Remove Unnecessary DOM Mutations
This fixes an edge case that can cause unnecessary mutations in the DOM. Namely, if a prop is falsey, it will get touched on every update by reconciliation. See unit test.
2013-06-13 17:39:47 -07:00
CommitSyncScript 802241a660 Cleanup style Prop Reconciliation
This cleans up the reconcilation path when adding a `style` prop (going from a falsey or no `style` to having one) by reducing the need for an object allocation and for-loop.
2013-06-13 17:39:23 -07:00
Ben Alpert fdc6beed1a Fix nit and comment 2013-06-11 19:53:24 -07:00
Ben Alpert 731aa8ead1 internalPropNames isn't necessary, so remove it
Perhaps we'll bring it back as a future perf optimization if that
appears useful.
2013-06-11 19:02:35 -07:00
Ben Alpert 705ce56694 Correctly remove attributes when deleting props
The most obvious manifestation of this bug is visible here:
http://jsfiddle.net/spicyj/zzGas/. In short, when props are removed from a
component, the underlying HTML element doesn't have the attribute
removed.

This change should fix it, but unfortunately it (presumably) makes
_updateDOMProperties a bit slower.
2013-06-11 16:46:10 -07:00
CommitSyncScript 9d1055b3d2 Rename ReactEvent to ReactEventEmitter
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).
2013-06-06 14:29:45 -07:00
CommitSyncScript 9965b6b9dd Fix Listener Cleanup on Unmount
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.
2013-06-06 14:29:44 -07:00
Paul O’Shannessy 75897c2dcd Initial public release 2013-05-29 12:54:02 -07:00