@samitouri / QOS-React-2 / commits / ee21a604f3
Fork 0

The library for web and native user interfaces.

Delete files that accidentally got merged in

ಠ_ಠ

Paul O’Shannessy committed Jun 28, 2013 at 14:52 UTC ee21a604f31020fbaa898a4d0d61dc487198ce82
148 files changed -21441
React/$.js deleted
-46
@@ -1,46 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule $
17 - */
18 -
19 -var ge = require("./ge");
20 -
21 -/**
22 - * Find a node by ID.
23 - *
24 - * If your application code depends on the existence of the element, use $,
25 - * which will throw if the element doesn't exist.
26 - *
27 - * If you're not sure whether or not the element exists, use ge instead, and
28 - * manually check for the element's existence in your application code.
29 - */
30 -function $(arg) {
31 - var element = ge(arg);
32 - if (!element) {
33 - if (typeof arg == 'undefined') {
34 - arg = 'undefined';
35 - } else if (arg === null) {
36 - arg = 'null';
37 - }
38 - throw new Error(
39 - 'Tried to get element "' + arg.toString() + '" but it is not present ' +
40 - 'on the page.'
41 - );
42 - }
43 - return element;
44 -}
45 -
46 -module.exports = $;
React/AbstractEvent.js deleted
-276
@@ -1,276 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule AbstractEvent
17 - */
18 -
19 -"use strict";
20 -
21 -var BrowserEnv = require("./BrowserEnv");
22 -var PooledClass = require("./PooledClass");
23 -var TouchEventUtils = require("./TouchEventUtils");
24 -
25 -var throwIf = require("./throwIf");
26 -
27 -
28 -// Only accessed in __DEV__
29 -var CLONE_TYPE_ERR;
30 -if (true) {
31 - CLONE_TYPE_ERR =
32 - 'You may only clone instances of AbstractEvent for ' +
33 - 'persistent references. Check yourself.';
34 -}
35 -var MAX_POOL_SIZE = 20;
36 -
37 -/**
38 - * AbstractEvent copy constructor. @see `PooledClass`. Provides a single place
39 - * to define all cross browser normalization of DOM events. Does not attempt to
40 - * extend a native event, rather creates a completely new object that has a
41 - * reference to the nativeEvent through .nativeEvent member. The property .data
42 - * should hold all data that is extracted from the event in a cross browser
43 - * manner. Application code should use the data field when possible, not the
44 - * unreliable native event.
45 - */
46 -function AbstractEvent(
47 - abstractEventType,
48 - abstractTargetID, // Allows the abstract target to differ from native.
49 - originatingTopLevelEventType,
50 - nativeEvent,
51 - data) {
52 - this.type = abstractEventType;
53 - this.abstractTargetID = abstractTargetID || '';
54 - this.originatingTopLevelEventType = originatingTopLevelEventType;
55 - this.nativeEvent = nativeEvent;
56 - this.data = data;
57 - // TODO: Deprecate storing target - doesn't always make sense for some types
58 - this.target = nativeEvent && nativeEvent.target;
59 -
60 - /**
61 - * As a performance optimization, we tag the existing event with the listeners
62 - * (or listener [singular] if only one). This avoids having to package up an
63 - * abstract event along with the set of listeners into a wrapping "dispatch"
64 - * object. No one should ever read this property except event system and
65 - * plugin/dispatcher code. We also tag the abstract event with a parallel
66 - * ID array. _dispatchListeners[i] is being dispatched to a DOM node at ID
67 - * _dispatchIDs[i]. The lengths should never, ever, ever be different.
68 - */
69 - this._dispatchListeners = null;
70 - this._dispatchIDs = null;
71 -
72 - this.isPropagationStopped = false;
73 -}
74 -
75 -/** `PooledClass` looks for this. */
76 -AbstractEvent.poolSize = MAX_POOL_SIZE;
77 -
78 -/**
79 - * `PooledClass` looks for `destructor` on each instance it releases. We need to
80 - * ensure that we remove all references to listeners which could trap large
81 - * amounts of memory in their closures.
82 - */
83 -AbstractEvent.prototype.destructor = function() {
84 - this.target = null;
85 - this._dispatchListeners = null;
86 - this._dispatchIDs = null;
87 -};
88 -
89 -/**
90 - * Enhance the `AbstractEvent` class to have pooling abilities. We instruct
91 - * `PooledClass` that our copy constructor accepts five arguments (this is just
92 - * a performance optimization). These objects are instantiated frequently.
93 - */
94 -PooledClass.addPoolingTo(AbstractEvent, PooledClass.fiveArgumentPooler);
95 -
96 -AbstractEvent.prototype.stopPropagation = function() {
97 - this.isPropagationStopped = true;
98 - if (this.nativeEvent.stopPropagation) {
99 - this.nativeEvent.stopPropagation();
100 - }
101 - // IE8 only understands cancelBubble, not stopPropagation().
102 - this.nativeEvent.cancelBubble = true;
103 -};
104 -
105 -AbstractEvent.prototype.preventDefault = function() {
106 - AbstractEvent.preventDefaultOnNativeEvent(this.nativeEvent);
107 -};
108 -
109 -/**
110 - * Utility function for preventing default in cross browser manner.
111 - */
112 -AbstractEvent.preventDefaultOnNativeEvent = function(nativeEvent) {
113 - if (nativeEvent.preventDefault) {
114 - nativeEvent.preventDefault();
115 - } else {
116 - nativeEvent.returnValue = false;
117 - }
118 -};
119 -
120 -/**
121 - * @param {Element} target The target element.
122 - */
123 -AbstractEvent.normalizeScrollDataFromTarget = function(target) {
124 - return {
125 - scrollTop: target.scrollTop,
126 - scrollLeft: target.scrollLeft,
127 - clientWidth: target.clientWidth,
128 - clientHeight: target.clientHeight,
129 - scrollHeight: target.scrollHeight,
130 - scrollWidth: target.scrollWidth
131 - };
132 -};
133 -
134 -/*
135 - * There are some normalizations that need to happen for various browsers. In
136 - * addition to replacing the general event fixing with a framework such as
137 - * jquery, we need to normalize mouse events here. Code below is mostly borrowed
138 - * from: jScrollPane/script/jquery.mousewheel.js
139 - */
140 -AbstractEvent.normalizeMouseWheelData = function(nativeEvent) {
141 - var delta = 0;
142 - var deltaX = 0;
143 - var deltaY = 0;
144 -
145 - /* traditional scroll wheel data */
146 - if ( nativeEvent.wheelDelta ) { delta = nativeEvent.wheelDelta/120; }
147 - if ( nativeEvent.detail ) { delta = -nativeEvent.detail/3; }
148 -
149 - /* Multidimensional scroll (touchpads) with deltas */
150 - deltaY = delta;
151 -
152 - /* Gecko based browsers */
153 - if (nativeEvent.axis !== undefined &&
154 - nativeEvent.axis === nativeEvent.HORIZONTAL_AXIS ) {
155 - deltaY = 0;
156 - deltaX = -delta;
157 - }
158 -
159 - /* Webkit based browsers */
160 - if (nativeEvent.wheelDeltaY !== undefined ) {
161 - deltaY = nativeEvent.wheelDeltaY/120;
162 - }
163 - if (nativeEvent.wheelDeltaX !== undefined ) {
164 - deltaX = -nativeEvent.wheelDeltaX/120;
165 - }
166 -
167 - return { delta: delta, deltaX: deltaX, deltaY: deltaY };
168 -};
169 -
170 -/**
171 - * I <3 Quirksmode.org:
172 - * http://www.quirksmode.org/js/events_properties.html
173 - */
174 -AbstractEvent.isNativeClickEventRightClick = function(nativeEvent) {
175 - return nativeEvent.which ? nativeEvent.which === 3 :
176 - nativeEvent.button ? nativeEvent.button === 2 :
177 - false;
178 -};
179 -
180 -AbstractEvent.normalizePointerData = function(nativeEvent) {
181 - return {
182 - globalX: AbstractEvent.eventPageX(nativeEvent),
183 - globalY: AbstractEvent.eventPageY(nativeEvent),
184 - rightMouseButton:
185 - AbstractEvent.isNativeClickEventRightClick(nativeEvent)
186 - };
187 -};
188 -
189 -AbstractEvent.normalizeDragEventData =
190 - function(nativeEvent, globalX, globalY, startX, startY) {
191 - return {
192 - globalX: globalX,
193 - globalY: globalY,
194 - startX: startX,
195 - startY: startY
196 - };
197 - };
198 -
199 -/**
200 - * Warning: It is possible to move your finger on a touch surface, yet not
201 - * effect the `eventPageX/Y` because the touch had caused a scroll that
202 - * compensated for your movement. To track movements across the page, prevent
203 - * default to avoid scrolling, and control scrolling in javascript.
204 - */
205 -
206 -/**
207 - * Gets the exact position of a touch/mouse event on the page with respect to
208 - * the document body. The only reason why this method is needed instead of using
209 - * `TouchEventUtils.extractSingleTouch` is to support IE8-. Mouse events in all
210 - * browsers except IE8- contain a pageY. IE8 and below require clientY
211 - * computation:
212 - *
213 - * @param {Event} nativeEvent Native event, possibly touch or mouse.
214 - * @return {number} Coordinate with respect to document body.
215 - */
216 -AbstractEvent.eventPageY = function(nativeEvent) {
217 - var singleTouch = TouchEventUtils.extractSingleTouch(nativeEvent);
218 - if (singleTouch) {
219 - return singleTouch.pageY;
220 - } else if (typeof nativeEvent.pageY !== 'undefined') {
221 - return nativeEvent.pageY;
222 - } else {
223 - return nativeEvent.clientY + BrowserEnv.currentPageScrollTop;
224 - }
225 -};
226 -
227 -/**
228 - * @see `AbstractEvent.eventPageY`.
229 - *
230 - * @param {Event} nativeEvent Native event, possibly touch or mouse.
231 - * @return {number} Coordinate with respect to document body.
232 - */
233 -AbstractEvent.eventPageX = function(nativeEvent) {
234 - var singleTouch = TouchEventUtils.extractSingleTouch(nativeEvent);
235 - if (singleTouch) {
236 - return singleTouch.pageX;
237 - } else if (typeof nativeEvent.pageX !== 'undefined') {
238 - return nativeEvent.pageX;
239 - } else {
240 - return nativeEvent.clientX + BrowserEnv.currentPageScrollLeft;
241 - }
242 -};
243 -
244 -/**
245 - * A semantic API around cloning an event for use in another event loop. We
246 - * clear out all dispatched `AbstractEvent`s after each event loop, adding them
247 - * back into the pool. This allows a way to hold onto a reference that won't be
248 - * added back into the pool. Please note that `AbstractEvent.nativeEvent` is
249 - * *not* cloned and you will run into problems in IE if you assume that it will
250 - * be! The moral of that story is to always normalize any data you need into the
251 - * `.data` field. The data field is not cloned either, but there won't be any
252 - * issues related to use of `.data` in a future event cycle so long as no part
253 - * of your application mutates it. We don't clone the private fields because
254 - * your application should never be accessing them.
255 - *
256 - * - TODO: In __DEV__ when "releasing" events, don't put them back into the
257 - * pool. Instead add ES5 getters on all their fields that throw errors so you
258 - * can detect any application that's hanging onto events and reusing them.
259 - * In prod - we can put them back into the pool for reuse.
260 - */
261 -AbstractEvent.persistentCloneOf = function(abstractEvent) {
262 - if (true) {
263 - throwIf(!(abstractEvent instanceof AbstractEvent), CLONE_TYPE_ERR);
264 - }
265 - return new AbstractEvent(
266 - abstractEvent.type,
267 - abstractEvent.abstractTargetID,
268 - abstractEvent.originatingTopLevelEventType,
269 - abstractEvent.nativeEvent,
270 - abstractEvent.data,
271 - abstractEvent.target
272 - );
273 -};
274 -
275 -module.exports = AbstractEvent;
276 -
React/AnalyticsEventPluginFactory.js deleted
-225
@@ -1,225 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule AnalyticsEventPluginFactory
17 - *
18 - * This module provides a factory method to create the AnalyticsEventPlugin that
19 - * can be used to track the usage of React components that are of interest to
20 - * the user.
21 - *
22 - * In order to enable a component for analytics tracking, you need to specify
23 - * two additional attributes to the component when you describe the structure of
24 - * your component in the render() method:
25 - *
26 - * 1. 'data-analytics-id': This represents a unique ID that the analytics module
27 - * will use to identify this component in all the analytics data. Note that
28 - * this is independent of the ref or the DOM id of the element. Over the
29 - * lifetime of the product, even if the component id or ref needs to be
30 - * changed, as long as you can ensure the analytics ID doesnt change, the
31 - * historical data can be correlated. Also note that React does NOT do
32 - * anything to guarantee or enforce uniqueness of this ID. If its not unique
33 - * the analytics data reported will be incorrect.
34 - *
35 - * 2. 'data-analytics-events': This is a comma separated list of DOM events that
36 - * you want analytics on. React currently supports tracking only on a
37 - * distinct set of events (See topLevelTypesToAnalyticsEvent).
38 - * If the list contains an event that React does not recognize for analytics
39 - * tracking, in __DEV__, an error will be thrown. Note that it is case
40 - * sensitive and space sensitive.
41 - *
42 - * By default the AnalyticsEventPlugin is NOT enabled in React. To use it, you
43 - * need to create the plugin using the factory method and add it to the list of
44 - * Plugins maintained in the EventPluginHub before your component is rendered.
45 - * As creation parameters you can specify two arguments:
46 - *
47 - * 1. callback: This is a required parameter. In __DEV__, an error will be
48 - * thrown if this param is missing. The callback will be called with the
49 - * analyticsData as an argument. The analyticsData will contain one property
50 - * per every React component, identified by its data-analytics-id. The value
51 - * of this property will be an object containing properties corresponding to
52 - * each of the comma separated events specified in data-analytics-events.
53 - *
54 - * For example, if you have:
55 - * <Button ...
56 - * data-analytics-id="createButton"
57 - * data-analytics-events="click"
58 - * />
59 - * and
60 - * <TextBox ...
61 - * data-analytics-id="disclaimerBox"
62 - * data-analytics-events="focus,scroll"
63 - * />
64 - * analyticsData will be something like:
65 - * '{"createButton":{"click":50}, "disclaimerBox":{"focus":15, "scroll":5}}'
66 - *
67 - * DO NOT mutate the data that you get in the callback. Mutating it will lead
68 - * to errors and unstable behavior.
69 - *
70 - * The React component will be included for analytics as long as some user
71 - * interaction has happened with that component. If no user interaction has
72 - * happened with any of the components tracked for analytics, the callback
73 - * will not be called.
74 - *
75 - * 2. interval (in milliseconds): This is an optional parameter to specify the
76 - * interval at which the callback needs to be called. It needs to be greater
77 - * than the 2 minutes (which is the default value if this parameter is not
78 - * specified or a value less than 2 minutes is specified)
79 - *
80 - * Please refer to the unit tests AnalyticsEventPlugin-test.js for details on
81 - * usage.
82 - */
83 -
84 -"use strict";
85 -
86 -var ExecutionEnvironment = require("./ExecutionEnvironment");
87 -
88 -var emptyFunction = require("./emptyFunction");
89 -var invariant = require("./invariant");
90 -var topLevelTypes = require("./EventConstants").topLevelTypes;
91 -
92 -var ANALYTICS_ID = 'data-analytics-id';
93 -var ANALYTICS_EVENTS = 'data-analytics-events';
94 -var DEFAULT_INTERVAL_MS = 2 * 60 * 1000; // 2 minutes
95 -
96 -var analyticsData = {};
97 -
98 -// List of topLevel event types that React supports for analytics tracking
99 -var topLevelTypesToAnalyticsEvent = {
100 - topClick: 'click',
101 - topDoubleClick: 'doubleClick',
102 - topMouseWheel: 'mouseWheel',
103 - topTouchStart: 'touchStart',
104 - topTouchEnd: 'touchEnd',
105 - topTouchMove: 'touchMove',
106 - topTouchCancel: 'touchCancel',
107 - topKeyUp: 'keyUp',
108 - topKeyPress: 'keyPress',
109 - topKeyDown: 'keyDown',
110 - topFocus: 'focus',
111 - topBlur: 'blur',
112 - topScroll: 'scroll',
113 - topChange: 'change'
114 -};
115 -
116 -if (true) {
117 - var analyticsEventNameToTopLevelType = {
118 - 'click': topLevelTypes.topClick,
119 - 'doubleClick': topLevelTypes.topDoubleClick,
120 - 'mouseWheel': topLevelTypes.topMouseWheel,
121 - 'touchStart': topLevelTypes.topTouchStart,
122 - 'touchEnd': topLevelTypes.topTouchEnd,
123 - 'touchMove': topLevelTypes.topTouchMove,
124 - 'touchCancel': topLevelTypes.topTouchCancel,
125 - 'keyUp': topLevelTypes.topKeyUp,
126 - 'keyPress': topLevelTypes.topKeyPress,
127 - 'keyDown': topLevelTypes.topKeyDown,
128 - 'focus': topLevelTypes.topFocus,
129 - 'blur': topLevelTypes.topBlur,
130 - 'scroll': topLevelTypes.topScroll,
131 - 'change': topLevelTypes.topChange
132 - };
133 -}
134 -
135 -/**
136 - * This plugin does not really extract any abstract events. Rather it just looks
137 - * at the top level event and bumps up counters as appropriate
138 - *
139 - * @see EventPluginHub.extractAbstractEvents
140 - */
141 -function extractAbstractEvents(
142 - topLevelType,
143 - nativeEvent,
144 - renderedTargetID,
145 - renderedTarget) {
146 - var currentEvent = topLevelTypesToAnalyticsEvent[topLevelType];
147 - if (!currentEvent || !renderedTarget || !renderedTarget.attributes) {
148 - return null;
149 - }
150 -
151 - var analyticsIDAttribute = renderedTarget.attributes[ANALYTICS_ID];
152 - var analyticsEventsAttribute = renderedTarget.attributes[ANALYTICS_EVENTS];
153 - if(!analyticsIDAttribute || !analyticsEventsAttribute) {
154 - return null;
155 - }
156 -
157 - var analyticsEventsArr = analyticsEventsAttribute.value.split(",");
158 - var analyticsID = analyticsIDAttribute.value;
159 - if (!analyticsData[analyticsID]) {
160 - initAnalyticsDataForID(analyticsID, analyticsEventsArr);
161 - }
162 -
163 - if (analyticsEventsArr.indexOf(currentEvent) !== -1) {
164 - analyticsData[analyticsID][currentEvent]++;
165 - }
166 -
167 - return null;
168 -}
169 -
170 -/**
171 - * Initialize the analytics data for a specific element identified by the
172 - * analyticsID - Create an entry in the analyticsData object for the element and
173 - * initialize all counters for that element to 0.
174 - */
175 -function initAnalyticsDataForID(analyticsID, analyticsEventsArr) {
176 - analyticsData[analyticsID] = {};
177 - analyticsEventsArr.forEach(function(analyticsEvent) {
178 - if (true) {
179 - invariant(
180 - analyticsEventNameToTopLevelType[analyticsEvent],
181 - 'Invalid analyticsEvent:%s for analyticsID:%s',
182 - analyticsEvent,
183 - analyticsID
184 - );
185 - }
186 - analyticsData[analyticsID][analyticsEvent] = 0;
187 - });
188 -}
189 -
190 -/**
191 - * Returns the analytics event plugin given the callback that needs to be
192 - * invoked for reporting analytics and the interval at which the callback needs
193 - * to be invoked. This interval has to be atleast DEFAULT_INTERVAL_MS.
194 - */
195 -var createAnalyticsPlugin = function(cb, interval) {
196 - invariant(
197 - ExecutionEnvironment.canUseDOM,
198 - 'createAnalyticsPlugin(...): The DOM is not supported in the execution ' +
199 - 'environment.'
200 - );
201 -
202 - if (true) {
203 - invariant(cb, 'createAnalyticsPlugin(...): You must provide a callback.');
204 - }
205 - cb = cb || emptyFunction;
206 -
207 - setInterval(
208 - function() {
209 - if (Object.keys(analyticsData).length) {
210 - // Invoke the callback with a clone of analyticsData, otherwise our
211 - // analyticsData will be dirtied by user changes
212 - cb(analyticsData);
213 - }
214 - },
215 - interval > DEFAULT_INTERVAL_MS ? interval : DEFAULT_INTERVAL_MS
216 - );
217 -
218 - return {extractAbstractEvents: extractAbstractEvents};
219 -};
220 -
221 -var AnalyticsEventPluginFactory = {
222 - createAnalyticsPlugin: createAnalyticsPlugin
223 -};
224 -
225 -module.exports = AnalyticsEventPluginFactory;
React/BrowserEnv.js deleted
-36
@@ -1,36 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule BrowserEnv
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * A place to share/cache browser/chrome level computations.
23 - */
24 -var BrowserEnv = {
25 - currentScrollLeft: 0,
26 - currentScrollTop: 0,
27 - browserInfo: null,
28 - refreshAuthoritativeScrollValues: function() {
29 - BrowserEnv.currentScrollLeft =
30 - document.body.scrollLeft + document.documentElement.scrollLeft;
31 - BrowserEnv.currentScrollTop =
32 - document.body.scrollTop + document.documentElement.scrollTop;
33 - }
34 -};
35 -
36 -module.exports = BrowserEnv;
React/CSSProperty.js deleted
-38
@@ -1,38 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule CSSProperty
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * CSS properties for which we do not append "px".
23 - */
24 -var isNumber = {
25 - fillOpacity: true,
26 - fontWeight: true,
27 - opacity: true,
28 - orphans: true,
29 - textDecoration: true,
30 - zIndex: true,
31 - zoom: true
32 -};
33 -
34 -var CSSProperty = {
35 - isNumber: isNumber
36 -};
37 -
38 -module.exports = CSSProperty;
React/CSSPropertyOperations.js deleted
-81
@@ -1,81 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule CSSPropertyOperations
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var dangerousStyleValue = require("./dangerousStyleValue");
23 -var escapeTextForBrowser = require("./escapeTextForBrowser");
24 -var hyphenate = require("./hyphenate");
25 -var memoizeStringOnly = require("./memoizeStringOnly");
26 -
27 -var processStyleName = memoizeStringOnly(function(styleName) {
28 - return escapeTextForBrowser(hyphenate(styleName));
29 -});
30 -
31 -/**
32 - * Operations for dealing with CSS properties.
33 - */
34 -var CSSPropertyOperations = {
35 -
36 - /**
37 - * Serializes a mapping of style properties for use as inline styles:
38 - *
39 - * > createMarkupForStyles({width: '200px', height: 0})
40 - * "width:200px;height:0;"
41 - *
42 - * Undefined values are ignored so that declarative programming is easier.
43 - *
44 - * @param {object} styles
45 - * @return {string}
46 - */
47 - createMarkupForStyles: function(styles) {
48 - var serialized = '';
49 - for (var styleName in styles) {
50 - if (!styles.hasOwnProperty(styleName)) {
51 - continue;
52 - }
53 - var styleValue = styles[styleName];
54 - if (typeof styleValue !== 'undefined') {
55 - serialized += processStyleName(styleName) + ':';
56 - serialized += dangerousStyleValue(styleName, styleValue) + ';';
57 - }
58 - }
59 - return serialized;
60 - },
61 -
62 - /**
63 - * Sets the value for multiple styles on a node.
64 - *
65 - * @param {DOMElement} node
66 - * @param {object} styles
67 - */
68 - setValueForStyles: function(node, styles) {
69 - var style = node.style;
70 - for (var styleName in styles) {
71 - if (!styles.hasOwnProperty(styleName)) {
72 - continue;
73 - }
74 - var styleValue = styles[styleName];
75 - style[styleName] = dangerousStyleValue(styleName, styleValue);
76 - }
77 - }
78 -
79 -};
80 -
81 -module.exports = CSSPropertyOperations;
React/CallbackRegistry.js deleted
-72
@@ -1,72 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule CallbackRegistry
17 - */
18 -
19 -"use strict";
20 -
21 -var listenerBank = {};
22 -
23 -/**
24 - * Stores "listeners" by `registrationName`/`id`. There should be at most one
25 - * "listener" per `registrationName/id` in the `listenerBank`.
26 - * Access listeners via `listenerBank[registrationName][id]`
27 - *
28 - * @constructor CallbackRegistry
29 - */
30 -var CallbackRegistry = {
31 -
32 - /**
33 - * Stores `listener` at `listenerBank[registrationName][id]. Is idempotent.
34 - * @param {string} domID The id of the DOM node.
35 - * @param {string} registrationName The name of listener (`onClick` etc).
36 - * @param {Function} listener The callback to to store.
37 - */
38 - putListener: function(id, registrationName, listener) {
39 - var bankForRegistrationName =
40 - listenerBank[registrationName] || (listenerBank[registrationName] = {});
41 - bankForRegistrationName[id] = listener;
42 - },
43 -
44 - /**
45 - * @param {string} id.
46 - * @param {string} registrationName Name of registration (`onClick` etc).
47 - * @return {Function?} The Listener
48 - */
49 - getListener: function(id, registrationName) {
50 - var bankForRegistrationName = listenerBank[registrationName];
51 - return bankForRegistrationName && bankForRegistrationName[id];
52 - },
53 -
54 - /**
55 - * Deletes the listener from the registration bank.
56 - * @param {string} id
57 - * @param {string} registrationName (`onClick` etc).
58 - */
59 - deleteListener: function(id, registrationName) {
60 - var bankForRegistrationName = listenerBank[registrationName];
61 - if (bankForRegistrationName) {
62 - delete bankForRegistrationName[id];
63 - }
64 - },
65 -
66 - // This is needed for tests only. Do not use in real life
67 - __purge: function() {
68 - listenerBank = {};
69 - }
70 -};
71 -
72 -module.exports = CallbackRegistry;
React/DOMChildrenOperations.js deleted
-146
@@ -1,146 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule DOMChildrenOperations
17 - */
18 -
19 -"use strict";
20 -
21 -var Danger = require("./Danger");
22 -
23 -var insertNodeAt = require("./insertNodeAt");
24 -var keyOf = require("./keyOf");
25 -var throwIf = require("./throwIf");
26 -
27 -var NON_INCREASING_OPERATIONS;
28 -if (true) {
29 - NON_INCREASING_OPERATIONS =
30 - 'DOM child management operations must be provided in order ' +
31 - 'of increasing destination index. This is likely an issue with ' +
32 - 'the core framework.';
33 -}
34 -
35 -var MOVE_NODE_AT_ORIG_INDEX = keyOf({moveFrom: null});
36 -var INSERT_MARKUP = keyOf({insertMarkup: null});
37 -var REMOVE_AT = keyOf({removeAt: null});
38 -
39 -/**
40 - * In order to carry out movement of DOM nodes without knowing their IDs, we
41 - * have to first store knowledge about nodes' original indices before beginning
42 - * to carry out the sequence of operations. Once we begin the sequence, the DOM
43 - * indices in future instructions are no longer valid.
44 - *
45 - * @param {Element} parent Parent DOM node.
46 - * @param {Object} childOperations Description of child operations.
47 - * @returns {Array?} Sparse array containing elements by their current index in
48 - * the DOM.
49 - */
50 -var _getNodesByOriginalIndex = function(parent, childOperations) {
51 - var nodesByOriginalIndex; // Sparse array.
52 - var childOperation;
53 - var origIndex;
54 - for (var i = 0; i < childOperations.length; i++) {
55 - childOperation = childOperations[i];
56 - if (MOVE_NODE_AT_ORIG_INDEX in childOperation) {
57 - nodesByOriginalIndex = nodesByOriginalIndex || [];
58 - origIndex = childOperation.moveFrom;
59 - nodesByOriginalIndex[origIndex] = parent.childNodes[origIndex];
60 - } else if (REMOVE_AT in childOperation) {
61 - nodesByOriginalIndex = nodesByOriginalIndex || [];
62 - origIndex = childOperation.removeAt;
63 - nodesByOriginalIndex[origIndex] = parent.childNodes[origIndex];
64 - }
65 - }
66 - return nodesByOriginalIndex;
67 -};
68 -
69 -/**
70 - * Removes DOM elements from their parent, or moved.
71 - * @param {Element} parent Parent DOM node.
72 - * @param {Array} nodesByOriginalIndex Child nodes by their original index
73 - * (potentially sparse.)
74 - */
75 -var _removeChildrenByOriginalIndex = function(parent, nodesByOriginalIndex) {
76 - for (var j = 0; j < nodesByOriginalIndex.length; j++) {
77 - var nodeToRemove = nodesByOriginalIndex[j];
78 - if (nodeToRemove) { // We used a sparse array.
79 - parent.removeChild(nodesByOriginalIndex[j]);
80 - }
81 - }
82 -};
83 -
84 -/**
85 - * Once all nodes that will be removed or moved - are removed from the parent
86 - * node, we can begin the process of placing nodes into their final locations.
87 - * We must perform all operations in the order of the final DOM index -
88 - * otherwise, we couldn't count on the fact that an insertion at index X, will
89 - * remain at index X. This will iterate through the child operations, adding
90 - * content where needed, skip over removals (they've already been removed) and
91 - * insert "moved" Elements that were previously removed. The "moved" elements
92 - * are only temporarily removed from the parent, so that index calculations can
93 - * be manageable and perform well in the cases that matter.
94 - */
95 -var _placeNodesAtDestination =
96 - function(parent, childOperations, nodesByOriginalIndex) {
97 - var origNode;
98 - var finalIndex;
99 - var lastFinalIndex = -1;
100 - var childOperation;
101 - for (var k = 0; k < childOperations.length; k++) {
102 - childOperation = childOperations[k];
103 - if (MOVE_NODE_AT_ORIG_INDEX in childOperation) {
104 - origNode = nodesByOriginalIndex[childOperation.moveFrom];
105 - finalIndex = childOperation.finalIndex;
106 - insertNodeAt(parent, origNode, finalIndex);
107 - if (true) {
108 - throwIf(finalIndex <= lastFinalIndex, NON_INCREASING_OPERATIONS);
109 - lastFinalIndex = finalIndex;
110 - }
111 - } else if (REMOVE_AT in childOperation) {
112 - } else if (INSERT_MARKUP in childOperation) {
113 - finalIndex = childOperation.finalIndex;
114 - var markup = childOperation.insertMarkup;
115 - Danger.dangerouslyInsertMarkupAt(parent, markup, finalIndex);
116 - if (true) {
117 - throwIf(finalIndex <= lastFinalIndex, NON_INCREASING_OPERATIONS);
118 - lastFinalIndex = finalIndex;
119 - }
120 - }
121 - }
122 - };
123 -
124 -var manageChildren = function(parent, childOperations) {
125 - var nodesByOriginalIndex = _getNodesByOriginalIndex(parent, childOperations);
126 - if (nodesByOriginalIndex) {
127 - _removeChildrenByOriginalIndex(parent, nodesByOriginalIndex);
128 - }
129 - _placeNodesAtDestination(parent, childOperations, nodesByOriginalIndex);
130 -};
131 -
132 -var setTextNodeValueAtIndex = function(parent, index, val) {
133 - parent.childNodes[index].nodeValue = val;
134 -};
135 -
136 -/**
137 - * Also reexport all of the dangerous functions. It helps to have all dangerous
138 - * functions located in a single module `Danger`.
139 - */
140 -var DOMChildrenOperations = {
141 - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
142 - manageChildren: manageChildren,
143 - setTextNodeValueAtIndex: setTextNodeValueAtIndex
144 -};
145 -
146 -module.exports = DOMChildrenOperations;
React/DOMProperty.js deleted
-263
@@ -1,263 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule DOMProperty
17 - * @typechecks
18 - */
19 -
20 -/*jslint bitwise: true */
21 -
22 -"use strict";
23 -
24 -var invariant = require("./invariant");
25 -
26 -/**
27 - * DOMProperty exports lookup objects that can be used like functions:
28 - *
29 - * > DOMProperty.isValid['id']
30 - * true
31 - * > DOMProperty.isValid['foobar']
32 - * undefined
33 - *
34 - * Although this may be confusing, it performs better in general.
35 - *
36 - * @see http://jsperf.com/key-exists
37 - * @see http://jsperf.com/key-missing
38 - */
39 -var DOMProperty = {
40 -
41 - /**
42 - * Checks whether a property name is a standard property.
43 - * @type {Object}
44 - */
45 - isStandardName: {},
46 -
47 - /**
48 - * Mapping from normalized names to attribute names that differ. Attribute
49 - * names are used when rendering markup or with `*Attribute()`.
50 - * @type {Object}
51 - */
52 - getAttributeName: {},
53 -
54 - /**
55 - * Mapping from normalized names to properties on DOM node instances.
56 - * (This includes properties that mutate due to external factors.)
57 - * @type {Object}
58 - */
59 - getPropertyName: {},
60 -
61 - /**
62 - * Mapping from normalized names to mutation methods. This will only exist if
63 - * mutation cannot be set simply by the property or `setAttribute()`.
64 - * @type {Object}
65 - */
66 - getMutationMethod: {},
67 -
68 - /**
69 - * Whether the property must be accessed and mutated as an object property.
70 - * @type {Object}
71 - */
72 - mustUseAttribute: {},
73 -
74 - /**
75 - * Whether the property must be accessed and mutated using `*Attribute()`.
76 - * (This includes anything that fails `<propName> in <element>`.)
77 - * @type {Object}
78 - */
79 - mustUseProperty: {},
80 -
81 - /**
82 - * Whether the property should be removed when set to a falsey value.
83 - * @type {Object}
84 - */
85 - hasBooleanValue: {},
86 -
87 - /**
88 - * Whether or not setting a value causes side effects such as triggering
89 - * resources to be loaded or text selection changes. We must ensure that
90 - * the value is only set if it has changed.
91 - * @type {Object}
92 - */
93 - hasSideEffects: {},
94 -
95 - /**
96 - * Checks whether a property name is a custom attribute.
97 - * @method
98 - */
99 - isCustomAttribute: RegExp.prototype.test.bind(
100 - /^(data|aria)-[a-z_][a-z\d_.\-]*$/
101 - )
102 -};
103 -
104 -/**
105 - * Mapping from normalized, camelcased property names to a configuration that
106 - * specifies how the associated DOM property should be accessed or rendered.
107 - */
108 -var MustUseAttribute = 0x1;
109 -var MustUseProperty = 0x2;
110 -var HasBooleanValue = 0x4;
111 -var HasSideEffects = 0x8;
112 -
113 -var Properties = {
114 - /**
115 - * Standard Properties
116 - */
117 - accept: null,
118 - action: null,
119 - ajaxify: MustUseAttribute,
120 - allowFullScreen: MustUseAttribute | HasBooleanValue,
121 - alt: null,
122 - autoComplete: null,
123 - autoplay: HasBooleanValue,
124 - cellPadding: null,
125 - cellSpacing: null,
126 - checked: MustUseProperty | HasBooleanValue,
127 - className: MustUseProperty,
128 - colSpan: null,
129 - contentEditable: null,
130 - controls: MustUseProperty | HasBooleanValue,
131 - data: null, // For `<object />` acts as `src`.
132 - dir: null,
133 - disabled: MustUseProperty | HasBooleanValue,
134 - enctype: null,
135 - height: null,
136 - href: null,
137 - htmlFor: null,
138 - max: null,
139 - method: null,
140 - min: null,
141 - multiple: MustUseProperty | HasBooleanValue,
142 - name: null,
143 - poster: null,
144 - preload: null,
145 - placeholder: null,
146 - rel: null,
147 - required: HasBooleanValue,
148 - role: MustUseAttribute,
149 - scrollLeft: MustUseProperty,
150 - scrollTop: MustUseProperty,
151 - selected: MustUseProperty | HasBooleanValue,
152 - spellCheck: null,
153 - src: null,
154 - step: null,
155 - style: null,
156 - tabIndex: null,
157 - target: null,
158 - title: null,
159 - type: null,
160 - value: MustUseProperty | HasSideEffects,
161 - width: null,
162 - wmode: MustUseAttribute,
163 - /**
164 - * SVG Properties
165 - */
166 - cx: MustUseProperty,
167 - cy: MustUseProperty,
168 - d: MustUseProperty,
169 - fill: MustUseProperty,
170 - fx: MustUseProperty,
171 - fy: MustUseProperty,
172 - points: MustUseProperty,
173 - r: MustUseProperty,
174 - stroke: MustUseProperty,
175 - strokeLinecap: MustUseProperty,
176 - strokeWidth: MustUseProperty,
177 - transform: MustUseProperty,
178 - x: MustUseProperty,
179 - x1: MustUseProperty,
180 - x2: MustUseProperty,
181 - version: MustUseProperty,
182 - viewBox: MustUseProperty,
183 - y: MustUseProperty,
184 - y1: MustUseProperty,
185 - y2: MustUseProperty,
186 - spreadMethod: MustUseProperty,
187 - offset: MustUseProperty,
188 - stopColor: MustUseProperty,
189 - stopOpacity: MustUseProperty,
190 - gradientUnits: MustUseProperty,
191 - gradientTransform: MustUseProperty
192 -};
193 -
194 -/**
195 - * Attribute names not specified use the **lowercase** normalized name.
196 - */
197 -var DOMAttributeNames = {
198 - className: 'class',
199 - htmlFor: 'for',
200 - strokeLinecap: 'stroke-linecap',
201 - strokeWidth: 'stroke-width',
202 - stopColor: 'stop-color',
203 - stopOpacity: 'stop-opacity'
204 -};
205 -
206 -/**
207 - * Property names not specified use the normalized name.
208 - */
209 -var DOMPropertyNames = {
210 - autoComplete: 'autocomplete',
211 - spellCheck: 'spellcheck'
212 -};
213 -
214 -/**
215 - * Properties that require special mutation methods.
216 - */
217 -var DOMMutationMethods = {
218 - /**
219 - * Setting `className` to null may cause it to be set to the string "null".
220 - *
221 - * @param {DOMElement} node
222 - * @param {*} value
223 - */
224 - className: function(node, value) {
225 - node.className = value || '';
226 - }
227 -};
228 -
229 -for (var propName in Properties) {
230 - DOMProperty.isStandardName[propName] = true;
231 -
232 - DOMProperty.getAttributeName[propName] =
233 - DOMAttributeNames[propName] || propName.toLowerCase();
234 -
235 - DOMProperty.getPropertyName[propName] =
236 - DOMPropertyNames[propName] || propName;
237 -
238 - var mutationMethod = DOMMutationMethods[propName];
239 - if (mutationMethod) {
240 - DOMProperty.getMutationMethod[propName] = mutationMethod;
241 - }
242 -
243 - var propConfig = Properties[propName];
244 - DOMProperty.mustUseAttribute[propName] = propConfig & MustUseAttribute;
245 - DOMProperty.mustUseProperty[propName] = propConfig & MustUseProperty;
246 - DOMProperty.hasBooleanValue[propName] = propConfig & HasBooleanValue;
247 - DOMProperty.hasSideEffects[propName] = propConfig & HasSideEffects;
248 -
249 - invariant(
250 - !DOMProperty.mustUseAttribute[propName] ||
251 - !DOMProperty.mustUseProperty[propName],
252 - 'DOMProperty: Cannot use require using both attribute and property: %s',
253 - propName
254 - );
255 - invariant(
256 - DOMProperty.mustUseProperty[propName] ||
257 - !DOMProperty.hasSideEffects[propName],
258 - 'DOMProperty: Properties that have side effects must use property: %s',
259 - propName
260 - );
261 -}
262 -
263 -module.exports = DOMProperty;
React/DOMPropertyOperations.js deleted
-93
@@ -1,93 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule DOMPropertyOperations
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var DOMProperty = require("./DOMProperty");
23 -
24 -var escapeTextForBrowser = require("./escapeTextForBrowser");
25 -var memoizeStringOnly = require("./memoizeStringOnly");
26 -
27 -var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
28 - return escapeTextForBrowser(name) + '="';
29 -});
30 -
31 -/**
32 - * Operations for dealing with DOM properties.
33 - */
34 -var DOMPropertyOperations = {
35 -
36 - /**
37 - * Creates markup for a property.
38 - *
39 - * @param {string} name
40 - * @param {*} value
41 - * @return {?string} Markup string, or null if the property was invalid.
42 - */
43 - createMarkupForProperty: function(name, value) {
44 - if (DOMProperty.isStandardName[name]) {
45 - if (value == null || DOMProperty.hasBooleanValue[name] && !value) {
46 - return '';
47 - }
48 - var attributeName = DOMProperty.getAttributeName[name];
49 - return processAttributeNameAndPrefix(attributeName) +
50 - escapeTextForBrowser(value) + '"';
51 - } else if (DOMProperty.isCustomAttribute(name)) {
52 - if (value == null) {
53 - return '';
54 - }
55 - return processAttributeNameAndPrefix(name) +
56 - escapeTextForBrowser(value) + '"';
57 - } else {
58 - return null;
59 - }
60 - },
61 -
62 - /**
63 - * Sets the value for a property on a node.
64 - *
65 - * @param {DOMElement} node
66 - * @param {string} name
67 - * @param {*} value
68 - */
69 - setValueForProperty: function(node, name, value) {
70 - if (DOMProperty.isStandardName[name]) {
71 - var mutationMethod = DOMProperty.getMutationMethod[name];
72 - if (mutationMethod) {
73 - mutationMethod(node, value);
74 - } else if (DOMProperty.mustUseAttribute[name]) {
75 - if (DOMProperty.hasBooleanValue[name] && !value) {
76 - node.removeAttribute(DOMProperty.getAttributeName[name]);
77 - } else {
78 - node.setAttribute(DOMProperty.getAttributeName[name], value);
79 - }
80 - } else {
81 - var propName = DOMProperty.getPropertyName[name];
82 - if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {
83 - node[propName] = value;
84 - }
85 - }
86 - } else if (DOMProperty.isCustomAttribute(name)) {
87 - node.setAttribute(name, value);
88 - }
89 - }
90 -
91 -};
92 -
93 -module.exports = DOMPropertyOperations;
React/Danger.js deleted
-158
@@ -1,158 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule Danger
17 - */
18 -
19 -"use strict";
20 -
21 -var ExecutionEnvironment = require("./ExecutionEnvironment");
22 -
23 -var throwIf = require("./throwIf");
24 -
25 -var DOM_UNSUPPORTED;
26 -var NO_MARKUP_PARENT;
27 -var NO_MULTI_MARKUP;
28 -if (true) {
29 - DOM_UNSUPPORTED =
30 - 'You may not insert markup into the document while you are in a worker ' +
31 - 'thread. It\'s not you, it\'s me. This is likely the fault of the ' +
32 - 'framework. Please report this immediately.';
33 - NO_MARKUP_PARENT =
34 - 'You have attempted to inject markup without a suitable parent. This is ' +
35 - 'likely the fault of the framework - please report immediately.';
36 - NO_MULTI_MARKUP =
37 - 'The framework has attempted to either insert zero or multiple markup ' +
38 - 'roots into a single location when it should not. This is a serious ' +
39 - 'error - a fault of the framework - please report immediately.';
40 -}
41 -
42 -var validateMarkupParams;
43 -if (true) {
44 - validateMarkupParams = function(parentNode, markup) {
45 - throwIf(!ExecutionEnvironment.canUseDOM, DOM_UNSUPPORTED);
46 - throwIf(!parentNode || !parentNode.tagName, NO_MARKUP_PARENT);
47 - throwIf(!markup, NO_MULTI_MARKUP);
48 - };
49 -}
50 -
51 -var dummies = {};
52 -
53 -function getParentDummy(parent) {
54 - var parentTag = parent.tagName;
55 - return dummies[parentTag] ||
56 - (dummies[parentTag] = document.createElement(parentTag));
57 -}
58 -
59 -/**
60 - * Inserts node after 'after'. If 'after' is null, inserts it after nothing,
61 - * which is inserting it at the beginning.
62 - *
63 - * @param {Element} elem Parent element.
64 - * @param {Element} insert Element to insert.
65 - * @param {Element} after Element to insert after.
66 - * @returns {Element} Element that was inserted.
67 - */
68 -function insertNodeAfterNode(elem, insert, after) {
69 - if (true) {
70 - throwIf(!ExecutionEnvironment.canUseDOM, DOM_UNSUPPORTED);
71 - }
72 - if (after) {
73 - if (after.nextSibling) {
74 - return elem.insertBefore(insert, after.nextSibling);
75 - } else {
76 - return elem.appendChild(insert);
77 - }
78 - } else {
79 - return elem.insertBefore(insert, elem.firstChild);
80 - }
81 -}
82 -
83 -/**
84 - * Slow: Should only be used when it is known there are a few (or one) element
85 - * in the node list.
86 - * @param {Element} parentRootDomNode Parent element.
87 - * @param {HTMLCollection} htmlCollection HTMLCollection to insert.
88 - * @param {Element} after Element to insert the node list after.
89 - */
90 -function inefficientlyInsertHTMLCollectionAfter(
91 - parentRootDomNode,
92 - htmlCollection,
93 - after) {
94 -
95 - if (true) {
96 - throwIf(!ExecutionEnvironment.canUseDOM, DOM_UNSUPPORTED);
97 - }
98 - var ret;
99 - var originalLength = htmlCollection.length;
100 - // Access htmlCollection[0] because htmlCollection shrinks as we remove items.
101 - // `insertNodeAfterNode` will remove items from the htmlCollection.
102 - for (var i = 0; i < originalLength; i++) {
103 - ret =
104 - insertNodeAfterNode(parentRootDomNode, htmlCollection[0], ret || after);
105 - }
106 -}
107 -
108 -/**
109 - * Super-dangerously inserts markup into existing DOM structure. Seriously, you
110 - * don't want to use this module unless you are building a framework. This
111 - * requires that the markup that you are inserting represents the root of a
112 - * tree. We do not support the case where there `markup` represents several
113 - * roots.
114 - *
115 - * @param {Element} parentNode Parent DOM element.
116 - * @param {string} markup Markup to dangerously insert.
117 - * @param {number} index Position to insert markup at.
118 - */
119 -function dangerouslyInsertMarkupAt(parentNode, markup, index) {
120 - if (true) {
121 - validateMarkupParams(parentNode, markup);
122 - }
123 - var parentDummy = getParentDummy(parentNode);
124 - parentDummy.innerHTML = markup;
125 - var htmlCollection = parentDummy.childNodes;
126 - var afterNode = index ? parentNode.childNodes[index - 1] : null;
127 - inefficientlyInsertHTMLCollectionAfter(parentNode, htmlCollection, afterNode);
128 -}
129 -
130 -/**
131 - * Replaces a node with a string of markup at its current position within its
132 - * parent. `childNode` must be in the document (or at least within a parent
133 - * node). The string of markup must represent a tree of markup with a single
134 - * root.
135 - *
136 - * @param {Element} childNode Child node to replace.
137 - * @param {string} markup Markup to dangerously replace child with.
138 - */
139 -function dangerouslyReplaceNodeWithMarkup(childNode, markup) {
140 - var parentNode = childNode.parentNode;
141 - if (true) {
142 - validateMarkupParams(parentNode, markup);
143 - }
144 - var parentDummy = getParentDummy(parentNode);
145 - parentDummy.innerHTML = markup;
146 - var htmlCollection = parentDummy.childNodes;
147 - if (true) {
148 - throwIf(htmlCollection.length !== 1, NO_MULTI_MARKUP);
149 - }
150 - parentNode.replaceChild(htmlCollection[0], childNode);
151 -}
152 -
153 -var Danger = {
154 - dangerouslyInsertMarkupAt: dangerouslyInsertMarkupAt,
155 - dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup
156 -};
157 -
158 -module.exports = Danger;
React/DefaultEventPluginOrder.js deleted
-40
@@ -1,40 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule DefaultEventPluginOrder
17 - */
18 -
19 -"use strict";
20 -
21 - var keyOf = require("./keyOf");
22 -
23 -/**
24 - * Module that is injectable into `EventPluginHub`, that specifies a
25 - * deterministic ordering of `EventPlugin`s. A convenient way to reason about
26 - * plugins, without having to package every one of them. This is better than
27 - * having plugins be ordered in the same order that they are injected because
28 - * that ordering would be influenced by the packaging order.
29 - * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
30 - * preventing default on events is convenient in `SimpleEventPlugin` handlers.
31 - */
32 -var DefaultEventPluginOrder = [
33 - keyOf({ResponderEventPlugin: null}),
34 - keyOf({SimpleEventPlugin: null}),
35 - keyOf({TapEventPlugin: null}),
36 - keyOf({EnterLeaveEventPlugin: null}),
37 - keyOf({AnalyticsEventPlugin: null})
38 -];
39 -
40 -module.exports = DefaultEventPluginOrder;
React/EnterLeaveEventPlugin.js deleted
-102
@@ -1,102 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EnterLeaveEventPlugin
17 - */
18 -
19 -"use strict";
20 -
21 -var EventPropagators = require("./EventPropagators");
22 -var ExecutionEnvironment = require("./ExecutionEnvironment");
23 -var AbstractEvent = require("./AbstractEvent");
24 -var EventConstants = require("./EventConstants");
25 -var ReactInstanceHandles = require("./ReactInstanceHandles");
26 -
27 -var getDOMNodeID = require("./getDOMNodeID");
28 -var keyOf = require("./keyOf");
29 -
30 -var topLevelTypes = EventConstants.topLevelTypes;
31 -var getFirstReactDOM = ReactInstanceHandles.getFirstReactDOM;
32 -
33 -var abstractEventTypes = {
34 - mouseEnter: {registrationName: keyOf({onMouseEnter: null})},
35 - mouseLeave: {registrationName: keyOf({onMouseLeave: null})}
36 -};
37 -
38 -/**
39 - * For almost every interaction we care about, there will be a top level
40 - * `mouseOver` and `mouseOut` event that occur so we can usually only pay
41 - * attention to one of the two (we'll pay attention to the `mouseOut` event) to
42 - * avoid extracting a duplicate event. However, there's one interaction where
43 - * there will be no `mouseOut` event to rely on - mousing from outside the
44 - * browser *into* the chrome. We detect this scenario and only in that case, we
45 - * use the `mouseOver` event.
46 - *
47 - * @see EventPluginHub.extractAbstractEvents
48 - */
49 -var extractAbstractEvents = function(
50 - topLevelType,
51 - nativeEvent,
52 - renderedTargetID,
53 - renderedTarget) {
54 -
55 - if (topLevelType === topLevelTypes.topMouseOver &&
56 - (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
57 - return;
58 - }
59 - if (topLevelType !== topLevelTypes.topMouseOut &&
60 - topLevelType !== topLevelTypes.topMouseOver){
61 - return null; // Must not be a mouse in or mouse out - ignoring.
62 - }
63 -
64 - var to, from;
65 - if (topLevelType === topLevelTypes.topMouseOut) {
66 - to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
67 - ExecutionEnvironment.global;
68 - from = renderedTarget;
69 - } else {
70 - to = renderedTarget;
71 - from = ExecutionEnvironment.global;
72 - }
73 -
74 - // Nothing pertains to our managed components.
75 - if (from === to ) {
76 - return;
77 - }
78 -
79 - var fromID = from ? getDOMNodeID(from) : '';
80 - var toID = to ? getDOMNodeID(to) : '';
81 - var leave = AbstractEvent.getPooled(
82 - abstractEventTypes.mouseLeave,
83 - fromID,
84 - topLevelType,
85 - nativeEvent
86 - );
87 - var enter = AbstractEvent.getPooled(
88 - abstractEventTypes.mouseEnter,
89 - toID,
90 - topLevelType,
91 - nativeEvent
92 - );
93 - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
94 - return [leave, enter];
95 -};
96 -
97 -var EnterLeaveEventPlugin = {
98 - abstractEventTypes: abstractEventTypes,
99 - extractAbstractEvents: extractAbstractEvents
100 -};
101 -
102 -module.exports = EnterLeaveEventPlugin;
React/EventConstants.js deleted
-57
@@ -1,57 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EventConstants
17 - */
18 -
19 -"use strict";
20 -
21 -var keyMirror = require("./keyMirror");
22 -
23 -var PropagationPhases = keyMirror({bubbled: null, captured: null});
24 -
25 -/**
26 - * Types of raw signals from the browser caught at the top level.
27 - */
28 -var topLevelTypes = keyMirror({
29 - topBlur: null,
30 - topChange: null,
31 - topClick: null,
32 - topDOMCharacterDataModified: null,
33 - topDoubleClick: null,
34 - topFocus: null,
35 - topKeyDown: null,
36 - topKeyPress: null,
37 - topKeyUp: null,
38 - topMouseDown: null,
39 - topMouseMove: null,
40 - topMouseOut: null,
41 - topMouseOver: null,
42 - topMouseUp: null,
43 - topMouseWheel: null,
44 - topScroll: null,
45 - topSubmit: null,
46 - topTouchCancel: null,
47 - topTouchEnd: null,
48 - topTouchMove: null,
49 - topTouchStart: null
50 -});
51 -
52 -var EventConstants = {
53 - topLevelTypes: topLevelTypes,
54 - PropagationPhases: PropagationPhases
55 -};
56 -
57 -module.exports = EventConstants;
React/EventListener.js deleted
-59
@@ -1,59 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EventListener
17 - */
18 -
19 -/**
20 - * Upstream version of event listener. Does not take into account specific
21 - * nature of platform.
22 - */
23 -var EventListener = {
24 - /**
25 - * Listens to bubbled events on a DOM node.
26 - *
27 - * @param {Element} el DOM element to register listener on.
28 - * @param {string} handlerBaseName 'click'/'mouseover'
29 - * @param {Function!} cb Callback function
30 - */
31 - listen: function(el, handlerBaseName, cb) {
32 - if (el.addEventListener) {
33 - el.addEventListener(handlerBaseName, cb, false);
34 - } else if (el.attachEvent) {
35 - el.attachEvent('on' + handlerBaseName, cb);
36 - }
37 - },
38 -
39 - /**
40 - * Listens to captured events on a DOM node.
41 - *
42 - * @see `EventListener.listen` for params.
43 - * @throws Exception if addEventListener is not supported.
44 - */
45 - capture: function(el, handlerBaseName, cb) {
46 - if (!el.addEventListener) {
47 - console.error(
48 - 'You are attempting to use addEventlistener ' +
49 - 'in a browser that does not support it support it.' +
50 - 'This likely means that you will not receive events that ' +
51 - 'your application relies on (such as scroll).');
52 - return;
53 - } else {
54 - el.addEventListener(handlerBaseName, cb, true);
55 - }
56 - }
57 -};
58 -
59 -module.exports = EventListener;
React/EventPluginHub.js deleted
-324
@@ -1,324 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EventPluginHub
17 - */
18 -
19 -"use strict";
20 -
21 -var AbstractEvent = require("./AbstractEvent");
22 -var CallbackRegistry = require("./CallbackRegistry");
23 -var EventPluginUtils = require("./EventPluginUtils");
24 -var EventPropagators = require("./EventPropagators");
25 -var ExecutionEnvironment = require("./ExecutionEnvironment");
26 -
27 -var accumulate = require("./accumulate");
28 -var forEachAccumulated = require("./forEachAccumulated");
29 -var keyMirror = require("./keyMirror");
30 -var merge = require("./merge");
31 -var throwIf = require("./throwIf");
32 -
33 -var deleteListener = CallbackRegistry.deleteListener;
34 -
35 -var ERRORS = keyMirror({
36 - DOUBLE_REGISTER: null,
37 - DOUBLE_ENQUEUE: null,
38 - DEPENDENCY_ERROR: null
39 -});
40 -
41 -if (true) {
42 - ERRORS.DOUBLE_REGISTER =
43 - 'You\'ve included an event plugin that extracts an ' +
44 - 'event type with the exact same or identity as an event that ' +
45 - 'had previously been injected - or, one of the registration names ' +
46 - 'used by an plugin has already been used.';
47 - ERRORS.DOUBLE_ENQUEUE =
48 - 'During the processing of events, more events were enqueued. This ' +
49 - 'is strange and should not happen. Please report immediately. ';
50 - ERRORS.DEPENDENCY_ERROR =
51 - 'You have either attempted to load an event plugin that has no ' +
52 - 'entry in EventPluginOrder, or have attempted to extract events ' +
53 - 'when some critical dependencies have not yet been injected.';
54 -}
55 -
56 -
57 -/**
58 - * EventPluginHub: To see a diagram and explanation of the overall architecture
59 - * of the plugin hub system, @see ReactEvents.js
60 - */
61 -
62 -/**
63 - * Injected Dependencies:
64 - */
65 -var injection = {
66 - /**
67 - * [required] Dependency of `EventPropagators`.
68 - */
69 - injectInstanceHandle: function(InjectedInstanceHandle) {
70 - EventPropagators.injection.injectInstanceHandle(InjectedInstanceHandle);
71 - },
72 -
73 - /**
74 - * `EventPluginOrder`: [optional] Provides deterministic ordering of
75 - * `EventPlugin`s. Ordering decoupled from the injection of actual
76 - * plugins so that there is always a deterministic and permanent ordering
77 - * regardless of the plugins that happen to become packaged, or applications
78 - * that happen to inject on-the-fly event plugins.
79 - */
80 - EventPluginOrder: null,
81 - injectEventPluginOrder: function(InjectedEventPluginOrder) {
82 - injection.EventPluginOrder = InjectedEventPluginOrder;
83 - injection._recomputePluginsList();
84 - },
85 -
86 - /**
87 - * `EventPlugins`: [optional][lazy-loadable] Plugins that must be listed in
88 - * the `EventPluginOrder` injected dependency. The list of plugins may grow as
89 - * custom plugins are injected into the system at page as part of the
90 - * initialization process, or even after the initialization process (on-the-
91 - * fly). Plugins injected into the hub have an opportunity to infer abstract
92 - * events when top level events are streamed through the `EventPluginHub`.
93 - */
94 - plugins: [],
95 - injectEventPluginsByName: function(pluginsByName) {
96 - injection.pluginsByName = merge(injection.pluginsByName, pluginsByName);
97 - injection._recomputePluginsList();
98 - },
99 -
100 - /**
101 - * A reference of all injected plugins by their name. Both plugins and
102 - * `EventPluginOrder` can be injected on-the-fly. Any time either dependency
103 - * is (re)injected, the resulting list of plugins in correct order is
104 - * recomputed.
105 - */
106 - pluginsByName: {},
107 - _recomputePluginsList: function() {
108 - var injectPluginByName = function(name, PluginModule) {
109 - var pluginIndex = injection.EventPluginOrder.indexOf(name);
110 - throwIf(pluginIndex === -1, ERRORS.DEPENDENCY_ERROR + name);
111 - if (!injection.plugins[pluginIndex]) {
112 - injection.plugins[pluginIndex] = PluginModule;
113 - for (var eventName in PluginModule.abstractEventTypes) {
114 - var eventType = PluginModule.abstractEventTypes[eventName];
115 - recordAllRegistrationNames(eventType, PluginModule);
116 - }
117 - }
118 - };
119 - if (injection.EventPluginOrder) { // Else, do when plugin order injected
120 - var injectedPluginsByName = injection.pluginsByName;
121 - for (var name in injectedPluginsByName) {
122 - injectPluginByName(name, injectedPluginsByName[name]);
123 - }
124 - }
125 - }
126 -};
127 -
128 -
129 -/**
130 - * `renderedTarget`: We'll refer to the concept of a "rendered target". Any
131 - * framework code that uses the `EventPluginHub` will stream events to the
132 - * `EventPluginHub`. In order for registered plugins to make sense of the native
133 - * events, it helps to allow plugins to not only have access to the native
134 - * `Event` object but also the notion of a "rendered target", which is the
135 - * conceptual target `Element` of the `Event` that the framework (user of
136 - * `EventPluginHub`) deems as being the "important" target.
137 - */
138 -/**
139 - * Keeps track of all valid "registration names" (`onClick` etc). We expose
140 - * these structures to other modules, who will always see updates that we apply
141 - * to these structures. They should never have a desire to mutate these.
142 - */
143 -var registrationNames = {};
144 -
145 -/**
146 - * This prevents the need for clients to call `Object.keys(registrationNames)`
147 - * every time they want to loop through the possible registration names.
148 - */
149 -var registrationNamesArr = [];
150 -
151 -/**
152 - * Internal queue of events that have accumulated their dispatches and are
153 - * waiting to have their dispatches executed.
154 - */
155 -var abstractEventQueue = [];
156 -
157 -/**
158 - * Records all the registration names that the event plugin makes available
159 - * to the general event system. These are things like
160 - * `onClick`/`onClickCapture`.
161 - */
162 -function recordAllRegistrationNames(eventType, PluginModule) {
163 - var phaseName;
164 - var phasedRegistrationNames = eventType.phasedRegistrationNames;
165 - if (phasedRegistrationNames) {
166 - for (phaseName in phasedRegistrationNames) {
167 - if (!phasedRegistrationNames.hasOwnProperty(phaseName)) {
168 - continue;
169 - }
170 - if (true) {
171 - throwIf(
172 - registrationNames[phasedRegistrationNames[phaseName]],
173 - ERRORS.DOUBLE_REGISTER
174 - );
175 - }
176 - registrationNames[phasedRegistrationNames[phaseName]] = PluginModule;
177 - registrationNamesArr.push(phasedRegistrationNames[phaseName]);
178 - }
179 - } else if (eventType.registrationName) {
180 - if (true) {
181 - throwIf(
182 - registrationNames[eventType.registrationName],
183 - ERRORS.DOUBLE_REGISTER
184 - );
185 - }
186 - registrationNames[eventType.registrationName] = PluginModule;
187 - registrationNamesArr.push(eventType.registrationName);
188 - }
189 -}
190 -
191 -/**
192 - * A hacky way to reverse engineer which event plugin module created an
193 - * AbstractEvent.
194 - * @param {AbstractEvent} abstractEvent to look at
195 - */
196 -function getPluginModuleForAbstractEvent(abstractEvent) {
197 - if (abstractEvent.type.registrationName) {
198 - return registrationNames[abstractEvent.type.registrationName];
199 - } else {
200 - for (var phase in abstractEvent.type.phasedRegistrationNames) {
201 - if (!abstractEvent.type.phasedRegistrationNames.hasOwnProperty(phase)) {
202 - continue;
203 - }
204 - var PluginModule = registrationNames[
205 - abstractEvent.type.phasedRegistrationNames[phase]
206 - ];
207 - if (PluginModule) {
208 - return PluginModule;
209 - }
210 - }
211 - }
212 - return null;
213 -}
214 -
215 -var deleteAllListeners = function(domID) {
216 - var ii;
217 - for (ii = 0; ii < registrationNamesArr.length; ii++) {
218 - deleteListener(domID, registrationNamesArr[ii]);
219 - }
220 -};
221 -
222 -/**
223 - * Accepts the stream of top level native events, and gives every registered
224 - * plugin an opportunity to extract `AbstractEvent`s with annotated dispatches.
225 - *
226 - * @param {Enum} topLevelType Record from `EventConstants`.
227 - * @param {Event} nativeEvent A Standard Event with fixed `target` property.
228 - * @param {Element} renderedTarget Element of interest to the framework, usually
229 - * the same as `nativeEvent.target` but occasionally an element immediately
230 - * above `nativeEvent.target` (the first DOM node recognized as one "rendered"
231 - * by the framework at hand.)
232 - * @param {string} renderedTargetID string ID of `renderedTarget`.
233 - */
234 -var extractAbstractEvents =
235 - function(topLevelType, nativeEvent, renderedTargetID, renderedTarget) {
236 - var abstractEvents;
237 - var plugins = injection.plugins;
238 - var len = plugins.length;
239 - for (var i = 0; i < len; i++) {
240 - // Not every plugin in the ordering may be loaded at runtime.
241 - var possiblePlugin = plugins[i];
242 - var extractedAbstractEvents =
243 - possiblePlugin &&
244 - possiblePlugin.extractAbstractEvents(
245 - topLevelType,
246 - nativeEvent,
247 - renderedTargetID,
248 - renderedTarget
249 - );
250 - if (extractedAbstractEvents) {
251 - abstractEvents = accumulate(abstractEvents, extractedAbstractEvents);
252 - }
253 - }
254 - return abstractEvents;
255 - };
256 -
257 -var enqueueAbstractEvents = function(abstractEvents) {
258 - if (abstractEvents) {
259 - abstractEventQueue = accumulate(abstractEventQueue, abstractEvents);
260 - }
261 -};
262 -
263 -/**
264 - * Executes a single abstract event dispatch. Returns a value, but this return
265 - * value doesn't make much sense when executing dispatches for a list of a
266 - * events. However, if a plugin executes a single dispatch, mostly bypassing
267 - * `EventPluginHub`, it can execute dispatches directly and assign special
268 - * meaning to the return value. So this will return the result of executing the
269 - * dispatch, though for most use cases, it gets dropped.
270 - */
271 -var executeDispatchesAndRelease = function(abstractEvent) {
272 - if (abstractEvent) {
273 - var PluginModule = getPluginModuleForAbstractEvent(abstractEvent);
274 - var pluginExecuteDispatch = PluginModule && PluginModule.executeDispatch;
275 - EventPluginUtils.executeDispatchesInOrder(
276 - abstractEvent,
277 - pluginExecuteDispatch || EventPluginUtils.executeDispatch
278 - );
279 - AbstractEvent.release(abstractEvent);
280 - }
281 -};
282 -
283 -/**
284 - * Sets `abstractEventQueue` to null before processing it, so that we can tell
285 - * if in the process of processing events, more were enqueued. We throw if we
286 - * find that any were enqueued though this use case could be supported in the
287 - * future. For now, throwing an error as it's something we don't expect to
288 - * occur.
289 - */
290 -var processAbstractEventQueue = function() {
291 - var processingAbstractEventQueue = abstractEventQueue;
292 - abstractEventQueue = null;
293 - forEachAccumulated(processingAbstractEventQueue, executeDispatchesAndRelease);
294 - if (true) {
295 - throwIf(abstractEventQueue, ERRORS.DOUBLE_ENQUEUE);
296 - }
297 -};
298 -
299 -/**
300 - * Provides a unified interface for an arbitrary and dynamic set of event
301 - * plugins. Loosely, a hub, where several "event plugins" may act as a single
302 - * event plugin behind the facade of `EventPluginHub`. Each event plugin injects
303 - * themselves into the HUB, and will immediately become operable upon injection.
304 - *
305 - * @constructor EventPluginHub
306 - */
307 -var EventPluginHub = {
308 - registrationNames: registrationNames,
309 - registrationNamesArr: registrationNamesArr,
310 - putListener: CallbackRegistry.putListener,
311 - getListener: CallbackRegistry.getListener,
312 - deleteAllListeners: deleteAllListeners,
313 - extractAbstractEvents: extractAbstractEvents,
314 - enqueueAbstractEvents: enqueueAbstractEvents,
315 - processAbstractEventQueue: processAbstractEventQueue,
316 - injection: injection
317 -};
318 -
319 -
320 -if (ExecutionEnvironment.canUseDOM) {
321 - window.EventPluginHub = EventPluginHub;
322 -}
323 -
324 -module.exports = EventPluginHub;
React/EventPluginUtils.js deleted
-206
@@ -1,206 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EventPluginUtils
17 - */
18 -
19 -"use strict";
20 -
21 -var EventConstants = require("./EventConstants");
22 -var AbstractEvent = require("./AbstractEvent");
23 -
24 -var invariant = require("./invariant");
25 -
26 -var topLevelTypes = EventConstants.topLevelTypes;
27 -
28 -function isEndish(topLevelType) {
29 - return topLevelType === topLevelTypes.topMouseUp ||
30 - topLevelType === topLevelTypes.topTouchEnd ||
31 - topLevelType === topLevelTypes.topTouchCancel;
32 -}
33 -
34 -function isMoveish(topLevelType) {
35 - return topLevelType === topLevelTypes.topMouseMove ||
36 - topLevelType === topLevelTypes.topTouchMove;
37 -}
38 -function isStartish(topLevelType) {
39 - return topLevelType === topLevelTypes.topMouseDown ||
40 - topLevelType === topLevelTypes.topTouchStart;
41 -}
42 -
43 -function storePageCoordsIn(obj, nativeEvent) {
44 - var pageX = AbstractEvent.eventPageX(nativeEvent);
45 - var pageY = AbstractEvent.eventPageY(nativeEvent);
46 - obj.pageX = pageX;
47 - obj.pageY = pageY;
48 -}
49 -
50 -function eventDistance(coords, nativeEvent) {
51 - var pageX = AbstractEvent.eventPageX(nativeEvent);
52 - var pageY = AbstractEvent.eventPageY(nativeEvent);
53 - return Math.pow(
54 - Math.pow(pageX - coords.pageX, 2) + Math.pow(pageY - coords.pageY, 2),
55 - 0.5
56 - );
57 -}
58 -
59 -var validateEventDispatches;
60 -if (true) {
61 - validateEventDispatches = function(abstractEvent) {
62 - var dispatchListeners = abstractEvent._dispatchListeners;
63 - var dispatchIDs = abstractEvent._dispatchIDs;
64 -
65 - var listenersIsArr = Array.isArray(dispatchListeners);
66 - var idsIsArr = Array.isArray(dispatchIDs);
67 - var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
68 - var listenersLen = listenersIsArr ?
69 - dispatchListeners.length :
70 - dispatchListeners ? 1 : 0;
71 -
72 - invariant(
73 - idsIsArr === listenersIsArr && IDsLen === listenersLen,
74 - 'EventPluginUtils: Invalid `abstractEvent`.'
75 - );
76 - };
77 -}
78 -
79 -/**
80 - * Invokes `cb(abstractEvent, listener, id)`. Avoids using call if no scope is
81 - * provided. The `(listener,id)` pair effectively forms the "dispatch" but are
82 - * kept separate to conserve memory.
83 - */
84 -function forEachEventDispatch(abstractEvent, cb) {
85 - var dispatchListeners = abstractEvent._dispatchListeners;
86 - var dispatchIDs = abstractEvent._dispatchIDs;
87 - if (true) {
88 - validateEventDispatches(abstractEvent);
89 - }
90 - if (Array.isArray(dispatchListeners)) {
91 - var i;
92 - for (
93 - i = 0;
94 - i < dispatchListeners.length && !abstractEvent.isPropagationStopped;
95 - i++) {
96 - // Listeners and IDs are two parallel arrays that are always in sync.
97 - cb(abstractEvent, dispatchListeners[i], dispatchIDs[i]);
98 - }
99 - } else if (dispatchListeners) {
100 - cb(abstractEvent, dispatchListeners, dispatchIDs);
101 - }
102 -}
103 -
104 -/**
105 - * Default implementation of PluginModule.executeDispatch().
106 - * @param {AbstractEvent} AbstractEvent to handle
107 - * @param {function} Application-level callback
108 - * @param {string} domID DOM id to pass to the callback.
109 - */
110 -function executeDispatch(abstractEvent, listener, domID) {
111 - listener(abstractEvent, domID);
112 -}
113 -
114 -/**
115 - * Standard/simple iteration through an event's collected dispatches.
116 - */
117 -function executeDispatchesInOrder(abstractEvent, executeDispatch) {
118 - forEachEventDispatch(abstractEvent, executeDispatch);
119 - abstractEvent._dispatchListeners = null;
120 - abstractEvent._dispatchIDs = null;
121 -}
122 -
123 -/**
124 - * Standard/simple iteration through an event's collected dispatches, but stops
125 - * at the first dispatch execution returning true, and returns that id.
126 - *
127 - * @returns id of the first dispatch execution who's listener returns true, or
128 - * null if no listener returned true.
129 - */
130 -function executeDispatchesInOrderStopAtTrue(abstractEvent) {
131 - var dispatchListeners = abstractEvent._dispatchListeners;
132 - var dispatchIDs = abstractEvent._dispatchIDs;
133 - if (true) {
134 - validateEventDispatches(abstractEvent);
135 - }
136 - if (Array.isArray(dispatchListeners)) {
137 - var i;
138 - for (
139 - i = 0;
140 - i < dispatchListeners.length && !abstractEvent.isPropagationStopped;
141 - i++) {
142 - // Listeners and IDs are two parallel arrays that are always in sync.
143 - if (dispatchListeners[i](abstractEvent, dispatchIDs[i])) {
144 - return dispatchIDs[i];
145 - }
146 - }
147 - } else if (dispatchListeners) {
148 - if (dispatchListeners(abstractEvent, dispatchIDs)) {
149 - return dispatchIDs;
150 - }
151 - }
152 - return null;
153 -}
154 -
155 -/**
156 - * Execution of a "direct" dispatch - there must be at most one dispatch
157 - * accumulated on the event or it is considered an error. It doesn't really make
158 - * sense for an event with multiple dispatches (bubbled) to keep track of the
159 - * return values at each dispatch execution, but it does tend to make sense when
160 - * dealing with "direct" dispatches.
161 - *
162 - * @returns The return value of executing the single dispatch.
163 - */
164 -function executeDirectDispatch(abstractEvent) {
165 - if (true) {
166 - validateEventDispatches(abstractEvent);
167 - }
168 - var dispatchListener = abstractEvent._dispatchListeners;
169 - var dispatchID = abstractEvent._dispatchIDs;
170 - invariant(
171 - !Array.isArray(dispatchListener),
172 - 'executeDirectDispatch(...): Invalid `abstractEvent`.'
173 - );
174 - var res = dispatchListener ?
175 - dispatchListener(abstractEvent, dispatchID) :
176 - null;
177 - abstractEvent._dispatchListeners = null;
178 - abstractEvent._dispatchIDs = null;
179 - return res;
180 -}
181 -
182 -/**
183 - * @param {AbstractEvent} abstractEvent
184 - * @returns {bool} True iff number of dispatches accumulated is greater than 0.
185 - */
186 -function hasDispatches(abstractEvent) {
187 - return !!abstractEvent._dispatchListeners;
188 -}
189 -
190 -/**
191 - * General utilities that are useful in creating custom Event Plugins.
192 - */
193 -var EventPluginUtils = {
194 - isEndish: isEndish,
195 - isMoveish: isMoveish,
196 - isStartish: isStartish,
197 - storePageCoordsIn: storePageCoordsIn,
198 - eventDistance: eventDistance,
199 - executeDispatchesInOrder: executeDispatchesInOrder,
200 - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
201 - executeDirectDispatch: executeDirectDispatch,
202 - hasDispatches: hasDispatches,
203 - executeDispatch: executeDispatch
204 -};
205 -
206 -module.exports = EventPluginUtils;
React/EventPropagators.js deleted
-180
@@ -1,180 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule EventPropagators
17 - */
18 -
19 -"use strict";
20 -
21 -var CallbackRegistry = require("./CallbackRegistry");
22 -var EventConstants = require("./EventConstants");
23 -
24 -var accumulate = require("./accumulate");
25 -var forEachAccumulated = require("./forEachAccumulated");
26 -var getListener = CallbackRegistry.getListener;
27 -var PropagationPhases = EventConstants.PropagationPhases;
28 -
29 -/**
30 - * Injected dependencies:
31 - */
32 -
33 -/**
34 - * - `InstanceHandle`: [required] Module that performs logical traversals of DOM
35 - * hierarchy given ids of the logical DOM elements involved.
36 - */
37 -var injection = {
38 - InstanceHandle: null,
39 - injectInstanceHandle: function(InjectedInstanceHandle) {
40 - injection.InstanceHandle = InjectedInstanceHandle;
41 - if (true) {
42 - injection.validate();
43 - }
44 - },
45 - validate: function() {
46 - var invalid = !injection.InstanceHandle||
47 - !injection.InstanceHandle.traverseTwoPhase ||
48 - !injection.InstanceHandle.traverseEnterLeave;
49 - if (invalid) {
50 - throw new Error('InstanceHandle not injected before use!');
51 - }
52 - }
53 -};
54 -
55 -/**
56 - * Some event types have a notion of different registration names for different
57 - * "phases" of propagation. This finds listeners by a given phase.
58 - */
59 -function listenerAtPhase(id, abstractEvent, propagationPhase) {
60 - var registrationName =
61 - abstractEvent.type.phasedRegistrationNames[propagationPhase];
62 - return getListener(id, registrationName);
63 -}
64 -
65 -/**
66 - * Tags an `AbstractEvent` with dispatched listeners. Creating this function
67 - * here, allows us to not have to bind or create functions for each event.
68 - * Mutating the event's members allows us to not have to create a wrapping
69 - * "dispatch" object that pairs the event with the listener.
70 - */
71 -function accumulateDirectionalDispatches(domID, upwards, abstractEvent) {
72 - if (true) {
73 - if (!domID) {
74 - throw new Error('Dispatching id must not be null');
75 - }
76 - injection.validate();
77 - }
78 - var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
79 - var listener = listenerAtPhase(domID, abstractEvent, phase);
80 - if (listener) {
81 - abstractEvent._dispatchListeners =
82 - accumulate(abstractEvent._dispatchListeners, listener);
83 - abstractEvent._dispatchIDs = accumulate(abstractEvent._dispatchIDs, domID);
84 - }
85 -}
86 -
87 -/**
88 - * Collect dispatches (must be entirely collected before dispatching - see unit
89 - * tests). Lazily allocate the array to conserve memory. We must loop through
90 - * each event and perform the traversal for each one. We can not perform a
91 - * single traversal for the entire collection of events because each event may
92 - * have a different target.
93 - */
94 -function accumulateTwoPhaseDispatchesSingle(abstractEvent) {
95 - if (abstractEvent && abstractEvent.type.phasedRegistrationNames) {
96 - injection.InstanceHandle.traverseTwoPhase(
97 - abstractEvent.abstractTargetID,
98 - accumulateDirectionalDispatches,
99 - abstractEvent
100 - );
101 - }
102 -}
103 -
104 -
105 -/**
106 - * Accumulates without regard to direction, does not look for phased
107 - * registration names. Same as `accumulateDirectDispatchesSingle` but without
108 - * requiring that the `abstractTargetID` be the same as the dispatched ID.
109 - */
110 -function accumulateDispatches(id, ignoredDirection, abstractEvent) {
111 - if (abstractEvent && abstractEvent.type.registrationName) {
112 - var listener = getListener(id, abstractEvent.type.registrationName);
113 - if (listener) {
114 - abstractEvent._dispatchListeners =
115 - accumulate(abstractEvent._dispatchListeners, listener);
116 - abstractEvent._dispatchIDs = accumulate(abstractEvent._dispatchIDs, id);
117 - }
118 - }
119 -}
120 -
121 -/**
122 - * Accumulates dispatches on an `AbstractEvent`, but only for the
123 - * `abstractTargetID`.
124 - * @param {AbstractEvent} abstractEvent
125 - */
126 -function accumulateDirectDispatchesSingle(abstractEvent) {
127 - if (abstractEvent && abstractEvent.type.registrationName) {
128 - accumulateDispatches(abstractEvent.abstractTargetID, null, abstractEvent);
129 - }
130 -}
131 -
132 -function accumulateTwoPhaseDispatches(abstractEvents) {
133 - if (true) {
134 - injection.validate();
135 - }
136 - forEachAccumulated(abstractEvents, accumulateTwoPhaseDispatchesSingle);
137 -}
138 -
139 -function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
140 - if (true) {
141 - injection.validate();
142 - }
143 - injection.InstanceHandle.traverseEnterLeave(
144 - fromID,
145 - toID,
146 - accumulateDispatches,
147 - leave,
148 - enter
149 - );
150 -}
151 -
152 -
153 -function accumulateDirectDispatches(abstractEvents) {
154 - if (true) {
155 - injection.validate();
156 - }
157 - forEachAccumulated(abstractEvents, accumulateDirectDispatchesSingle);
158 -}
159 -
160 -
161 -
162 -/**
163 - * A small set of propagation patterns, each of which will accept a small amount
164 - * of information, and generate a set of "dispatch ready event objects" - which
165 - * are sets of events that have already been annotated with a set of dispatched
166 - * listener functions/ids. The API is designed this way to discourage these
167 - * propagation strategies from actually executing the dispatches, since we
168 - * always want to collect the entire set of dispatches before executing event a
169 - * single one.
170 - *
171 - * @constructor EventPropagators
172 - */
173 -var EventPropagators = {
174 - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
175 - accumulateDirectDispatches: accumulateDirectDispatches,
176 - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
177 - injection: injection
178 -};
179 -
180 -module.exports = EventPropagators;
React/ExecutionEnvironment.js deleted
-43
@@ -1,43 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ExecutionEnvironment
17 - */
18 -
19 -/*jslint evil: true */
20 -
21 -"use strict";
22 -
23 -var canUseDOM = typeof window !== 'undefined';
24 -
25 -/**
26 - * Simple, lightweight module assisting with the detection and context of
27 - * Worker. Helps avoid circular dependencies and allows code to reason about
28 - * whether or not they are in a Worker, even if they never include the main
29 - * `ReactWorker` dependency.
30 - */
31 -var ExecutionEnvironment = {
32 -
33 - canUseDOM: canUseDOM,
34 -
35 - canUseWorkers: typeof Worker !== 'undefined',
36 -
37 - isInWorker: !canUseDOM, // For now, this is true - might change in the future.
38 -
39 - global: new Function('return this;')()
40 -
41 -};
42 -
43 -module.exports = ExecutionEnvironment;
React/ImmutableObject.js deleted
-168
@@ -1,168 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ImmutableObject
17 - */
18 -
19 -"use strict";
20 -
21 -var keyMirror = require("./keyMirror");
22 -var merge = require("./merge");
23 -var mergeInto = require("./mergeInto");
24 -var mergeHelpers = require("./mergeHelpers");
25 -var throwIf = require("./throwIf");
26 -
27 -var checkMergeObjectArgs = mergeHelpers.checkMergeObjectArgs;
28 -var isTerminal = mergeHelpers.isTerminal;
29 -
30 -/**
31 - * Simple wrapper around javascript key/value objects that provide a dev time
32 - * guarantee of immutability (assuming all modules that may potentially mutate
33 - * include a "use strict" declaration). Retaining immutability requires CPU
34 - * cycles (in order to perform the freeze), but this computation can be avoided
35 - * in production. The fact that mutation attempts in __DEV__ will be caught,
36 - * allows us to reasonably assume that mutation on those objects won't even be
37 - * attempted in production. This means that an object being an instanceof
38 - * `ImmutableObject` implies that the object may never change.
39 - *
40 - * TODO: Require strict mode in source files that use ImmutableObject (lint
41 - * rule).
42 - *
43 - * @class ImmutableObject
44 - */
45 -
46 -var ERRORS;
47 -var ImmutableObject;
48 -
49 -if (true) {
50 - ERRORS = {
51 - INVALID_MAP_SET_ARG: 'You have attempted to set fields on an object that ' +
52 - 'is not an instance of ImmutableObject'
53 - };
54 -
55 - /**
56 - * Constructs an instance of `ImmutableObject`.
57 - *
58 - * @param {!Object} initMap The initial set of properties.
59 - * @constructor
60 - */
61 - ImmutableObject = function(initMap) {
62 - mergeInto(this, initMap);
63 - deepFreeze(this, initMap);
64 - };
65 -
66 - /**
67 - * Objects that are instances of `ImmutableObject` are assumed to be deep
68 - * frozen.
69 - * @param {!Object} o The object to deep freeze.
70 - * @return {!boolean} Whether or not deep freeze is needed.
71 - */
72 - var shouldRecurseFreeze = function(o) {
73 - return (typeof o) === 'object' &&
74 - !(o instanceof ImmutableObject) && o !== null;
75 - };
76 -
77 - /**
78 - * Freezes an object `o` deeply. Invokes `shouldRecurseFreeze` to determine if
79 - * further freezing is needed.
80 - *
81 - * @param {!Object} o The object to freeze.
82 - */
83 - var deepFreeze = function(o) {
84 - var prop;
85 - Object.freeze(o); // First freeze the object.
86 - for (prop in o) {
87 - var field = o[prop];
88 - if (o.hasOwnProperty(prop) && shouldRecurseFreeze(field)) {
89 - deepFreeze(field);
90 - }
91 - }
92 - };
93 -
94 - /**
95 - * Returns a new ImmutableObject that is that is the same as the parameter
96 - * `immutableObject` but with the differences specified in `put`.
97 - * @param {!ImmutableObject} ImmutableObject The ImmutableObject object to set
98 - * fields on.
99 - * @param {!Object} put Subset of fields to merge into the returned result.
100 - * @return {!ImmutableObject} The result of merging in `put` fields.
101 - */
102 - ImmutableObject.set = function(immutableObject, put) {
103 - throwIf(
104 - !(immutableObject instanceof ImmutableObject),
105 - ERRORS.INVALID_MAP_SET_ARG
106 - );
107 - var totalNewFields = merge(immutableObject, put);
108 - return new ImmutableObject(totalNewFields);
109 - };
110 -
111 -}
112 -
113 -/**
114 - * Sugar for `ImmutableObject.set(ImmutableObject, {fieldName: putField})`
115 - * @see ImmutableObject.set
116 - */
117 -ImmutableObject.setField = function(immutableObject, fieldName, putField) {
118 - var put = {};
119 - put[fieldName] = putField;
120 - return ImmutableObject.set(immutableObject, put);
121 -};
122 -
123 -/**
124 - * Returns a new ImmutableObject that is that is the same as the parameter
125 - * `immutableObject` but with the differences specified in `put` recursively
126 - * applied.
127 - */
128 -ImmutableObject.setDeep = function(immutableObject, put) {
129 - throwIf(
130 - !(immutableObject instanceof ImmutableObject),
131 - ERRORS.INVALID_MAP_SET_ARG
132 - );
133 - return _setDeep(immutableObject, put);
134 -};
135 -
136 -function _setDeep(object, put) {
137 - checkMergeObjectArgs(object, put);
138 - var totalNewFields = {};
139 -
140 - // To maintain the order of the keys, copy the base object's entries first.
141 - var keys = Object.keys(object);
142 - for (var ii = 0; ii < keys.length; ii++) {
143 - var key = keys[ii];
144 - if (!put.hasOwnProperty(key)) {
145 - totalNewFields[key] = object[key];
146 - } else if (isTerminal(object[key]) || isTerminal(put[key])) {
147 - totalNewFields[key] = put[key];
148 - } else {
149 - totalNewFields[key] = _setDeep(object[key], put[key]);
150 - }
151 - }
152 -
153 - // Apply any new keys that the base object didn't have.
154 - var newKeys = Object.keys(put);
155 - for (ii = 0; ii < newKeys.length; ii++) {
156 - var newKey = newKeys[ii];
157 - if (object.hasOwnProperty(newKey)) {
158 - continue;
159 - }
160 - totalNewFields[newKey] = put[newKey];
161 - }
162 -
163 - return (object instanceof ImmutableObject || put instanceof ImmutableObject) ?
164 - new ImmutableObject(totalNewFields) :
165 - totalNewFields;
166 -}
167 -
168 -module.exports = ImmutableObject;
React/NormalizedEventListener.js deleted
-88
@@ -1,88 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule NormalizedEventListener
17 - */
18 -
19 -"use strict";
20 -
21 -var EventListener = require("./EventListener");
22 -
23 -/**
24 - * @param {?Event} eventParam Event parameter from an attached listener.
25 - * @return {Event} Normalized event object.
26 - * @private
27 - */
28 -function normalizeEvent(eventParam) {
29 - var normalized = eventParam || window.event;
30 - // In some browsers (OLD FF), setting the target throws an error. A good way
31 - // to tell if setting the target will throw an error, is to check if the event
32 - // has a `target` property. Safari events have a `target` but it's not always
33 - // normalized. Even if a `target` property exists, it's good to only set the
34 - // target property if we realize that a change will actually take place.
35 - var hasTargetProperty = 'target' in normalized;
36 - var eventTarget = normalized.target || normalized.srcElement || window;
37 - // Safari may fire events on text nodes (Node.TEXT_NODE is 3)
38 - // @see http://www.quirksmode.org/js/events_properties.html
39 - var textNodeNormalizedTarget =
40 - (eventTarget.nodeType === 3) ? eventTarget.parentNode : eventTarget;
41 - if (!hasTargetProperty || normalized.target !== textNodeNormalizedTarget) {
42 - // Create an object that inherits from the native event so that we can set
43 - // `target` on it. (It is read-only and setting it throws in strict mode).
44 - normalized = Object.create(normalized);
45 - normalized.target = textNodeNormalizedTarget;
46 - }
47 - return normalized;
48 -}
49 -
50 -function createNormalizedCallback(cb) {
51 - return function(unfixedNativeEvent) {
52 - cb(normalizeEvent(unfixedNativeEvent));
53 - };
54 -}
55 -
56 -var NormalizedEventListener = {
57 -
58 - /**
59 - * Listens to bubbled events on a DOM node.
60 - *
61 - * NOTE: The listener will be invoked with a normalized event object.
62 - *
63 - * @param {DOMElement} el DOM element to register listener on.
64 - * @param {string} handlerBaseName Event name, e.g. "click".
65 - * @param {function} cb Callback function.
66 - * @public
67 - */
68 - listen: function(el, handlerBaseName, cb) {
69 - EventListener.listen(el, handlerBaseName, createNormalizedCallback(cb));
70 - },
71 -
72 - /**
73 - * Listens to captured events on a DOM node.
74 - *
75 - * NOTE: The listener will be invoked with a normalized event object.
76 - *
77 - * @param {DOMElement} el DOM element to register listener on.
78 - * @param {string} handlerBaseName Event name, e.g. "click".
79 - * @param {function} cb Callback function.
80 - * @public
81 - */
82 - capture: function(el, handlerBaseName, cb) {
83 - EventListener.capture(el, handlerBaseName, createNormalizedCallback(cb));
84 - }
85 -
86 -};
87 -
88 -module.exports = NormalizedEventListener;
React/OrderedMap.js deleted
-514
@@ -1,514 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule OrderedMap
17 - */
18 -
19 -"use strict";
20 -
21 -var mixInto = require("./mixInto");
22 -var throwIf = require("./throwIf");
23 -
24 -var PREFIX = 'key:';
25 -
26 -var ARRAY_MUST_CB = 'ARRAY_MUST_CB';
27 -var INVALID_KEY = 'INVALID_KEY';
28 -var DUPLICATE_KEY = 'DUPLICATE_KEY';
29 -var OPERATION_ARGS = 'OPERATION_ARGS';
30 -var RANGE_ARGS = 'RANGE_ARGS';
31 -var NO_EXIST = 'NO_EXIST';
32 -
33 -if (true) {
34 - ARRAY_MUST_CB =
35 - 'If providing an array to an OrderedMap constructor, you must provide ' +
36 - 'a callback that may determine the uniqueue key for each entry. ' +
37 - 'The key that you return from the callback should uniquely define that ' +
38 - 'entity. What is returned from that function must answer the question: ' +
39 - '"If you were to shuffle the array of entities, how would you be able to ' +
40 - 'determine the identity of the Array entry?"';
41 - INVALID_KEY =
42 - 'Key must be non-empty, non-null, string or number';
43 - DUPLICATE_KEY =
44 - 'At creation time, you must extract out IDs that are unique.';
45 - OPERATION_ARGS =
46 - 'Invalid argument type for construction or operation on OrderedMap. ' +
47 - 'from/merge accepts another OrderedMap. fromArray accepts an Array ' +
48 - 'and a callback to extract a unique ID.';
49 - RANGE_ARGS =
50 - 'OrderedMap.mapRange requires end of range to be >= start, start to be ' +
51 - '>= 0 and end < length.';
52 - NO_EXIST =
53 - 'The requested key does not exist in the OrderedMap';
54 -}
55 -
56 -/**
57 - * Utility to extract a backing object from an initialization `Array`, allowing
58 - * the caller to assist in resolving the unique ID for each entry via the
59 - * `keyExtractor` callback. The `keyExtractor` must extract non-empty strings or
60 - * numbers.
61 - * @param {Array<Object!>} arr Array of items.
62 - * @param {function} keyExtractor Extracts a unique key from each item.
63 - * @return {Object} Map from unique key to originating value that the key was
64 - * extracted from.
65 - * @throws Exception if the initialization array has duplicate extracted keys.
66 - */
67 -function extractObjectFromArray(arr, keyExtractor) {
68 - var normalizedObj = {};
69 - for (var i=0; i < arr.length; i++) {
70 - var item = arr[i];
71 - var key = keyExtractor(item);
72 - validatePublicKey(key);
73 - var normalizedKey = PREFIX + key;
74 - throwIf(normalizedKey in normalizedObj, DUPLICATE_KEY);
75 - normalizedObj[normalizedKey] = item;
76 - }
77 - return normalizedObj;
78 -}
79 -
80 -/**
81 - * Utility class for mappings with ordering. This class is to be used in an
82 - * immutable manner. A `OrderedMap` is very much like the native JavaScript
83 - * object, where keys map to values via the `get()` function. Also, like the
84 - * native JavaScript object, there is an ordering associated with the mapping.
85 - * This class is helpful because it eliminates many of the pitfalls that come
86 - * with the native JavaScript ordered mappings. Specifically, there are
87 - * inconsistencies with numeric keys in some JavaScript implementations
88 - * (enumeration ordering). This class protects against those pitfalls and
89 - * provides functional utilities for dealing with these `OrderedMap`s.
90 - *
91 - * - TODO:
92 - * - orderedMergeExclusive: Merges mutually exclusive `OrderedMap`s.
93 - * - mapReverse().
94 - *
95 - * @class {OrderedMap}
96 - * @constructor {OrderedMap}
97 - * @param {Object} normalizedObj Object that is known to be a defensive copy of
98 - * caller supplied data. We require a defensive copy to guard against callers
99 - * mutating. It is also assumed that the keys of `normalizedObj` have been
100 - * normalized and do not contain any numeric-appearing strings.
101 - * @param {number} computedLength The precomputed length of `_normalizedObj`
102 - * keys.
103 - * @private
104 - */
105 -function OrderedMapImpl(normalizedObj, computedLength) {
106 - this._normalizedObj = normalizedObj;
107 - this._computedPositions = null;
108 - this.length = computedLength;
109 -}
110 -
111 -/**
112 - * Validates a "public" key - that is, one that the public facing API supplies.
113 - * The key is then normalized for internal storage. In order to be considered
114 - * valid, all keys must be non-empty, defined, non-null strings or numbers.
115 - * Since this already costs a function invocation, will avoid additional call to
116 - * `throwIf`.
117 - *
118 - * @param {string?} key Validates that the key is suitable for use in a
119 - * `OrderedMap`.
120 - * @throws Error if key is not appropriate for use in `OrderedMap`.
121 - */
122 -function validatePublicKey(key) {
123 - var isEmpty = key === '';
124 - var correctKeyType = typeof key === 'string' || typeof key === 'number';
125 - if (isEmpty || !correctKeyType) {
126 - throw new Error(INVALID_KEY);
127 - }
128 -}
129 -
130 -/**
131 - * Validates that arguments to range operations are within the correct limits.
132 - *
133 - * @param {number} start Start of range.
134 - * @param {number} length Length of range.
135 - * @param {number} actualLen Actual length of range that should not be
136 - * exceeded.
137 - * @return {void} description
138 - */
139 -function validateRangeIndices(start, length, actualLen) {
140 - var startType = typeof start;
141 - var lengthType = typeof length;
142 - var invalid =
143 - startType !== 'number' || lengthType !== 'number' ||
144 - length < 0 || start < 0 || start + length > actualLen;
145 - if (invalid) {
146 - throw new Error(RANGE_ARGS);
147 - }
148 -}
149 -
150 -/**
151 - * Merges two "normalized" objects (objects who's key have been normalized) into
152 - * a `OrderedMap`.
153 - *
154 - * @param {Object} a Object of key value pairs.
155 - * @param {Object} b Object of key value pairs.
156 - * @return {OrderedMap} new `OrderedMap` that results in merging `a` and `b`.
157 - */
158 -function _fromNormalizedObjects(a, b) {
159 - // Second optional, both must be a Plain Old JavaScript Object.
160 - var invalidArgs =
161 - !a || a.constructor !== Object || (b && b.constructor !== Object);
162 - throwIf(invalidArgs, OPERATION_ARGS);
163 - var newSet = {};
164 - var length = 0;
165 - var key;
166 - for (key in a) {
167 - if (a.hasOwnProperty(key)) {
168 - newSet[key] = a[key];
169 - length++;
170 - }
171 - }
172 -
173 - for (key in b) {
174 - if (b.hasOwnProperty(key)) {
175 - // Increment length if not already added via first object (a)
176 - if (!(key in newSet)) {
177 - length++;
178 - }
179 - newSet[key] = b[key];
180 - }
181 - }
182 - return new OrderedMapImpl(newSet, length);
183 -}
184 -
185 -/**
186 - * Methods for `OrderedMap` instances.
187 - *
188 - * @lends OrderedMap.prototype
189 - * TODO: Make this data structure lazy, unify with LazyArray.
190 - * TODO: Unify this with ImmutableObject - it is to be used immutably.
191 - * TODO: If so, consider providing `fromObject` API.
192 - * TODO: Create faster implementation of merging/mapping from original Array,
193 - * without having to first create an object - simply for the sake of merging.
194 - */
195 -var OrderedMapMethods = {
196 -
197 - /**
198 - * Returns whether or not a given key is present in the map.
199 - *
200 - * @param {string} key Valid string key to lookup membership for.
201 - * @return {boolean} Whether or not `key` is a member of the map.
202 - * @throws Error if provided known invalid key.
203 - */
204 - has: function(key) {
205 - validatePublicKey(key);
206 - var normalizedKey = PREFIX + key;
207 - return normalizedKey in this._normalizedObj;
208 - },
209 -
210 - /**
211 - * Returns the object for a given key, or `undefined` if not present. To
212 - * distinguish a undefined entry vs not being in the set, use `has()`.
213 - *
214 - * @param {string} key String key to lookup the value for.
215 - * @return {Object?} Object at key `key`, or undefined if not in map.
216 - * @throws Error if provided known invalid key.
217 - */
218 - get: function(key) {
219 - validatePublicKey(key);
220 - var normalizedKey = PREFIX + key;
221 - return this.has(key) ? this._normalizedObj[normalizedKey] : undefined;
222 - },
223 -
224 - /**
225 - * Merges, appending new keys to the end of the ordering. Keys in `orderedMap`
226 - * that are redundant with `this`, maintain the same ordering index that they
227 - * had in `this`. This is how standard JavaScript object merging would work.
228 - * If you wish to prepend a `OrderedMap` to the beginning of another
229 - * `OrderedMap` then simply reverse the order of operation. This is the analog
230 - * to `merge(x, y)`.
231 - *
232 - * @param {OrderedMap} orderedMap OrderedMap to merge onto the end.
233 - * @return {OrderedMap} New OrderedMap that represents the result of the
234 - * merge.
235 - */
236 - merge: function(orderedMap) {
237 - throwIf(!(orderedMap instanceof OrderedMapImpl), OPERATION_ARGS);
238 - return _fromNormalizedObjects(
239 - this._normalizedObj,
240 - orderedMap._normalizedObj
241 - );
242 - },
243 -
244 - /**
245 - * Functional map API. Returns a new `OrderedMap`.
246 - *
247 - * @param {Function} cb Callback to invoke for each item.
248 - * @param {Object?=} context Context to invoke callback from.
249 - * @returns {OrderedMap} OrderedMap that results from mapping.
250 - */
251 - map: function(cb, context) {
252 - return this.mapRange(cb, 0, this.length, context);
253 - },
254 -
255 - /**
256 - * The callback `cb` is invoked with the arguments (item, key,
257 - * indexInOriginal).
258 - *
259 - * @param {Function} cb Determines result for each item.
260 - * @param {number} start Start index of map range.
261 - * @param {end} end End index of map range.
262 - * @param {*!?} context Context of callback invocation.
263 - * @return {OrderedMap} OrderedMap resulting from mapping the range.
264 - */
265 - mapRange: function(cb, start, length, context) {
266 - var thisSet = this._normalizedObj;
267 - var newSet = {};
268 - var i = 0;
269 - validateRangeIndices(start, length, this.length);
270 - var end = start + length - 1;
271 - for (var key in thisSet) {
272 - if (thisSet.hasOwnProperty(key)) {
273 - if (i >= start) {
274 - if (i > end) {
275 - break;
276 - }
277 - var item = thisSet[key];
278 - newSet[key] = cb.call(context, item, key.substr(PREFIX.length), i);
279 - }
280 - i++;
281 - }
282 - }
283 - return new OrderedMapImpl(newSet, length);
284 - },
285 -
286 - /**
287 - * Function filter API. Returns new `OrderedMap`.
288 - *
289 - * @param {Function} cb Callback to invoke for each item.
290 - * @param {Object?=} context Context to invoke callback from.
291 - * @returns {OrderedMap} OrderedMap that results from filtering.
292 - */
293 - filter: function(cb, context) {
294 - return this.filterRange(cb, 0, this.length, context);
295 - },
296 -
297 - /**
298 - * The callback `cb` is invoked with the arguments (item, key,
299 - * indexInOriginal).
300 - *
301 - * @param {Function} cb Returns true if item should be in result.
302 - * @param {number} start Start index of filter range.
303 - * @param {number} end End index of map range.
304 - * @param {*!?} context Context of callback invocation.
305 - * @return {OrderedMap} OrderedMap resulting from filtering the range.
306 - */
307 - filterRange: function(cb, start, length, context) {
308 - var newSet = {};
309 - var newSetLength = 0;
310 - this.forEachRange(function(item, key, originalIndex) {
311 - if (cb.call(context, item, key, originalIndex)) {
312 - var normalizedKey = PREFIX + key;
313 - newSet[normalizedKey] = item;
314 - newSetLength++;
315 - }
316 - }, start, length);
317 - return new OrderedMapImpl(newSet, newSetLength);
318 - },
319 -
320 - forEach: function(cb, context) {
321 - this.forEachRange(cb, 0, this.length, context);
322 - },
323 -
324 - forEachRange: function(cb, start, length, context) {
325 - validateRangeIndices(start, length, this.length);
326 - var thisSet = this._normalizedObj;
327 - var i = 0;
328 - var end = start + length - 1;
329 - for (var key in thisSet) {
330 - if (thisSet.hasOwnProperty(key)) {
331 - if (i >= start) {
332 - if (i > end) {
333 - break;
334 - }
335 - var item = thisSet[key];
336 - cb.call(context, item, key.substr(PREFIX.length), i);
337 - }
338 - i++;
339 - }
340 - }
341 - },
342 -
343 - /**
344 - * Even though `mapRange`/`forEachKeyRange` allow zero length mappings, we'll
345 - * impose an additional restriction here that the length of mapping be greater
346 - * than zero - the only reason is that there are many ways to express length
347 - * zero in terms of two keys and that is confusing.
348 - */
349 - mapKeyRange: function(cb, startKey, endKey, context) {
350 - var startIndex = this.indexOfKey(startKey);
351 - var endIndex = this.indexOfKey(endKey);
352 - if (endIndex < startIndex) {
353 - throw new Error(RANGE_ARGS);
354 - }
355 - return this.mapRange(cb, startIndex, (endIndex - startIndex) + 1, context);
356 - },
357 -
358 - forEachKeyRange: function(cb, startKey, endKey, context) {
359 - var startIndex = this.indexOfKey(startKey);
360 - var endIndex = this.indexOfKey(endKey);
361 - if (endIndex < startIndex) {
362 - throw new Error(RANGE_ARGS);
363 - }
364 - this.forEachRange(cb, startIndex, (endIndex - startIndex) + 1, context);
365 - },
366 -
367 - /**
368 - * @param {number} pos Index to search for key at.
369 - * @return {string|undefined} Either the key at index `pos` or undefined if
370 - * not in map.
371 - */
372 - keyAtIndex: function(pos) {
373 - var computedPositions = this._getOrComputePositions();
374 - var keyAtPos = computedPositions.keyByIndex[pos];
375 - return keyAtPos ? keyAtPos.substr(PREFIX.length) : undefined;
376 - },
377 -
378 - /**
379 - * @param {string} key String key from which to find the next key.
380 - * @return {string|undefined} Either the next key, or undefined if there is no
381 - * next key.
382 - * @throws Error if `key` is not in this `OrderedMap`.
383 - */
384 - keyAfter: function(key) {
385 - return this.nthKeyAfter(key, 1);
386 - },
387 -
388 - /**
389 - * @param {string} key String key from which to find the preceding key.
390 - * @return {string|undefined} Either the preceding key, or undefined if there
391 - * is no preceding.key.
392 - * @throws Error if `key` is not in this `OrderedMap`.
393 - */
394 - keyBefore: function(key) {
395 - return this.nthKeyBefore(key, 1);
396 - },
397 -
398 - /**
399 - * @param {string} key String key from which to find a following key.
400 - * @param {number} n Distance to scan forward after `key`.
401 - * @return {string|undefined} Either the nth key after `key`, or undefined if
402 - * there is no next key.
403 - * @throws Error if `key` is not in this `OrderedMap`.
404 - */
405 - nthKeyAfter: function(key, n) {
406 - var curIndex = this.indexOfKey(key);
407 - throwIf(curIndex === undefined, NO_EXIST);
408 - return this.keyAtIndex(curIndex + n);
409 - },
410 -
411 - /**
412 - * @param {string} key String key from which to find a preceding key.
413 - * @param {number} n Distance to scan backwards before `key`.
414 - * @return {string|undefined} Either the nth key before `key`, or undefined if
415 - * there is no previous key.
416 - * @throws Error if `key` is not in this `OrderedMap`.
417 - */
418 - nthKeyBefore: function(key, n) {
419 - return this.nthKeyAfter(key, -n);
420 - },
421 -
422 - /**
423 - * @param {string} key Key to find the index of.
424 - * @return {number|undefined} Index of the provided key, or `undefined` if the
425 - * key is not found.
426 - */
427 - indexOfKey: function(key) {
428 - validatePublicKey(key);
429 - var normalizedKey = PREFIX + key;
430 - var computedPositions = this._getOrComputePositions();
431 - var computedPosition = computedPositions.indexByKey[normalizedKey];
432 - // Just writing it this way to make it clear this is intentional.
433 - return computedPosition === undefined ? undefined : computedPosition;
434 - },
435 -
436 - /**
437 - * @return {Array} An ordered array of this object's values.
438 - */
439 - toArray: function() {
440 - var result = [];
441 - var thisSet = this._normalizedObj;
442 - for (var key in thisSet) {
443 - if (thisSet.hasOwnProperty(key)) {
444 - result.push(thisSet[key]);
445 - }
446 - }
447 - return result;
448 - },
449 -
450 - /**
451 - * Finds the key at a given position, or indicates via `undefined` that that
452 - * position does not exist in the `OrderedMap`. It is appropriate to return
453 - * undefined, indicating that the key doesn't exist in the `OrderedMap`
454 - * because `undefined` is not ever a valid `OrderedMap` key.
455 - *
456 - * @private
457 - * @param {number} pos Position for which we're querying the name.
458 - * @return {string?} Name of the item at position `pos`, or `undefined` if
459 - * there is no item at that position.
460 - */
461 - _getOrComputePositions: function() {
462 - // TODO: Entertain computing this at construction time in some less
463 - // performance critical paths.
464 - var computedPositions = this._computedPositions;
465 - if (!computedPositions) {
466 - this._computePositions();
467 - }
468 - return this._computedPositions;
469 - },
470 -
471 - /**
472 - * Precomputes the index/key mapping for future lookup. Since `OrderedMap`s
473 - * are immutable, there is only ever a need to perform this once.
474 - * @private
475 - */
476 - _computePositions: function() {
477 - this._computedPositions = {
478 - keyByIndex: {},
479 - indexByKey: {}
480 - };
481 - var keyByIndex = this._computedPositions.keyByIndex;
482 - var indexByKey = this._computedPositions.indexByKey;
483 - var index = 0;
484 - var thisSet = this._normalizedObj;
485 - for (var key in thisSet) {
486 - if (thisSet.hasOwnProperty(key)) {
487 - keyByIndex[index] = key;
488 - indexByKey[key] = index;
489 - index++;
490 - }
491 - }
492 - }
493 -};
494 -
495 -mixInto(OrderedMapImpl, OrderedMapMethods);
496 -
497 -var OrderedMap = {
498 - from: function(orderedMap) {
499 - var invalidArg = !(orderedMap instanceof OrderedMapImpl);
500 - throwIf(invalidArg, OPERATION_ARGS);
501 - return _fromNormalizedObjects(orderedMap._normalizedObj, null);
502 - },
503 -
504 - fromArray: function(arr, keyExtractor) {
505 - throwIf(!Array.isArray(arr), OPERATION_ARGS);
506 - throwIf(!keyExtractor, ARRAY_MUST_CB);
507 - return new OrderedMapImpl(
508 - extractObjectFromArray(arr, keyExtractor),
509 - arr.length
510 - );
511 - }
512 -};
513 -
514 -module.exports = OrderedMap;
React/PooledClass.js deleted
-101
@@ -1,101 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule PooledClass
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Static poolers. Several custom versions for each potential number of
23 - * arguments. A completely generic pooler is easy to implement, but would
24 - * require accessing the `arguments` object. In each of these, `this` refers to
25 - * the Class itself, not an instance. If any others are needed, simply add them
26 - * here, or in their own files.
27 - */
28 -var oneArgumentPooler = function(copyFieldsFrom) {
29 - var Klass = this;
30 - if (Klass.instancePool.length) {
31 - var instance = Klass.instancePool.pop();
32 - Klass.call(instance, copyFieldsFrom);
33 - return instance;
34 - } else {
35 - return new Klass(copyFieldsFrom);
36 - }
37 -};
38 -
39 -var twoArgumentPooler = function(a1, a2) {
40 - var Klass = this;
41 - if (Klass.instancePool.length) {
42 - var instance = Klass.instancePool.pop();
43 - Klass.call(instance, a1, a2);
44 - return instance;
45 - } else {
46 - return new Klass(a1, a2);
47 - }
48 -};
49 -
50 -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
51 - var Klass = this;
52 - if (Klass.instancePool.length) {
53 - var instance = Klass.instancePool.pop();
54 - Klass.call(instance, a1, a2, a3, a4, a5);
55 - return instance;
56 - } else {
57 - return new Klass(a1, a2, a3, a4, a5);
58 - }
59 -};
60 -
61 -var standardReleaser = function(instance) {
62 - var Klass = this;
63 - if (instance.destructor) {
64 - instance.destructor();
65 - }
66 - if (Klass.instancePool.length < Klass.poolSize) {
67 - Klass.instancePool.push(instance);
68 - }
69 -};
70 -
71 -var DEFAULT_POOL_SIZE = 10;
72 -var DEFAULT_POOLER = oneArgumentPooler;
73 -
74 -/**
75 - * Augments `CopyConstructor` to be a poolable class, augmenting only the class
76 - * itself (statically) not adding any prototypical fields. Any CopyConstructor
77 - * you give this may have a `poolSize` property, and will look for a
78 - * prototypical `destructor` on instances (optional).
79 - *
80 - * @param {Function} CopyConstructor Constructor that can be used to reset.
81 - * @param {Function} pooler Customizable pooler.
82 - */
83 -var addPoolingTo = function(CopyConstructor, pooler) {
84 - var NewKlass = CopyConstructor;
85 - NewKlass.instancePool = [];
86 - NewKlass.getPooled = pooler || DEFAULT_POOLER;
87 - if (!NewKlass.poolSize) {
88 - NewKlass.poolSize = DEFAULT_POOL_SIZE;
89 - }
90 - NewKlass.release = standardReleaser;
91 - return NewKlass;
92 -};
93 -
94 -var PooledClass = {
95 - addPoolingTo: addPoolingTo,
96 - oneArgumentPooler: oneArgumentPooler,
97 - twoArgumentPooler: twoArgumentPooler,
98 - fiveArgumentPooler: fiveArgumentPooler
99 -};
100 -
101 -module.exports = PooledClass;
React/React.js deleted
-45
@@ -1,45 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule React
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactCompositeComponent = require("./ReactCompositeComponent");
22 -var ReactComponent = require("./ReactComponent");
23 -var ReactDOM = require("./ReactDOM");
24 -var ReactMount = require("./ReactMount");
25 -
26 -var ReactDefaultInjection = require("./ReactDefaultInjection");
27 -
28 -ReactDefaultInjection.inject();
29 -
30 -var React = {
31 - DOM: ReactDOM,
32 - initializeTouchEvents: function(shouldUseTouch) {
33 - ReactMount.useTouchEvents = shouldUseTouch;
34 - },
35 - autoBind: ReactCompositeComponent.autoBind,
36 - createClass: ReactCompositeComponent.createClass,
37 - createComponentRenderer: ReactMount.createComponentRenderer,
38 - constructAndRenderComponent: ReactMount.constructAndRenderComponent,
39 - constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
40 - renderComponent: ReactMount.renderComponent,
41 - unmountAndReleaseReactRootNode: ReactMount.unmountAndReleaseReactRootNode,
42 - isValidComponent: ReactComponent.isValidComponent
43 -};
44 -
45 -module.exports = React;
React/ReactComponent.js deleted
-402
@@ -1,402 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactComponent
17 - */
18 -
19 -"use strict";
20 -
21 -var ExecutionEnvironment = require("./ExecutionEnvironment");
22 -var ReactCurrentOwner = require("./ReactCurrentOwner");
23 -var ReactDOMIDOperations = require("./ReactDOMIDOperations");
24 -var ReactMount = require("./ReactMount");
25 -var ReactOwner = require("./ReactOwner");
26 -var ReactReconcileTransaction = require("./ReactReconcileTransaction");
27 -
28 -var invariant = require("./invariant");
29 -var keyMirror = require("./keyMirror");
30 -var merge = require("./merge");
31 -
32 -/**
33 - * Prop key that references a component's owner.
34 - * @private
35 - */
36 -var OWNER = '{owner}';
37 -
38 -/**
39 - * Every React component is in one of these life cycles.
40 - */
41 -var ComponentLifeCycle = keyMirror({
42 - /**
43 - * Mounted components have a DOM node representation and are capable of
44 - * receiving new props.
45 - */
46 - MOUNTED: null,
47 - /**
48 - * Unmounted components are inactive and cannot receive new props.
49 - */
50 - UNMOUNTED: null
51 -});
52 -
53 -/**
54 - * Components are the basic units of composition in React.
55 - *
56 - * Every component accepts a set of keyed input parameters known as "props" that
57 - * are initialized by the constructor. Once a component is mounted, the props
58 - * can be mutated using `setProps` or `replaceProps`.
59 - *
60 - * Every component is capable of the following operations:
61 - *
62 - * `mountComponent`
63 - * Initializes the component, renders markup, and registers event listeners.
64 - *
65 - * `receiveProps`
66 - * Updates the rendered DOM nodes given a new set of props.
67 - *
68 - * `unmountComponent`
69 - * Releases any resources allocated by this component.
70 - *
71 - * Components can also be "owned" by other components. Being owned by another
72 - * component means being constructed by that component. This is different from
73 - * being the child of a component, which means having a DOM representation that
74 - * is a child of the DOM representation of that component.
75 - *
76 - * @class ReactComponent
77 - */
78 -var ReactComponent = {
79 -
80 - /**
81 - * @param {?object} object
82 - * @return {boolean} True if `object` is a valid component.
83 - * @final
84 - */
85 - isValidComponent: function(object) {
86 - return !!(
87 - object &&
88 - typeof object.mountComponentIntoNode === 'function' &&
89 - typeof object.receiveProps === 'function'
90 - );
91 - },
92 -
93 - /**
94 - * @internal
95 - */
96 - LifeCycle: ComponentLifeCycle,
97 -
98 - /**
99 - * React references `ReactDOMIDOperations` using this property in order to
100 - * allow dependency injection.
101 - *
102 - * @internal
103 - */
104 - DOMIDOperations: ReactDOMIDOperations,
105 -
106 - /**
107 - * React references `ReactReconcileTransaction` using this property in order
108 - * to allow dependency injection.
109 - *
110 - * @internal
111 - */
112 - ReactReconcileTransaction: ReactReconcileTransaction,
113 -
114 - /**
115 - * @param {object} DOMIDOperations
116 - * @final
117 - */
118 - setDOMOperations: function(DOMIDOperations) {
119 - ReactComponent.DOMIDOperations = DOMIDOperations;
120 - },
121 -
122 - /**
123 - * @param {Transaction} ReactReconcileTransaction
124 - * @final
125 - */
126 - setReactReconcileTransaction: function(ReactReconcileTransaction) {
127 - ReactComponent.ReactReconcileTransaction = ReactReconcileTransaction;
128 - },
129 -
130 - /**
131 - * Base functionality for every ReactComponent constructor.
132 - *
133 - * @lends {ReactComponent.prototype}
134 - */
135 - Mixin: {
136 -
137 - /**
138 - * Returns the DOM node rendered by this component.
139 - *
140 - * @return {?DOMElement} The root node of this component.
141 - * @final
142 - * @protected
143 - */
144 - getDOMNode: function() {
145 - invariant(
146 - ExecutionEnvironment.canUseDOM,
147 - 'getDOMNode(): The DOM is not supported in the current environment.'
148 - );
149 - invariant(
150 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
151 - 'getDOMNode(): A component must be mounted to have a DOM node.'
152 - );
153 - var rootNode = this._rootNode;
154 - if (!rootNode) {
155 - rootNode = document.getElementById(this._rootNodeID);
156 - if (!rootNode) {
157 - // TODO: Log the frequency that we reach this path.
158 - rootNode = ReactMount.findReactRenderedDOMNodeSlow(this._rootNodeID);
159 - }
160 - this._rootNode = rootNode;
161 - }
162 - return rootNode;
163 - },
164 -
165 - /**
166 - * Sets a subset of the props.
167 - *
168 - * @param {object} partialProps Subset of the next props.
169 - * @final
170 - * @public
171 - */
172 - setProps: function(partialProps) {
173 - this.replaceProps(merge(this.props, partialProps));
174 - },
175 -
176 - /**
177 - * Replaces all of the props.
178 - *
179 - * @param {object} props New props.
180 - * @final
181 - * @public
182 - */
183 - replaceProps: function(props) {
184 - invariant(
185 - !this.props[OWNER],
186 - 'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
187 - 'component with an owner. This is an anti-pattern since props will ' +
188 - 'get reactively updated when rendered. Instead, change the owner\'s ' +
189 - '`render` method to pass the correct value as props to the component ' +
190 - 'where it is created.'
191 - );
192 - var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
193 - transaction.perform(this.receiveProps, this, props, transaction);
194 - ReactComponent.ReactReconcileTransaction.release(transaction);
195 - },
196 -
197 - /**
198 - * Base constructor for all React component.
199 - *
200 - * Subclasses that override this method should make sure to invoke
201 - * `ReactComponent.Mixin.construct.call(this, ...)`.
202 - *
203 - * @param {?object} initialProps
204 - * @param {*} children
205 - * @internal
206 - */
207 - construct: function(initialProps, children) {
208 - this.props = initialProps || {};
209 - if (typeof children !== 'undefined') {
210 - this.props.children = children;
211 - }
212 - // Record the component responsible for creating this component.
213 - this.props[OWNER] = ReactCurrentOwner.current;
214 - // All components start unmounted.
215 - this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
216 - },
217 -
218 - /**
219 - * Initializes the component, renders markup, and registers event listeners.
220 - *
221 - * NOTE: This does not insert any nodes into the DOM.
222 - *
223 - * Subclasses that override this method should make sure to invoke
224 - * `ReactComponent.Mixin.mountComponent.call(this, ...)`.
225 - *
226 - * @param {string} rootID DOM ID of the root node.
227 - * @param {ReactReconcileTransaction} transaction
228 - * @return {?string} Rendered markup to be inserted into the DOM.
229 - * @internal
230 - */
231 - mountComponent: function(rootID, transaction) {
232 - invariant(
233 - this._lifeCycleState === ComponentLifeCycle.UNMOUNTED,
234 - 'mountComponent(%s, ...): Can only mount an unmounted component.',
235 - rootID
236 - );
237 - var props = this.props;
238 - if (props.ref != null) {
239 - ReactOwner.addComponentAsRefTo(this, props.ref, props[OWNER]);
240 - }
241 - this._rootNodeID = rootID;
242 - this._lifeCycleState = ComponentLifeCycle.MOUNTED;
243 - // Effectively: return '';
244 - },
245 -
246 - /**
247 - * Releases any resources allocated by `mountComponent`.
248 - *
249 - * NOTE: This does not remove any nodes from the DOM.
250 - *
251 - * Subclasses that override this method should make sure to invoke
252 - * `ReactComponent.Mixin.unmountComponent.call(this)`.
253 - *
254 - * @internal
255 - */
256 - unmountComponent: function() {
257 - invariant(
258 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
259 - 'unmountComponent(): Can only unmount a mounted component.'
260 - );
261 - var props = this.props;
262 - if (props.ref != null) {
263 - ReactOwner.removeComponentAsRefFrom(this, props.ref, props[OWNER]);
264 - }
265 - this._rootNode = null;
266 - this._rootNodeID = null;
267 - this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
268 - },
269 -
270 - /**
271 - * Updates the rendered DOM nodes given a new set of props.
272 - *
273 - * Subclasses that override this method should make sure to invoke
274 - * `ReactComponent.Mixin.receiveProps.call(this, ...)`.
275 - *
276 - * @param {object} nextProps Next set of properties.
277 - * @param {ReactReconcileTransaction} transaction
278 - * @internal
279 - */
280 - receiveProps: function(nextProps, transaction) {
281 - invariant(
282 - this._lifeCycleState === ComponentLifeCycle.MOUNTED,
283 - 'receiveProps(...): Can only update a mounted component.'
284 - );
285 - var props = this.props;
286 - // If either the owner or a `ref` has changed, make sure the newest owner
287 - // has stored a reference to `this`, and the previous owner (if different)
288 - // has forgotten the reference to `this`.
289 - if (nextProps[OWNER] !== props[OWNER] || nextProps.ref !== props.ref) {
290 - if (props.ref != null) {
291 - ReactOwner.removeComponentAsRefFrom(this, props.ref, props[OWNER]);
292 - }
293 - // Correct, even if the owner is the same, and only the ref has changed.
294 - if (nextProps.ref != null) {
295 - ReactOwner.addComponentAsRefTo(this, nextProps.ref, nextProps[OWNER]);
296 - }
297 - }
298 - },
299 -
300 - /**
301 - * Mounts this component and inserts it into the DOM.
302 - *
303 - * @param {string} rootID DOM ID of the root node.
304 - * @param {DOMElement} container DOM element to mount into.
305 - * @final
306 - * @internal
307 - * @see {ReactMount.renderComponent}
308 - */
309 - mountComponentIntoNode: function(rootID, container) {
310 - var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
311 - transaction.perform(
312 - this._mountComponentIntoNode,
313 - this,
314 - rootID,
315 - container,
316 - transaction
317 - );
318 - ReactComponent.ReactReconcileTransaction.release(transaction);
319 - },
320 -
321 - /**
322 - * @param {string} rootID DOM ID of the root node.
323 - * @param {DOMElement} container DOM element to mount into.
324 - * @param {ReactReconcileTransaction} transaction
325 - * @final
326 - * @private
327 - */
328 - _mountComponentIntoNode: function(rootID, container, transaction) {
329 - var renderStart = Date.now();
330 - var markup = this.mountComponent(rootID, transaction);
331 - ReactMount.totalInstantiationTime += (Date.now() - renderStart);
332 -
333 - var injectionStart = Date.now();
334 - // Asynchronously inject markup by ensuring that the container is not in
335 - // the document when settings its `innerHTML`.
336 - var parent = container.parentNode;
337 - if (parent) {
338 - var next = container.nextSibling;
339 - parent.removeChild(container);
340 - container.innerHTML = markup;
341 - if (next) {
342 - parent.insertBefore(container, next);
343 - } else {
344 - parent.appendChild(container);
345 - }
346 - } else {
347 - container.innerHTML = markup;
348 - }
349 - ReactMount.totalInjectionTime += (Date.now() - injectionStart);
350 - },
351 -
352 - /**
353 - * Unmounts this component and removes it from the DOM.
354 - *
355 - * @param {DOMElement} container DOM element to unmount from.
356 - * @final
357 - * @internal
358 - * @see {ReactMount.unmountAndReleaseReactRootNode}
359 - */
360 - unmountComponentFromNode: function(container) {
361 - this.unmountComponent();
362 - // http://jsperf.com/emptying-a-node
363 - while (container.lastChild) {
364 - container.removeChild(container.lastChild);
365 - }
366 - },
367 -
368 - /**
369 - * Checks if this component is owned by the supplied `owner` component.
370 - *
371 - * @param {ReactComponent} owner Component to check.
372 - * @return {boolean} True if `owners` owns this component.
373 - * @final
374 - * @internal
375 - */
376 - isOwnedBy: function(owner) {
377 - return this.props[OWNER] === owner;
378 - }
379 -
380 - }
381 -
382 -};
383 -
384 -function logDeprecated(msg) {
385 - if (true) {
386 - throw new Error(msg);
387 - }
388 -}
389 -
390 -/**
391 - * @deprecated
392 - */
393 -ReactComponent.Mixin.update = function(props) {
394 - logDeprecated('this.update() is deprecated. Use this.setProps()');
395 - this.setProps(props);
396 -};
397 -ReactComponent.Mixin.updateAll = function(props) {
398 - logDeprecated('this.updateAll() is deprecated. Use this.replaceProps()');
399 - this.replaceProps(props);
400 -};
401 -
402 -module.exports = ReactComponent;
React/ReactCompositeComponent.js deleted
-836
@@ -1,836 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactCompositeComponent
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactComponent = require("./ReactComponent");
22 -var ReactCurrentOwner = require("./ReactCurrentOwner");
23 -var ReactOwner = require("./ReactOwner");
24 -var ReactPropTransferer = require("./ReactPropTransferer");
25 -
26 -var invariant = require("./invariant");
27 -var keyMirror = require("./keyMirror");
28 -var merge = require("./merge");
29 -var mixInto = require("./mixInto");
30 -
31 -/**
32 - * Policies that describe methods in `ReactCompositeComponentInterface`.
33 - */
34 -var SpecPolicy = keyMirror({
35 - /**
36 - * These methods may be defined only once by the class specification or mixin.
37 - */
38 - DEFINE_ONCE: null,
39 - /**
40 - * These methods may be defined by both the class specification and mixins.
41 - * Subsequent definitions will be chained. These methods must return void.
42 - */
43 - DEFINE_MANY: null,
44 - /**
45 - * These methods are overriding the base ReactCompositeComponent class.
46 - */
47 - OVERRIDE_BASE: null
48 -});
49 -
50 -/**
51 - * Composite components are higher-level components that compose other composite
52 - * or native components.
53 - *
54 - * To create a new type of `ReactCompositeComponent`, pass a specification of
55 - * your new class to `React.createClass`. The only requirement of your class
56 - * specification is that you implement a `render` method.
57 - *
58 - * var MyComponent = React.createClass({
59 - * render: function() {
60 - * return <div>Hello World</div>;
61 - * }
62 - * });
63 - *
64 - * The class specification supports a specific protocol of methods that have
65 - * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
66 - * more the comprehensive protocol. Any other properties and methods in the
67 - * class specification will available on the prototype.
68 - *
69 - * @interface ReactCompositeComponentInterface
70 - * @internal
71 - */
72 -var ReactCompositeComponentInterface = {
73 -
74 - /**
75 - * An array of Mixin objects to include when defining your component.
76 - *
77 - * @type {array}
78 - * @optional
79 - */
80 - mixins: SpecPolicy.DEFINE_MANY,
81 -
82 - /**
83 - * Definition of props for this component.
84 - *
85 - * @type {array}
86 - * @optional
87 - */
88 - props: SpecPolicy.DEFINE_ONCE,
89 -
90 -
91 -
92 - // ==== Definition methods ====
93 -
94 - /**
95 - * Invoked once before the component is mounted. The return value will be used
96 - * as the initial value of `this.state`.
97 - *
98 - * getInitialState: function() {
99 - * return {
100 - * isOn: false,
101 - * fooBaz: new BazFoo()
102 - * }
103 - * }
104 - *
105 - * @return {object}
106 - * @optional
107 - */
108 - getInitialState: SpecPolicy.DEFINE_ONCE,
109 -
110 - /**
111 - * Uses props from `this.props` and state from `this.state` to render the
112 - * structure of the component.
113 - *
114 - * No guarantees are made about when or how often this method is invoked, so
115 - * it must not have side effects.
116 - *
117 - * render: function() {
118 - * var name = this.props.name;
119 - * return <div>Hello, {name}!</div>;
120 - * }
121 - *
122 - * @return {ReactComponent}
123 - * @nosideeffects
124 - * @required
125 - */
126 - render: SpecPolicy.DEFINE_ONCE,
127 -
128 -
129 -
130 - // ==== Delegate methods ====
131 -
132 - /**
133 - * Invoked when the component is initially created and about to be mounted.
134 - * This may have side effects, but any external subscriptions or data created
135 - * by this method must be cleaned up in `componentWillUnmount`.
136 - *
137 - * @optional
138 - */
139 - componentWillMount: SpecPolicy.DEFINE_MANY,
140 -
141 - /**
142 - * Invoked when the component has been mounted and has a DOM representation.
143 - * However, there is no guarantee that the DOM node is in the document.
144 - *
145 - * Use this as an opportunity to operate on the DOM when the component has
146 - * been mounted (initialized and rendered) for the first time.
147 - *
148 - * @param {DOMElement} rootNode DOM element representing the component.
149 - * @optional
150 - */
151 - componentDidMount: SpecPolicy.DEFINE_MANY,
152 -
153 - /**
154 - * Invoked before the component receives new props.
155 - *
156 - * Use this as an opportunity to react to a prop transition by updating the
157 - * state using `this.setState`. Current props are accessed via `this.props`.
158 - *
159 - * componentWillReceiveProps: function(nextProps) {
160 - * this.setState({
161 - * likesIncreasing: nextProps.likeCount > this.props.likeCount
162 - * });
163 - * }
164 - *
165 - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
166 - * transition may cause a state change, but the opposite is not true. If you
167 - * need it, you are probably looking for `componentWillUpdate`.
168 - *
169 - * @param {object} nextProps
170 - * @optional
171 - */
172 - componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
173 -
174 - /**
175 - * Invoked while deciding if the component should be updated as a result of
176 - * receiving new props and state.
177 - *
178 - * Use this as an opportunity to `return false` when you're certain that the
179 - * transition to the new props and state will not require a component update.
180 - *
181 - * shouldComponentUpdate: function(nextProps, nextState) {
182 - * return !equal(nextProps, this.props) || !equal(nextState, this.state);
183 - * }
184 - *
185 - * @param {object} nextProps
186 - * @param {?object} nextState
187 - * @return {boolean} True if the component should update.
188 - * @optional
189 - */
190 - shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
191 -
192 - /**
193 - * Invoked when the component is about to update due to a transition from
194 - * `this.props` and `this.state` to `nextProps` and `nextState`.
195 - *
196 - * Use this as an opportunity to perform preparation before an update occurs.
197 - *
198 - * NOTE: You **cannot** use `this.setState()` in this method.
199 - *
200 - * @param {object} nextProps
201 - * @param {?object} nextState
202 - * @param {ReactReconcileTransaction} transaction
203 - * @optional
204 - */
205 - componentWillUpdate: SpecPolicy.DEFINE_MANY,
206 -
207 - /**
208 - * Invoked when the component's DOM representation has been updated.
209 - *
210 - * Use this as an opportunity to operate on the DOM when the component has
211 - * been updated.
212 - *
213 - * @param {object} prevProps
214 - * @param {?object} prevState
215 - * @param {DOMElement} rootNode DOM element representing the component.
216 - * @optional
217 - */
218 - componentDidUpdate: SpecPolicy.DEFINE_MANY,
219 -
220 - /**
221 - * Invoked when the component is about to be removed from its parent and have
222 - * its DOM representation destroyed.
223 - *
224 - * Use this as an opportunity to deallocate any external resources.
225 - *
226 - * NOTE: There is no `componentDidUnmount` since your component will have been
227 - * destroyed by that point.
228 - *
229 - * @optional
230 - */
231 - componentWillUnmount: SpecPolicy.DEFINE_MANY,
232 -
233 -
234 -
235 - // ==== Advanced methods ====
236 -
237 - /**
238 - * Updates the component's currently mounted DOM representation.
239 - *
240 - * By default, this implements React's rendering and reconciliation algorithm.
241 - * Sophisticated clients may wish to override this.
242 - *
243 - * @param {ReactReconcileTransaction} transaction
244 - * @internal
245 - * @overridable
246 - */
247 - updateComponent: SpecPolicy.OVERRIDE_BASE
248 -
249 -};
250 -
251 -/**
252 - * Mapping from class specification keys to special processing functions.
253 - *
254 - * Although these are declared in the specification when defining classes
255 - * using `React.createClass`, they will not be on the component's prototype.
256 - */
257 -var RESERVED_SPEC_KEYS = {
258 - displayName: function(Constructor, displayName) {
259 - Constructor.displayName = displayName;
260 - },
261 - mixins: function(Constructor, mixins) {
262 - if (mixins) {
263 - for (var i = 0; i < mixins.length; i++) {
264 - mixSpecIntoComponent(Constructor, mixins[i]);
265 - }
266 - }
267 - },
268 - props: function(Constructor, props) {
269 - Constructor.propDeclarations = props;
270 - }
271 -};
272 -
273 -/**
274 - * Custom version of `mixInto` which handles policy validation and reserved
275 - * specification keys when building `ReactCompositeComponent` classses.
276 - */
277 -function mixSpecIntoComponent(Constructor, spec) {
278 - var proto = Constructor.prototype;
279 - for (var name in spec) {
280 - if (!spec.hasOwnProperty(name)) {
281 - continue;
282 - }
283 - var property = spec[name];
284 - var specPolicy = ReactCompositeComponentInterface[name];
285 -
286 - // Disallow overriding of base class methods unless explicitly allowed.
287 - if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
288 - invariant(
289 - specPolicy === SpecPolicy.OVERRIDE_BASE,
290 - 'ReactCompositeComponentInterface: You are attempting to override ' +
291 - '`%s` from your class specification. Ensure that your method names ' +
292 - 'do not overlap with React methods.',
293 - name
294 - );
295 - }
296 -
297 - // Disallow using `React.autoBind` on internal methods.
298 - if (specPolicy != null) {
299 - invariant(
300 - !property || !property.__reactAutoBind,
301 - 'ReactCompositeComponentInterface: You are attempting to use ' +
302 - '`React.autoBind` on `%s`, a method that is internal to React.' +
303 - 'Internal methods are called with the component as the context.',
304 - name
305 - );
306 - }
307 -
308 - // Disallow defining methods more than once unless explicitly allowed.
309 - if (proto.hasOwnProperty(name)) {
310 - invariant(
311 - specPolicy === SpecPolicy.DEFINE_MANY,
312 - 'ReactCompositeComponentInterface: You are attempting to define ' +
313 - '`%s` on your component more than once. This conflict may be due ' +
314 - 'to a mixin.',
315 - name
316 - );
317 - }
318 -
319 - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
320 - RESERVED_SPEC_KEYS[name](Constructor, property);
321 - } else if (property && property.__reactAutoBind) {
322 - if (!proto.__reactAutoBindMap) {
323 - proto.__reactAutoBindMap = {};
324 - }
325 - proto.__reactAutoBindMap[name] = property.__reactAutoBind;
326 - } else if (proto.hasOwnProperty(name)) {
327 - // For methods which are defined more than once, call the existing methods
328 - // before calling the new property.
329 - proto[name] = createChainedFunction(proto[name], property);
330 - } else {
331 - proto[name] = property;
332 - }
333 - }
334 -}
335 -
336 -/**
337 - * Creates a function that invokes two functions and ignores their return vales.
338 - *
339 - * @param {function} one Function to invoke first.
340 - * @param {function} two Function to invoke second.
341 - * @return {function} Function that invokes the two argument functions.
342 - * @private
343 - */
344 -function createChainedFunction(one, two) {
345 - return function chainedFunction(a, b, c, d, e, tooMany) {
346 - invariant(
347 - typeof tooMany === 'undefined',
348 - 'Chained function can only take a maximum of 5 arguments.'
349 - );
350 - one.call(this, a, b, c, d, e);
351 - two.call(this, a, b, c, d, e);
352 - };
353 -}
354 -
355 -/**
356 - * `ReactCompositeComponent` maintains an auxiliary life cycle state in
357 - * `this._compositeLifeCycleState` (which can be null).
358 - *
359 - * This is different from the life cycle state maintained by `ReactComponent` in
360 - * `this._lifeCycleState`.
361 - */
362 -var CompositeLifeCycle = keyMirror({
363 - /**
364 - * Components in the process of being mounted respond to state changes
365 - * differently.
366 - */
367 - MOUNTING: null,
368 - /**
369 - * Components in the process of being unmounted are guarded against state
370 - * changes.
371 - */
372 - UNMOUNTING: null,
373 - /**
374 - * Components that are mounted and receiving new props respond to state
375 - * changes differently.
376 - */
377 - RECEIVING_PROPS: null,
378 - /**
379 - * Components that are mounted and receiving new state are guarded against
380 - * additional state changes.
381 - */
382 - RECEIVING_STATE: null
383 -});
384 -
385 -/**
386 - * @lends {ReactCompositeComponent.prototype}
387 - */
388 -var ReactCompositeComponentMixin = {
389 -
390 - /**
391 - * Base constructor for all composite component.
392 - *
393 - * @param {?object} initialProps
394 - * @param {*} children
395 - * @final
396 - * @internal
397 - */
398 - construct: function(initialProps, children) {
399 - ReactComponent.Mixin.construct.call(this, initialProps, children);
400 - this.state = null;
401 - this._pendingState = null;
402 - this._compositeLifeCycleState = null;
403 - },
404 -
405 - /**
406 - * Initializes the component, renders markup, and registers event listeners.
407 - *
408 - * @param {string} rootID DOM ID of the root node.
409 - * @param {ReactReconcileTransaction} transaction
410 - * @return {?string} Rendered markup to be inserted into the DOM.
411 - * @final
412 - * @internal
413 - */
414 - mountComponent: function(rootID, transaction) {
415 - ReactComponent.Mixin.mountComponent.call(this, rootID, transaction);
416 -
417 - // Unset `this._lifeCycleState` until after this method is finished.
418 - this._lifeCycleState = ReactComponent.LifeCycle.UNMOUNTED;
419 - this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
420 -
421 - if (this.constructor.propDeclarations) {
422 - this._assertValidProps(this.props);
423 - }
424 -
425 - if (this.__reactAutoBindMap) {
426 - this._bindAutoBindMethods();
427 - }
428 -
429 - this.state = this.getInitialState ? this.getInitialState() : null;
430 - this._pendingState = null;
431 -
432 - if (this.componentWillMount) {
433 - this.componentWillMount();
434 - // When mounting, calls to `setState` by `componentWillMount` will set
435 - // `this._pendingState` without triggering a re-render.
436 - if (this._pendingState) {
437 - this.state = this._pendingState;
438 - this._pendingState = null;
439 - }
440 - }
441 -
442 - if (this.componentDidMount) {
443 - transaction.getReactOnDOMReady().enqueue(this, this.componentDidMount);
444 - }
445 -
446 - this._renderedComponent = this._renderValidatedComponent();
447 -
448 - // Done with mounting, `setState` will now trigger UI changes.
449 - this._compositeLifeCycleState = null;
450 - this._lifeCycleState = ReactComponent.LifeCycle.MOUNTED;
451 -
452 - return this._renderedComponent.mountComponent(rootID, transaction);
453 - },
454 -
455 - /**
456 - * Releases any resources allocated by `mountComponent`.
457 - *
458 - * @final
459 - * @internal
460 - */
461 - unmountComponent: function() {
462 - this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
463 - if (this.componentWillUnmount) {
464 - this.componentWillUnmount();
465 - }
466 - this._compositeLifeCycleState = null;
467 -
468 - ReactComponent.Mixin.unmountComponent.call(this);
469 - this._renderedComponent.unmountComponent();
470 - this._renderedComponent = null;
471 -
472 - if (this.refs) {
473 - this.refs = null;
474 - }
475 -
476 - // Some existing components rely on this.props even after they've been
477 - // destroyed (in event handlers).
478 - // TODO: this.props = null;
479 - // TODO: this.state = null;
480 - },
481 -
482 - /**
483 - * Updates the rendered DOM nodes given a new set of props.
484 - *
485 - * @param {object} nextProps Next set of properties.
486 - * @param {ReactReconcileTransaction} transaction
487 - * @final
488 - * @internal
489 - */
490 - receiveProps: function(nextProps, transaction) {
491 - if (this.constructor.propDeclarations) {
492 - this._assertValidProps(nextProps);
493 - }
494 - ReactComponent.Mixin.receiveProps.call(this, nextProps, transaction);
495 -
496 - this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
497 - if (this.componentWillReceiveProps) {
498 - this.componentWillReceiveProps(nextProps, transaction);
499 - }
500 - this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
501 - // When receiving props, calls to `setState` by `componentWillReceiveProps`
502 - // will set `this._pendingState` without triggering a re-render.
503 - var nextState = this._pendingState || this.state;
504 - this._pendingState = null;
505 - this._receivePropsAndState(nextProps, nextState, transaction);
506 - this._compositeLifeCycleState = null;
507 - },
508 -
509 - /**
510 - * Sets a subset of the state. Always use this or `replaceState` to mutate
511 - * state. You should treat `this.state` as immutable.
512 - *
513 - * There is no guarantee that `this.state` will be immediately updated, so
514 - * accessing `this.state` after calling this method may return the old value.
515 - *
516 - * @param {object} partialState Next partial state to be merged with state.
517 - * @final
518 - * @protected
519 - */
520 - setState: function(partialState) {
521 - // Merge with `_pendingState` if it exists, otherwise with existing state.
522 - this.replaceState(merge(this._pendingState || this.state, partialState));
523 - },
524 -
525 - /**
526 - * Replaces all of the state. Always use this or `setState` to mutate state.
527 - * You should treat `this.state` as immutable.
528 - *
529 - * There is no guarantee that `this.state` will be immediately updated, so
530 - * accessing `this.state` after calling this method may return the old value.
531 - *
532 - * @param {object} completeState Next state.
533 - * @final
534 - * @protected
535 - */
536 - replaceState: function(completeState) {
537 - var compositeLifeCycleState = this._compositeLifeCycleState;
538 - invariant(
539 - this._lifeCycleState === ReactComponent.LifeCycle.MOUNTED ||
540 - compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
541 - 'replaceState(...): Can only update a mounted (or mounting) component.'
542 - );
543 - invariant(
544 - compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
545 - compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
546 - 'replaceState(...): Cannot update while unmounting component or during ' +
547 - 'an existing state transition (such as within `render`).'
548 - );
549 -
550 - this._pendingState = completeState;
551 -
552 - // Do not trigger a state transition if we are in the middle of mounting or
553 - // receiving props because both of those will already be doing this.
554 - if (compositeLifeCycleState !== CompositeLifeCycle.MOUNTING &&
555 - compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_PROPS) {
556 - this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
557 -
558 - var nextState = this._pendingState;
559 - this._pendingState = null;
560 -
561 - var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
562 - transaction.perform(
563 - this._receivePropsAndState,
564 - this,
565 - this.props,
566 - nextState,
567 - transaction
568 - );
569 - ReactComponent.ReactReconcileTransaction.release(transaction);
570 -
571 - this._compositeLifeCycleState = null;
572 - }
573 - },
574 -
575 - /**
576 - * Receives next props and next state, and negotiates whether or not the
577 - * component should update as a result.
578 - *
579 - * @param {object} nextProps Next object to set as props.
580 - * @param {?object} nextState Next object to set as state.
581 - * @param {ReactReconcileTransaction} transaction
582 - * @private
583 - */
584 - _receivePropsAndState: function(nextProps, nextState, transaction) {
585 - if (!this.shouldComponentUpdate ||
586 - this.shouldComponentUpdate(nextProps, nextState)) {
587 - // Will set `this.props` and `this.state`.
588 - this._performComponentUpdate(nextProps, nextState, transaction);
589 - } else {
590 - // If it's determined that a component should not update, we still want
591 - // to set props and state.
592 - this.props = nextProps;
593 - this.state = nextState;
594 - }
595 - },
596 -
597 - /**
598 - * Merges new props and state, notifies delegate methods of update and
599 - * performs update.
600 - *
601 - * @param {object} nextProps Next object to set as properties.
602 - * @param {?object} nextState Next object to set as state.
603 - * @param {ReactReconcileTransaction} transaction
604 - * @private
605 - */
606 - _performComponentUpdate: function(nextProps, nextState, transaction) {
607 - var prevProps = this.props;
608 - var prevState = this.state;
609 -
610 - if (this.componentWillUpdate) {
611 - this.componentWillUpdate(nextProps, nextState, transaction);
612 - }
613 -
614 - this.props = nextProps;
615 - this.state = nextState;
616 -
617 - this.updateComponent(transaction);
618 -
619 - if (this.componentDidUpdate) {
620 - transaction.getReactOnDOMReady().enqueue(
621 - this,
622 - this.componentDidUpdate.bind(this, prevProps, prevState)
623 - );
624 - }
625 - },
626 -
627 - /**
628 - * Updates the component's currently mounted DOM representation.
629 - *
630 - * By default, this implements React's rendering and reconciliation algorithm.
631 - * Sophisticated clients may wish to override this.
632 - *
633 - * @param {ReactReconcileTransaction} transaction
634 - * @internal
635 - * @overridable
636 - */
637 - updateComponent: function(transaction) {
638 - var currentComponent = this._renderedComponent;
639 - var nextComponent = this._renderValidatedComponent();
640 - if (currentComponent.constructor === nextComponent.constructor) {
641 - if (!nextComponent.props.isStatic) {
642 - currentComponent.receiveProps(nextComponent.props, transaction);
643 - }
644 - } else {
645 - // These two IDs are actually the same! But nothing should rely on that.
646 - var thisID = this._rootNodeID;
647 - var currentComponentID = currentComponent._rootNodeID;
648 - currentComponent.unmountComponent();
649 - var nextMarkup = nextComponent.mountComponent(thisID, transaction);
650 - ReactComponent.DOMIDOperations.dangerouslyReplaceNodeWithMarkupByID(
651 - currentComponentID,
652 - nextMarkup
653 - );
654 - this._renderedComponent = nextComponent;
655 - }
656 - },
657 -
658 - /**
659 - * Forces an update. This should only be invoked when it is known with
660 - * certainty that we are **not** in a DOM transaction.
661 - *
662 - * You may want to call this when you know that some deeper aspect of the
663 - * component's state has changed but `setState` was not called.
664 - *
665 - * This will not invoke `shouldUpdateComponent`, but it will invoke
666 - * `componentWillUpdate` and `componentDidUpdate`.
667 - *
668 - * @final
669 - * @protected
670 - */
671 - forceUpdate: function() {
672 - var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
673 - transaction.perform(
674 - this._performComponentUpdate,
675 - this,
676 - this.props,
677 - this.state,
678 - transaction
679 - );
680 - ReactComponent.ReactReconcileTransaction.release(transaction);
681 - },
682 -
683 - /**
684 - * @private
685 - */
686 - _renderValidatedComponent: function() {
687 - ReactCurrentOwner.current = this;
688 - var renderedComponent = this.render();
689 - ReactCurrentOwner.current = null;
690 - invariant(
691 - ReactComponent.isValidComponent(renderedComponent),
692 - '%s.render(): A valid ReactComponent must be returned.',
693 - this.constructor.displayName || 'ReactCompositeComponent'
694 - );
695 - return renderedComponent;
696 - },
697 -
698 - /**
699 - * @param {object} props
700 - * @private
701 - */
702 - _assertValidProps: function(props) {
703 - var propDeclarations = this.constructor.propDeclarations;
704 - var componentName = this.constructor.displayName;
705 - for (var propName in propDeclarations) {
706 - var checkProp = propDeclarations[propName];
707 - if (checkProp) {
708 - checkProp(props, propName, componentName);
709 - }
710 - }
711 - },
712 -
713 - /**
714 - * @private
715 - */
716 - _bindAutoBindMethods: function() {
717 - for (var autoBindKey in this.__reactAutoBindMap) {
718 - if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
719 - continue;
720 - }
721 - var method = this.__reactAutoBindMap[autoBindKey];
722 - this[autoBindKey] = this._bindAutoBindMethod(method);
723 - }
724 - },
725 -
726 - /**
727 - * Binds a method to the component.
728 - *
729 - * @param {function} method Method to be bound.
730 - * @private
731 - */
732 - _bindAutoBindMethod: function(method) {
733 - var component = this;
734 - var hasWarned = false;
735 - function autoBound(a, b, c, d, e, tooMany) {
736 - invariant(
737 - typeof tooMany === 'undefined',
738 - 'React.autoBind(...): Methods can only take a maximum of 5 arguments.'
739 - );
740 - if (component._lifeCycleState === ReactComponent.LifeCycle.MOUNTED) {
741 - return method.call(component, a, b, c, d, e);
742 - } else if (!hasWarned) {
743 - hasWarned = true;
744 - if (true) {
745 - console.warn(
746 - 'React.autoBind(...): Attempted to invoke an auto-bound method ' +
747 - 'on an unmounted instance of `%s`. You either have a memory leak ' +
748 - 'or an event handler that is being run after unmounting.',
749 - component.constructor.displayName || 'ReactCompositeComponent'
750 - );
751 - }
752 - }
753 - }
754 - return autoBound;
755 - }
756 -
757 -};
758 -
759 -var ReactCompositeComponentBase = function() {};
760 -mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
761 -mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
762 -mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
763 -mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
764 -
765 -/**
766 - * Module for creating composite components.
767 - *
768 - * @class ReactCompositeComponent
769 - * @extends ReactComponent
770 - * @extends ReactOwner
771 - * @extends ReactPropTransferer
772 - */
773 -var ReactCompositeComponent = {
774 -
775 - LifeCycle: CompositeLifeCycle,
776 -
777 - Base: ReactCompositeComponentBase,
778 -
779 - /**
780 - * Creates a composite component class given a class specification.
781 - *
782 - * @param {object} spec Class specification (which must define `render`).
783 - * @return {function} Component constructor function.
784 - * @public
785 - */
786 - createClass: function(spec) {
787 - var Constructor = function(initialProps, children) {
788 - this.construct(initialProps, children);
789 - };
790 - Constructor.prototype = new ReactCompositeComponentBase();
791 - Constructor.prototype.constructor = Constructor;
792 - mixSpecIntoComponent(Constructor, spec);
793 - invariant(
794 - Constructor.prototype.render,
795 - 'createClass(...): Class specification must implement a `render` method.'
796 - );
797 -
798 - var ConvenienceConstructor = function(props, children) {
799 - return new Constructor(props, children);
800 - };
801 - ConvenienceConstructor.componentConstructor = Constructor;
802 - ConvenienceConstructor.originalSpec = spec;
803 - return ConvenienceConstructor;
804 - },
805 -
806 - /**
807 - * Marks the provided method to be automatically bound to the component.
808 - * This means the method's context will always be the component.
809 - *
810 - * React.createClass({
811 - * handleClick: React.autoBind(function() {
812 - * this.setState({jumping: true});
813 - * }),
814 - * render: function() {
815 - * return <a onClick={this.handleClick}>Jump</a>;
816 - * }
817 - * });
818 - *
819 - * @param {function} method Method to be bound.
820 - * @public
821 - */
822 - autoBind: function(method) {
823 - function unbound() {
824 - invariant(
825 - false,
826 - 'React.autoBind(...): Attempted to invoke an auto-bound method that ' +
827 - 'was not correctly defined on the class specification.'
828 - );
829 - }
830 - unbound.__reactAutoBind = method;
831 - return unbound;
832 - }
833 -
834 -};
835 -
836 -module.exports = ReactCompositeComponent;
React/ReactCurrentOwner.js deleted
-37
@@ -1,37 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactCurrentOwner
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Keeps track of the current owner.
23 - *
24 - * The current owner is the component who should own any components that are
25 - * currently being constructed.
26 - */
27 -var ReactCurrentOwner = {
28 -
29 - /**
30 - * @internal
31 - * @type {ReactComponent}
32 - */
33 - current: null
34 -
35 -};
36 -
37 -module.exports = ReactCurrentOwner;
React/ReactDOM.js deleted
-148
@@ -1,148 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactDOM
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var ReactNativeComponent = require("./ReactNativeComponent");
23 -
24 -var mergeInto = require("./mergeInto");
25 -var objMapKeyVal = require("./objMapKeyVal");
26 -
27 -/**
28 - * Creates a new React class that is idempotent and capable of containing other
29 - * React components. It accepts event listeners and DOM properties that are
30 - * valid according to `DOMProperty`.
31 - *
32 - * - Event listeners: `onClick`, `onMouseDown`, etc.
33 - * - DOM properties: `className`, `name`, `title`, etc.
34 - *
35 - * The `style` property functions differently from the DOM API. It accepts an
36 - * object mapping of style properties to values.
37 - *
38 - * @param {string} tag Tag name (e.g. `div`).
39 - * @param {boolean} omitClose True if the close tag should be omitted.
40 - * @private
41 - */
42 -function createDOMComponentClass(tag, omitClose) {
43 - var Constructor = function(initialProps, children) {
44 - this.construct(initialProps, children);
45 - };
46 -
47 - Constructor.prototype = new ReactNativeComponent(tag, omitClose);
48 - Constructor.prototype.constructor = Constructor;
49 -
50 - return function(props, children) {
51 - return new Constructor(props, children);
52 - };
53 -}
54 -
55 -/**
56 - * Creates a mapping from supported HTML tags to `ReactNativeComponent` classes.
57 - * This is also accessible via `React.DOM`.
58 - *
59 - * @public
60 - */
61 -var ReactDOM = objMapKeyVal({
62 - a: false,
63 - abbr: false,
64 - address: false,
65 - audio: false,
66 - b: false,
67 - body: false,
68 - br: true,
69 - button: false,
70 - code: false,
71 - col: true,
72 - colgroup: false,
73 - dd: false,
74 - div: false,
75 - section: false,
76 - dl: false,
77 - dt: false,
78 - em: false,
79 - embed: true,
80 - fieldset: false,
81 - footer: false,
82 - // Danger: this gets monkeypatched! See ReactDOMForm for more info.
83 - form: false,
84 - h1: false,
85 - h2: false,
86 - h3: false,
87 - h4: false,
88 - h5: false,
89 - h6: false,
90 - header: false,
91 - hr: true,
92 - i: false,
93 - iframe: false,
94 - img: true,
95 - input: true,
96 - label: false,
97 - legend: false,
98 - li: false,
99 - line: false,
100 - nav: false,
101 - object: false,
102 - ol: false,
103 - optgroup: false,
104 - option: false,
105 - p: false,
106 - param: true,
107 - pre: false,
108 - select: false,
109 - small: false,
110 - source: false,
111 - span: false,
112 - sub: false,
113 - sup: false,
114 - strong: false,
115 - table: false,
116 - tbody: false,
117 - td: false,
118 - textarea: false,
119 - tfoot: false,
120 - th: false,
121 - thead: false,
122 - time: false,
123 - title: false,
124 - tr: false,
125 - u: false,
126 - ul: false,
127 - video: false,
128 - wbr: false,
129 -
130 - // SVG
131 - circle: false,
132 - g: false,
133 - path: false,
134 - polyline: false,
135 - rect: false,
136 - svg: false,
137 - text: false
138 -}, createDOMComponentClass);
139 -
140 -var injection = {
141 - injectComponentClasses: function(componentClasses) {
142 - mergeInto(ReactDOM, componentClasses);
143 - }
144 -};
145 -
146 -ReactDOM.injection = injection;
147 -
148 -module.exports = ReactDOM;
React/ReactDOMForm.js deleted
-52
@@ -1,52 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactDOMForm
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactCompositeComponent = require("./ReactCompositeComponent");
22 -var ReactDOM = require("./ReactDOM");
23 -var ReactEvent = require("./ReactEvent");
24 -var EventConstants = require("./EventConstants");
25 -
26 -// Store a reference to the <form> `ReactNativeComponent`.
27 -var form = ReactDOM.form;
28 -
29 -/**
30 - * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need
31 - * to capture it on the <form> element itself. There are lots of hacks we could
32 - * do to accomplish this, but the most reliable is to make <form> a
33 - * composite component and use `componentDidMount` to attach the event handlers.
34 - */
35 -var ReactDOMForm = ReactCompositeComponent.createClass({
36 - render: function() {
37 - // TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
38 - // `jshint` fails to parse JSX so in order for linting to work in the open
39 - // source repo, we need to just use `ReactDOM.form`.
40 - return this.transferPropsTo(form(null, this.props.children));
41 - },
42 -
43 - componentDidMount: function(node) {
44 - ReactEvent.trapBubbledEvent(
45 - EventConstants.topLevelTypes.topSubmit,
46 - 'submit',
47 - node
48 - );
49 - }
50 -});
51 -
52 -module.exports = ReactDOMForm;
React/ReactDOMIDOperations.js deleted
-166
@@ -1,166 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactDOMIDOperations
17 - * @typechecks
18 - */
19 -
20 -/*jslint evil: true */
21 -
22 -"use strict";
23 -
24 -var CSSPropertyOperations = require("./CSSPropertyOperations");
25 -var DOMChildrenOperations = require("./DOMChildrenOperations");
26 -var DOMPropertyOperations = require("./DOMPropertyOperations");
27 -var ReactDOMNodeCache = require("./ReactDOMNodeCache");
28 -
29 -var getTextContentAccessor = require("./getTextContentAccessor");
30 -var invariant = require("./invariant");
31 -
32 -/**
33 - * Errors for properties that should not be updated with `updatePropertyById()`.
34 - *
35 - * @type {object}
36 - * @private
37 - */
38 -var INVALID_PROPERTY_ERRORS = {
39 - content: '`content` must be set using `updateTextContentByID()`.',
40 - dangerouslySetInnerHTML:
41 - '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
42 - style: '`style` must be set using `updateStylesByID()`.'
43 -};
44 -
45 -/**
46 - * The DOM property to use when setting text content.
47 - *
48 - * @type {string}
49 - * @private
50 - */
51 -var textContentAccessor = getTextContentAccessor() || 'NA';
52 -
53 -/**
54 - * Operations used to process updates to DOM nodes. This is made injectable via
55 - * `ReactComponent.DOMIDOperations`.
56 - */
57 -var ReactDOMIDOperations = {
58 -
59 - /**
60 - * Updates a DOM node with new property values. This should only be used to
61 - * update DOM properties in `DOMProperty`.
62 - *
63 - * @param {string} id ID of the node to update.
64 - * @param {string} name A valid property name, see `DOMProperty`.
65 - * @param {*} value New value of the property.
66 - * @internal
67 - */
68 - updatePropertyByID: function(id, name, value) {
69 - var node = ReactDOMNodeCache.getCachedNodeByID(id);
70 - invariant(
71 - !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
72 - 'updatePropertyByID(...): %s',
73 - INVALID_PROPERTY_ERRORS[name]
74 - );
75 - DOMPropertyOperations.setValueForProperty(node, name, value);
76 - },
77 -
78 - /**
79 - * This should almost never be used instead of `updatePropertyByID()` due to
80 - * the extra object allocation required by the API. That said, this is useful
81 - * for batching up several operations across worker thread boundaries.
82 - *
83 - * @param {string} id ID of the node to update.
84 - * @param {object} properties A mapping of valid property names.
85 - * @internal
86 - * @see {ReactDOMIDOperations.updatePropertyByID}
87 - */
88 - updatePropertiesByID: function(id, properties) {
89 - for (var name in properties) {
90 - if (!properties.hasOwnProperty(name)) {
91 - continue;
92 - }
93 - ReactDOMIDOperations.updatePropertiesByID(id, name, properties[name]);
94 - }
95 - },
96 -
97 - /**
98 - * Updates a DOM node with new style values.
99 - *
100 - * @param {string} id ID of the node to update.
101 - * @param {object} styles Mapping from styles to values.
102 - * @internal
103 - */
104 - updateStylesByID: function(id, styles) {
105 - var node = ReactDOMNodeCache.getCachedNodeByID(id);
106 - CSSPropertyOperations.setValueForStyles(node, styles);
107 - },
108 -
109 - /**
110 - * Updates a DOM node's innerHTML set by `props.dangerouslySetInnerHTML`.
111 - *
112 - * @param {string} id ID of the node to update.
113 - * @param {object} html An HTML object with the `__html` property.
114 - * @internal
115 - */
116 - updateInnerHTMLByID: function(id, html) {
117 - var node = ReactDOMNodeCache.getCachedNodeByID(id);
118 - // HACK: IE8- normalize whitespace in innerHTML, removing leading spaces.
119 - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
120 - node.innerHTML = (html && html.__html || '').replace(/^ /g, '&nbsp;');
121 - },
122 -
123 - /**
124 - * Updates a DOM node's text content set by `props.content`.
125 - *
126 - * @param {string} id ID of the node to update.
127 - * @param {string} content Text content.
128 - * @internal
129 - */
130 - updateTextContentByID: function(id, content) {
131 - var node = ReactDOMNodeCache.getCachedNodeByID(id);
132 - node[textContentAccessor] = content;
133 - },
134 -
135 - /**
136 - * Replaces a DOM node that exists in the document with markup.
137 - *
138 - * @param {string} id ID of child to be replaced.
139 - * @param {string} markup Dangerous markup to inject in place of child.
140 - * @internal
141 - * @see {Danger.dangerouslyReplaceNodeWithMarkup}
142 - */
143 - dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
144 - var node = ReactDOMNodeCache.getCachedNodeByID(id);
145 - DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
146 - ReactDOMNodeCache.purgeEntireCache();
147 - },
148 -
149 - /**
150 - * TODO: We only actually *need* to purge the cache when we remove elements.
151 - * Detect if any elements were removed instead of blindly purging.
152 - */
153 - manageChildrenByParentID: function(parentID, domOperations) {
154 - var parent = ReactDOMNodeCache.getCachedNodeByID(parentID);
155 - DOMChildrenOperations.manageChildren(parent, domOperations);
156 - ReactDOMNodeCache.purgeEntireCache();
157 - },
158 -
159 - setTextNodeValueAtIndexByParentID: function(parentID, index, value) {
160 - var parent = ReactDOMNodeCache.getCachedNodeByID(parentID);
161 - DOMChildrenOperations.setTextNodeValueAtIndex(parent, index, value);
162 - }
163 -
164 -};
165 -
166 -module.exports = ReactDOMIDOperations;
React/ReactDOMNodeCache.js deleted
-52
@@ -1,52 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactDOMNodeCache
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactMount = require("./ReactMount");
22 -
23 -var nodeCache = {};
24 -
25 -/**
26 - * DOM node cache only intended for use by React. Placed into a shared module so
27 - * that both read and write utilities may benefit from a shared cache.
28 - */
29 -var ReactDOMNodeCache = {
30 - /**
31 - * Releases fast id lookups (node/style cache). This implementation is
32 - * aggressive with purging because the bookkeeping associated with doing fine
33 - * grained deleted from the cache may outweight the benefits of the cache. The
34 - * heuristic that should be used to purge is 'any time anything is deleted'.
35 - * Typically this means that a large amount of content is being replaced and
36 - * several elements would need purging regardless. It's also a time when an
37 - * application is likely not in the middle of a "smooth operation" (such as
38 - * animating/scrolling).
39 - */
40 - purgeEntireCache: function() {
41 - nodeCache = {};
42 - return nodeCache;
43 - },
44 - getCachedNodeByID: function(id) {
45 - return nodeCache[id] ||
46 - (nodeCache[id] =
47 - document.getElementById(id) ||
48 - ReactMount.findReactRenderedDOMNodeSlow(id));
49 - }
50 -};
51 -
52 -module.exports = ReactDOMNodeCache;
React/ReactDefaultInjection.js deleted
-59
@@ -1,59 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactDefaultInjection
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactDOM = require("./ReactDOM");
22 -var ReactDOMForm = require("./ReactDOMForm");
23 -
24 -var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
25 -var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
26 -var EventPluginHub = require("./EventPluginHub");
27 -var ReactInstanceHandles = require("./ReactInstanceHandles");
28 -var SimpleEventPlugin = require("./SimpleEventPlugin");
29 -
30 -function inject() {
31 - /**
32 - * Inject module for resolving DOM hierarchy and plugin ordering.
33 - */
34 - EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);
35 - EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);
36 -
37 - /**
38 - * Two important event plugins included by default (without having to require
39 - * them).
40 - */
41 - EventPluginHub.injection.injectEventPluginsByName({
42 - 'SimpleEventPlugin': SimpleEventPlugin,
43 - 'EnterLeaveEventPlugin': EnterLeaveEventPlugin
44 - });
45 -
46 - /*
47 - * This is a bit of a hack. We need to override the <form> element
48 - * to be a composite component because IE8 does not bubble or capture
49 - * submit to the top level. In order to make this work with our
50 - * dependency graph we need to inject it here.
51 - */
52 - ReactDOM.injection.injectComponentClasses({
53 - form: ReactDOMForm
54 - });
55 -}
56 -
57 -module.exports = {
58 - inject: inject
59 -};
React/ReactEvent.js deleted
-321
@@ -1,321 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactEvent
17 - */
18 -
19 -"use strict";
20 -
21 -var BrowserEnv = require("./BrowserEnv");
22 -var EventConstants = require("./EventConstants");
23 -var EventPluginHub = require("./EventPluginHub");
24 -var ExecutionEnvironment = require("./ExecutionEnvironment");
25 -var NormalizedEventListener = require("./NormalizedEventListener");
26 -
27 -var invariant = require("./invariant");
28 -var isEventSupported = require("./isEventSupported");
29 -
30 -var registrationNames = EventPluginHub.registrationNames;
31 -var topLevelTypes = EventConstants.topLevelTypes;
32 -var listen = NormalizedEventListener.listen;
33 -var capture = NormalizedEventListener.capture;
34 -
35 -/**
36 - * `ReactEvent` is used to attach top-level event listeners. For example:
37 - *
38 - * ReactEvent.putListener('myID', 'onClick', myFunction);
39 - *
40 - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
41 - */
42 -
43 -/**
44 - * Overview of React and the event system:
45 - *
46 - * .
47 - * +-------------+ .
48 - * | DOM | .
49 - * +-------------+ . +-----------+
50 - * + . +--------+|SimpleEvent|
51 - * | . | |Plugin |
52 - * +-----|-------+ . v +-----------+
53 - * | | | . +--------------+ +------------+
54 - * | +------------.---->|EventPluginHub| | Event |
55 - * | | . | | +-----------+ | Propagators|
56 - * | ReactEvent | . | | |TapEvent | |------------|
57 - * | | . | |<---+|Plugin | |other plugin|
58 - * | +------------.---------+ | +-----------+ | utilities |
59 - * | | | . | | | +------------+
60 - * | | | . +---|----------+
61 - * | | | . | ^ +-----------+
62 - * | | | . | | |Enter/Leave|
63 - * +-----| ------+ . | +-------+|Plugin |
64 - * | . v +-----------+
65 - * + . +--------+
66 - * +-------------+ . |callback|
67 - * | application | . |registry|
68 - * |-------------| . +--------+
69 - * | | .
70 - * | | .
71 - * | | .
72 - * | | .
73 - * +-------------+ .
74 - * .
75 - * React Core . General Purpose Event Plugin System
76 - */
77 -
78 -/**
79 - * We listen for bubbled touch events on the document object.
80 - *
81 - * Firefox v8.01 (and possibly others) exhibited strange behavior when mounting
82 - * `onmousemove` events at some node that was not the document element. The
83 - * symptoms were that if your mouse is not moving over something contained
84 - * within that mount point (for example on the background) the top-level
85 - * listeners for `onmousemove` won't be called. However, if you register the
86 - * `mousemove` on the document object, then it will of course catch all
87 - * `mousemove`s. This along with iOS quirks, justifies restricting top-level
88 - * listeners to the document object only, at least for these movement types of
89 - * events and possibly all events.
90 - *
91 - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
92 - *
93 - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
94 - * they bubble to document.
95 - *
96 - * @see http://www.quirksmode.org/dom/events/keys.html.
97 - */
98 -
99 -var _isListening = false;
100 -
101 -var EVENT_LISTEN_MISUSE;
102 -var WORKER_DISABLE;
103 -
104 -if (true) {
105 - EVENT_LISTEN_MISUSE =
106 - 'You must register listeners at the top of the document, only once - ' +
107 - 'and only in the main UI thread of a browser - if you are attempting ' +
108 - 'listen in a worker, the framework is probably doing something wrong ' +
109 - 'and you should report this immediately.';
110 - WORKER_DISABLE =
111 - 'Cannot disable event listening in Worker thread. This is likely a ' +
112 - 'bug in the framework. Please report immediately.';
113 -}
114 -
115 -
116 -/**
117 - * Traps top-level events that bubble. Delegates to the main dispatcher
118 - * `handleTopLevel` after performing some basic normalization via
119 - * `TopLevelCallbackCreator.createTopLevelCallback`.
120 - */
121 -function trapBubbledEvent(topLevelType, handlerBaseName, onWhat) {
122 - listen(
123 - onWhat,
124 - handlerBaseName,
125 - ReactEvent.TopLevelCallbackCreator.createTopLevelCallback(topLevelType)
126 - );
127 -}
128 -
129 -/**
130 - * Traps a top-level event by using event capturing.
131 - */
132 -function trapCapturedEvent(topLevelType, handlerBaseName, onWhat) {
133 - capture(
134 - onWhat,
135 - handlerBaseName,
136 - ReactEvent.TopLevelCallbackCreator.createTopLevelCallback(topLevelType)
137 - );
138 -}
139 -
140 -/**
141 - * Listens to document scroll and window resize events that may change the
142 - * document scroll values. We store those results so as to discourage
143 - * application code from asking the DOM itself which could trigger additional
144 - * reflows.
145 - */
146 -function registerDocumentScrollListener() {
147 - listen(window, 'scroll', function(nativeEvent) {
148 - if (nativeEvent.target === window) {
149 - BrowserEnv.refreshAuthoritativeScrollValues();
150 - }
151 - });
152 -}
153 -
154 -function registerDocumentResizeListener() {
155 - listen(window, 'resize', function(nativeEvent) {
156 - if (nativeEvent.target === window) {
157 - BrowserEnv.refreshAuthoritativeScrollValues();
158 - }
159 - });
160 -}
161 -
162 -/**
163 - * Summary of `ReactEvent` event handling:
164 - *
165 - * - We trap low level 'top-level' events.
166 - *
167 - * - We dedupe cross-browser event names into these 'top-level types' so that
168 - * `DOMMouseScroll` or `mouseWheel` both become `topMouseWheel`.
169 - *
170 - * - At this point we have native browser events with the top-level type that
171 - * was used to catch it at the top-level.
172 - *
173 - * - We continuously stream these native events (and their respective top-level
174 - * types) to the event plugin system `EventPluginHub` and ask the plugin
175 - * system if it was able to extract `AbstractEvent` objects. `AbstractEvent`
176 - * objects are the events that applications actually deal with - they are not
177 - * native browser events but cross-browser wrappers.
178 - *
179 - * - When returning the `AbstractEvent` objects, `EventPluginHub` will make
180 - * sure each abstract event is annotated with "dispatches", which are the
181 - * sequence of listeners (and IDs) that care about the event.
182 - *
183 - * - These `AbstractEvent` objects are fed back into the event plugin system,
184 - * which in turn executes these dispatches.
185 - *
186 - * @private
187 - */
188 -function listenAtTopLevel(touchNotMouse) {
189 - invariant(
190 - !_isListening,
191 - 'listenAtTopLevel(...): Cannot setup top-level listener more than once.'
192 - );
193 - var mountAt = document;
194 -
195 - registerDocumentScrollListener();
196 - registerDocumentResizeListener();
197 - trapBubbledEvent(topLevelTypes.topMouseOver, 'mouseover', mountAt);
198 - trapBubbledEvent(topLevelTypes.topMouseDown, 'mousedown', mountAt);
199 - trapBubbledEvent(topLevelTypes.topMouseUp, 'mouseup', mountAt);
200 - trapBubbledEvent(topLevelTypes.topMouseMove, 'mousemove', mountAt);
201 - trapBubbledEvent(topLevelTypes.topMouseOut, 'mouseout', mountAt);
202 - trapBubbledEvent(topLevelTypes.topClick, 'click', mountAt);
203 - trapBubbledEvent(topLevelTypes.topDoubleClick, 'dblclick', mountAt);
204 - trapBubbledEvent(topLevelTypes.topMouseWheel, 'mousewheel', mountAt);
205 - if (touchNotMouse) {
206 - trapBubbledEvent(topLevelTypes.topTouchStart, 'touchstart', mountAt);
207 - trapBubbledEvent(topLevelTypes.topTouchEnd, 'touchend', mountAt);
208 - trapBubbledEvent(topLevelTypes.topTouchMove, 'touchmove', mountAt);
209 - trapBubbledEvent(topLevelTypes.topTouchCancel, 'touchcancel', mountAt);
210 - }
211 - trapBubbledEvent(topLevelTypes.topKeyUp, 'keyup', mountAt);
212 - trapBubbledEvent(topLevelTypes.topKeyPress, 'keypress', mountAt);
213 - trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);
214 - trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);
215 - trapBubbledEvent(
216 - topLevelTypes.topDOMCharacterDataModified,
217 - 'DOMCharacterDataModified',
218 - mountAt
219 - );
220 -
221 - // Firefox needs to capture a different mouse scroll event.
222 - // @see http://www.quirksmode.org/dom/events/tests/scroll.html
223 - trapBubbledEvent(topLevelTypes.topMouseWheel, 'DOMMouseScroll', mountAt);
224 - // IE < 9 doesn't support capturing so just trap the bubbled event there.
225 - if (isEventSupported('scroll', true)) {
226 - trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
227 - } else {
228 - trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);
229 - }
230 -
231 - if (isEventSupported('focus', true)) {
232 - trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
233 - trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
234 - } else if (isEventSupported('focusin')) {
235 - // IE has `focusin` and `focusout` events which bubble.
236 - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
237 - trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
238 - trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
239 - }
240 -}
241 -
242 -/**
243 - * This is the heart of `ReactEvent`. It simply streams the top-level native
244 - * events to `EventPluginHub`.
245 - *
246 - * @param {object} topLevelType Record from `EventConstants`.
247 - * @param {Event} nativeEvent A Standard Event with fixed `target` property.
248 - * @param {DOMElement} renderedTarget Element of interest to the framework.
249 - * @param {string} renderedTargetID string ID of `renderedTarget`.
250 - * @internal
251 - */
252 -function handleTopLevel(
253 - topLevelType,
254 - nativeEvent,
255 - renderedTargetID,
256 - renderedTarget) {
257 - var abstractEvents = EventPluginHub.extractAbstractEvents(
258 - topLevelType,
259 - nativeEvent,
260 - renderedTargetID,
261 - renderedTarget
262 - );
263 -
264 - // The event queue being processed in the same cycle allows preventDefault.
265 - EventPluginHub.enqueueAbstractEvents(abstractEvents);
266 - EventPluginHub.processAbstractEventQueue();
267 -}
268 -
269 -function setEnabled(enabled) {
270 - invariant(
271 - ExecutionEnvironment.canUseDOM,
272 - 'setEnabled(...): Cannot toggle event listening in a Worker thread. This ' +
273 - 'is likely a bug in the framework. Please report immediately.'
274 - );
275 - ReactEvent.TopLevelCallbackCreator.setEnabled(enabled);
276 -}
277 -
278 -function isEnabled() {
279 - return ReactEvent.TopLevelCallbackCreator.isEnabled();
280 -}
281 -
282 -/**
283 - * Ensures that top-level event delegation listeners are listening at `mountAt`.
284 - * There are issues with listening to both touch events and mouse events on the
285 - * top-level, so we make the caller choose which one to listen to. (If there's a
286 - * touch top-level listeners, anchors don't receive clicks for some reason, and
287 - * only in some cases).
288 - *
289 - * @param {boolean} touchNotMouse Listen to touch events instead of mouse.
290 - * @param {object} TopLevelCallbackCreator Module that can create top-level
291 - * callback handlers.
292 - * @internal
293 - */
294 -function ensureListening(touchNotMouse, TopLevelCallbackCreator) {
295 - invariant(
296 - ExecutionEnvironment.canUseDOM,
297 - 'ensureListening(...): Cannot toggle event listening in a Worker thread. ' +
298 - 'This is likely a bug in the framework. Please report immediately.'
299 - );
300 - if (!_isListening) {
301 - ReactEvent.TopLevelCallbackCreator = TopLevelCallbackCreator;
302 - listenAtTopLevel(touchNotMouse);
303 - _isListening = true;
304 - }
305 -}
306 -
307 -var ReactEvent = {
308 - TopLevelCallbackCreator: null, // Injectable callback creator.
309 - handleTopLevel: handleTopLevel,
310 - setEnabled: setEnabled,
311 - isEnabled: isEnabled,
312 - ensureListening: ensureListening,
313 - registrationNames: registrationNames,
314 - putListener: EventPluginHub.putListener,
315 - getListener: EventPluginHub.getListener,
316 - deleteAllListeners: EventPluginHub.deleteAllListeners,
317 - trapBubbledEvent: trapBubbledEvent,
318 - trapCapturedEvent: trapCapturedEvent
319 -};
320 -
321 -module.exports = ReactEvent;
React/ReactEventTopLevelCallback.js deleted
-74
@@ -1,74 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactEventTopLevelCallback
17 - */
18 -
19 -"use strict";
20 -
21 -var ExecutionEnvironment = require("./ExecutionEnvironment");
22 -var ReactEvent = require("./ReactEvent");
23 -var ReactInstanceHandles = require("./ReactInstanceHandles");
24 -
25 -var getDOMNodeID = require("./getDOMNodeID");
26 -
27 -var _topLevelListenersEnabled = true;
28 -
29 -var ReactEventTopLevelCallback = {
30 -
31 - /**
32 - * @param {boolean} enabled Whether or not all callbacks that have ever been
33 - * created with this module should be enabled.
34 - */
35 - setEnabled: function(enabled) {
36 - _topLevelListenersEnabled = !!enabled;
37 - },
38 -
39 - isEnabled: function() {
40 - return _topLevelListenersEnabled;
41 - },
42 -
43 - /**
44 - * For a given `topLevelType`, creates a callback that could be added as a
45 - * listener to the document. That top level callback will simply fix the
46 - * native events before invoking `handleTopLevel`.
47 - *
48 - * - Raw native events cannot be trusted to describe their targets correctly
49 - * so we expect that the argument to the nested function has already been
50 - * fixed. But the `target` property may not be something of interest to
51 - * React, so we find the most suitable target. But even at that point, DOM
52 - * Elements (the target ) can't be trusted to describe their IDs correctly
53 - * so we obtain the ID in a reliable manner and pass it to
54 - * `handleTopLevel`. The target/id that we found to be relevant to our
55 - * framework are called `renderedTarget`/`renderedTargetID` respectively.
56 - */
57 - createTopLevelCallback: function(topLevelType) {
58 - return function(fixedNativeEvent) {
59 - if (!_topLevelListenersEnabled) {
60 - return;
61 - }
62 - var renderedTarget = ReactInstanceHandles.getFirstReactDOM(
63 - fixedNativeEvent.target
64 - ) || ExecutionEnvironment.global;
65 - var renderedTargetID = getDOMNodeID(renderedTarget);
66 - var event = fixedNativeEvent;
67 - var target = renderedTarget;
68 - ReactEvent.handleTopLevel(topLevelType, event, renderedTargetID, target);
69 - };
70 - }
71 -
72 -};
73 -
74 -module.exports = ReactEventTopLevelCallback;
React/ReactInputSelection.js deleted
-180
@@ -1,180 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactInputSelection
17 - */
18 -
19 -"use strict";
20 -
21 -// It is not safe to read the document.activeElement property in IE if there's
22 -// nothing focused.
23 -function getActiveElement() {
24 - try {
25 - return document.activeElement;
26 - } catch (e) {
27 - }
28 -}
29 -
30 -/**
31 - * @ReactInputSelection: React input selection module. Based on Selection.js,
32 - * but modified to be suitable for react and has a couple of bug fixes (doesn't
33 - * assume buttons have range selections allowed).
34 - * Input selection module for React.
35 - */
36 -var ReactInputSelection = {
37 -
38 - hasSelectionCapabilities: function(elem) {
39 - return elem && (
40 - (elem.nodeName === 'INPUT' && elem.type === 'text') ||
41 - elem.nodeName === 'TEXTAREA' ||
42 - elem.contentEditable === 'true'
43 - );
44 - },
45 -
46 - getSelectionInformation: function() {
47 - var focusedElem = getActiveElement();
48 - return {
49 - focusedElem: focusedElem,
50 - selectionRange:
51 - ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
52 - ReactInputSelection.getSelection(focusedElem) :
53 - null
54 - };
55 - },
56 -
57 - /**
58 - * @restoreSelection: If any selection information was potentially lost,
59 - * restore it. This is useful when performing operations that could remove dom
60 - * nodes and place them back in, resulting in focus being lost.
61 - */
62 - restoreSelection: function(priorSelectionInformation) {
63 - var curFocusedElem = getActiveElement();
64 - var priorFocusedElem = priorSelectionInformation.focusedElem;
65 - var priorSelectionRange = priorSelectionInformation.selectionRange;
66 - if (curFocusedElem !== priorFocusedElem &&
67 - document.getElementById(priorFocusedElem.id)) {
68 - if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
69 - ReactInputSelection.setSelection(
70 - priorFocusedElem,
71 - priorSelectionRange
72 - );
73 - }
74 - priorFocusedElem.focus();
75 - }
76 - },
77 -
78 - /**
79 - * @getSelection: Gets the selection bounds of a textarea or input.
80 - * -@input: Look up selection bounds of this input or textarea
81 - * -@return {start: selectionStart, end: selectionEnd}
82 - */
83 - getSelection: function(input) {
84 - var range;
85 - if (input.contentEditable === 'true' && window.getSelection) {
86 - range = window.getSelection().getRangeAt(0);
87 - var commonAncestor = range.commonAncestorContainer;
88 - if (commonAncestor && commonAncestor.nodeType === 3) {
89 - commonAncestor = commonAncestor.parentNode;
90 - }
91 - if (commonAncestor !== input) {
92 - return {start: 0, end: 0};
93 - } else {
94 - return {start: range.startOffset, end: range.endOffset};
95 - }
96 - }
97 -
98 - if (!document.selection) {
99 - // Mozilla, Safari, etc.
100 - return {start: input.selectionStart, end: input.selectionEnd};
101 - }
102 -
103 - range = document.selection.createRange();
104 - if (range.parentElement() !== input) {
105 - // There can only be one selection per document in IE, so if the
106 - // containing element of the document's selection isn't our text field,
107 - // our text field must have no selection.
108 - return {start: 0, end: 0};
109 - }
110 -
111 - var length = input.value.length;
112 -
113 - if (input.nodeName === 'INPUT') {
114 - return {
115 - start: -range.moveStart('character', -length),
116 - end: -range.moveEnd('character', -length)
117 - };
118 - } else {
119 - var range2 = range.duplicate();
120 - range2.moveToElementText(input);
121 - range2.setEndPoint('StartToEnd', range);
122 - var end = length - range2.text.length;
123 - range2.setEndPoint('StartToStart', range);
124 - return {
125 - start: length - range2.text.length,
126 - end: end
127 - };
128 - }
129 - },
130 -
131 - /**
132 - * @setSelection: Sets the selection bounds of a textarea or input and focuses
133 - * the input.
134 - * -@input Set selection bounds of this input or textarea
135 - * -@rangeObj Object of same form that is returned from get*
136 - */
137 - setSelection: function(input, rangeObj) {
138 - var range;
139 - var start = rangeObj.start;
140 - var end = rangeObj.end;
141 - if (typeof end === 'undefined') {
142 - end = start;
143 - }
144 - if (document.selection) {
145 - // IE is inconsistent about character offsets when it comes to carriage
146 - // returns, so we need to manually take them into account
147 - if (input.tagName === 'TEXTAREA') {
148 - var cr_before =
149 - (input.value.slice(0, start).match(/\r/g) || []).length;
150 - var cr_inside =
151 - (input.value.slice(start, end).match(/\r/g) || []).length;
152 - start -= cr_before;
153 - end -= cr_before + cr_inside;
154 - }
155 - range = input.createTextRange();
156 - range.collapse(true);
157 - range.moveStart('character', start);
158 - range.moveEnd('character', end - start);
159 - range.select();
160 - } else {
161 - if (input.contentEditable === 'true') {
162 - if (input.childNodes.length === 1) {
163 - range = document.createRange();
164 - range.setStart(input.childNodes[0], start);
165 - range.setEnd(input.childNodes[0], end);
166 - var sel = window.getSelection();
167 - sel.removeAllRanges();
168 - sel.addRange(range);
169 - }
170 - } else {
171 - input.selectionStart = start;
172 - input.selectionEnd = Math.min(end, input.value.length);
173 - input.focus();
174 - }
175 - }
176 - }
177 -
178 -};
179 -
180 -module.exports = ReactInputSelection;
React/ReactInstanceHandles.js deleted
-326
@@ -1,326 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactInstanceHandles
17 - */
18 -
19 -"use strict";
20 -
21 -var getDOMNodeID = require("./getDOMNodeID");
22 -var invariant = require("./invariant");
23 -
24 -var SEPARATOR = '.';
25 -var SEPARATOR_LENGTH = SEPARATOR.length;
26 -
27 -/**
28 - * Maximum depth of traversals before we consider the possibility of a bad ID.
29 - */
30 -var MAX_TREE_DEPTH = 100;
31 -
32 -/**
33 - * Checks if a character in the supplied ID is a separator or the end.
34 - *
35 - * @param {string} id A React DOM ID.
36 - * @param {number} index Index of the character to check.
37 - * @return {boolean} True if the character is a separator or end of the ID.
38 - * @private
39 - */
40 -function isMarker(id, index) {
41 - return id.charAt(index) === SEPARATOR || index === id.length;
42 -}
43 -
44 -/**
45 - * Checks if the supplied string is a valid React DOM ID.
46 - *
47 - * @param {string} id A React DOM ID, maybe.
48 - * @return {boolean} True if the string is a valid React DOM ID.
49 - * @private
50 - */
51 -function isValidID(id) {
52 - return id === '' || (
53 - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
54 - );
55 -}
56 -
57 -/**
58 - * True if the supplied `node` is rendered by React.
59 - *
60 - * @param {DOMElement} node DOM Element to check.
61 - * @return {boolean} True if the DOM Element appears to be rendered by React.
62 - * @private
63 - */
64 -function isRenderedByReact(node) {
65 - var id = getDOMNodeID(node);
66 - return id && id.charAt(0) === SEPARATOR;
67 -}
68 -
69 -/**
70 - * Gets the parent ID of the supplied React DOM ID, `id`.
71 - *
72 - * @param {string} id ID of a component.
73 - * @return {string} ID of the parent, or an empty string.
74 - * @private
75 - */
76 -function parentID(id) {
77 - return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
78 -}
79 -
80 -/**
81 - * Traverses the parent path between two IDs (either up or down). The IDs must
82 - * not be the same, and there must exist a parent path between them.
83 - *
84 - * @param {?string} start ID at which to start traversal.
85 - * @param {?string} stop ID at which to end traversal.
86 - * @param {function} cb Callback to invoke each ID with.
87 - * @param {?boolean} skipFirst Whether or not to skip the first node.
88 - * @param {?boolean} skipLast Whether or not to skip the last node.
89 - * @private
90 - */
91 -function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
92 - start = start || '';
93 - stop = stop || '';
94 - invariant(
95 - start !== stop,
96 - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
97 - start
98 - );
99 - var ancestorID = ReactInstanceHandles.getFirstCommonAncestorID(start, stop);
100 - var traverseUp = ancestorID === stop;
101 - invariant(
102 - traverseUp || ancestorID === start,
103 - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
104 - 'not have a parent path.',
105 - start,
106 - stop
107 - );
108 - // Traverse from `start` to `stop` one depth at a time.
109 - var depth = 0;
110 - var traverse = traverseUp ? parentID : ReactInstanceHandles.nextDescendantID;
111 - for (var id = start; /* until break */; id = traverse(id, stop)) {
112 - if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
113 - cb(id, traverseUp, arg);
114 - }
115 - if (id === stop) {
116 - // Only break //after// visiting `stop`.
117 - break;
118 - }
119 - invariant(
120 - depth++ < MAX_TREE_DEPTH,
121 - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
122 - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
123 - start, stop
124 - );
125 - }
126 -}
127 -
128 -/**
129 - * Manages the IDs assigned to DOM representations of React components. This
130 - * uses a specific scheme in order to traverse the DOM efficiently (e.g. in
131 - * order to simulate events).
132 - *
133 - * @internal
134 - */
135 -var ReactInstanceHandles = {
136 -
137 - separator: SEPARATOR,
138 -
139 - /**
140 - * Traverses up the ancestors of the supplied node to find a node that is a
141 - * DOM representation of a React component.
142 - *
143 - * @param {DOMElement} node
144 - * @return {?DOMElement}
145 - * @internal
146 - */
147 - getFirstReactDOM: function(node) {
148 - var current = node;
149 - while (current && current.parentNode !== current) {
150 - if (isRenderedByReact(current)) {
151 - return current;
152 - }
153 - current = current.parentNode;
154 - }
155 - return null;
156 - },
157 -
158 - /**
159 - * Finds a node with the supplied `id` inside of the supplied `ancestorNode`.
160 - * Exploits the ID naming scheme to perform the search quickly.
161 - *
162 - * @param {DOMElement} ancestorNode Search from this root.
163 - * @pararm {string} id ID of the DOM representation of the component.
164 - * @return {?DOMElement} DOM element with the supplied `id`, if one exists.
165 - * @internal
166 - */
167 - findComponentRoot: function(ancestorNode, id) {
168 - var child = ancestorNode.firstChild;
169 - while (child) {
170 - if (id === child.id) {
171 - return child;
172 - } else if (id.indexOf(child.id) === 0) {
173 - return ReactInstanceHandles.findComponentRoot(child, id);
174 - }
175 - child = child.nextSibling;
176 - }
177 - // Effectively: return null;
178 - },
179 -
180 - /**
181 - * Gets the nearest common ancestor ID of two IDs.
182 - *
183 - * Using this ID scheme, the nearest common ancestor ID is the longest common
184 - * prefix of the two IDs that immediately preceded a "marker" in both strings.
185 - *
186 - * @param {string} oneID
187 - * @param {string} twoID
188 - * @return {string} Nearest common ancestor ID, or the empty string if none.
189 - * @internal
190 - */
191 - getFirstCommonAncestorID: function(oneID, twoID) {
192 - var minLength = Math.min(oneID.length, twoID.length);
193 - if (minLength === 0) {
194 - return '';
195 - }
196 - var lastCommonMarkerIndex = 0;
197 - // Use `<=` to traverse until the "EOL" of the shorter string.
198 - for (var i = 0; i <= minLength; i++) {
199 - if (isMarker(oneID, i) && isMarker(twoID, i)) {
200 - lastCommonMarkerIndex = i;
201 - } else if (oneID.charAt(i) !== twoID.charAt(i)) {
202 - break;
203 - }
204 - }
205 - var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
206 - invariant(
207 - isValidID(longestCommonID),
208 - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
209 - oneID,
210 - twoID,
211 - longestCommonID
212 - );
213 - return longestCommonID;
214 - },
215 - /**
216 - * Creates a DOM ID to use when mounting React components.
217 - *
218 - * @param {number} mountPointCount The count of React renders so far.
219 - * @return {string} React root ID.
220 - * @internal
221 - */
222 - getReactRootID: function(mountPointCount) {
223 - return '.reactRoot[' + mountPointCount + ']';
224 - },
225 -
226 - /**
227 - * Gets the DOM ID of the React component that is the root of the tree that
228 - * contains the React component with the supplied DOM ID.
229 - *
230 - * @param {string} id DOM ID of a React component.
231 - * @return {string} DOM ID of the React component that is the root.
232 - * @internal
233 - */
234 - getReactRootIDFromNodeID: function(id) {
235 - var regexResult = /\.reactRoot\[[^\]]+\]/.exec(id);
236 - return regexResult && regexResult[0];
237 - },
238 -
239 - /**
240 - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
241 - * should would receive a `mouseEnter` or `mouseLeave` event.
242 - *
243 - * NOTE: Does not invoke the callback on the nearest common ancestor because
244 - * nothing "entered" or "left" that element.
245 - *
246 - * @param {string} leaveID ID being left.
247 - * @param {string} enterID ID being entered.
248 - * @param {function} cb Callback to invoke on each entered/left ID.
249 - * @param {*} upArg Argument to invoke the callback with on left IDs.
250 - * @param {*} downArg Argument to invoke the callback with on entered IDs.
251 - * @internal
252 - */
253 - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
254 - var longestCommonID = ReactInstanceHandles.getFirstCommonAncestorID(
255 - leaveID,
256 - enterID
257 - );
258 - if (longestCommonID !== leaveID) {
259 - traverseParentPath(leaveID, longestCommonID, cb, upArg, false, true);
260 - }
261 - if (longestCommonID !== enterID) {
262 - traverseParentPath(longestCommonID, enterID, cb, downArg, true, false);
263 - }
264 - },
265 -
266 - /**
267 - * Simulates the traversal of a two-phase, capture/bubble event dispatch.
268 - *
269 - * NOTE: This traversal happens on IDs without touching the DOM.
270 - *
271 - * @param {string} targetID ID of the target node.
272 - * @param {function} cb Callback to invoke.
273 - * @param {*} arg Argument to invoke the callback with.
274 - * @internal
275 - */
276 - traverseTwoPhase: function(targetID, cb, arg) {
277 - if (targetID) {
278 - traverseParentPath('', targetID, cb, arg, true, false);
279 - traverseParentPath(targetID, '', cb, arg, false, true);
280 - }
281 - },
282 -
283 - /**
284 - * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
285 - * supplied `destinationID`. If they are equal, the ID is returned.
286 - *
287 - * @param {string} ancestorID ID of an ancestor node of `destinationID`.
288 - * @param {string} destinationID ID of the destination node.
289 - * @return {string} Next ID on the path from `ancestorID` to `destinationID`.
290 - * @internal
291 - */
292 - nextDescendantID: function(ancestorID, destinationID) {
293 - invariant(
294 - isValidID(ancestorID) && isValidID(destinationID),
295 - 'nextDescendantID(%s, %s): Received an invalid React DOM ID.',
296 - ancestorID,
297 - destinationID
298 - );
299 - var longestCommonID = ReactInstanceHandles.getFirstCommonAncestorID(
300 - ancestorID,
301 - destinationID
302 - );
303 - invariant(
304 - longestCommonID === ancestorID,
305 - 'nextDescendantID(...): React has made an invalid assumption about the ' +
306 - 'DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
307 - ancestorID,
308 - destinationID
309 - );
310 - if (ancestorID === destinationID) {
311 - return ancestorID;
312 - }
313 - // Skip over the ancestor and the immediate separator. Traverse until we hit
314 - // another separator or we reach the end of `destinationID`.
315 - var start = ancestorID.length + SEPARATOR_LENGTH;
316 - for (var i = start; i < destinationID.length; i++) {
317 - if (isMarker(destinationID, i)) {
318 - break;
319 - }
320 - }
321 - return destinationID.substr(0, i);
322 - }
323 -
324 -};
325 -
326 -module.exports = ReactInstanceHandles;
React/ReactMount.js deleted
-232
@@ -1,232 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactMount
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactEvent = require("./ReactEvent");
22 -var ReactInstanceHandles = require("./ReactInstanceHandles");
23 -var ReactEventTopLevelCallback = require("./ReactEventTopLevelCallback");
24 -
25 -var $ = require("./$");
26 -
27 -var globalMountPointCounter = 0;
28 -
29 -/** Mapping from reactRoot DOM ID to React component instance. */
30 -var instanceByReactRootID = {};
31 -
32 -/** Mapping from reactRoot DOM ID to `container` nodes. */
33 -var containersByReactRootID = {};
34 -
35 -/**
36 - * @param {DOMElement} container DOM element that may contain a React component.
37 - * @return {?string} A "reactRoot" ID, if a React component is rendered.
38 - */
39 -function getReactRootID(container) {
40 - return container.firstChild && container.firstChild.id;
41 -}
42 -
43 -/**
44 - * Mounting is the process of initializing a React component by creatings its
45 - * representative DOM elements and inserting them into a supplied `container`.
46 - * Any prior content inside `container` is destroyed in the process.
47 - *
48 - * ReactMount.renderComponent(component, $('container'));
49 - *
50 - * <div id="container"> <-- Supplied `container`.
51 - * <div id=".reactRoot[3]"> <-- Rendered reactRoot of React component.
52 - * // ...
53 - * </div>
54 - * </div>
55 - *
56 - * Inside of `container`, the first element rendered is the "reactRoot".
57 - */
58 -var ReactMount = {
59 -
60 - /** Time spent generating markup. */
61 - totalInstantiationTime: 0,
62 -
63 - /** Time spent inserting markup into the DOM. */
64 - totalInjectionTime: 0,
65 -
66 - /** Whether support for touch events should be initialized. */
67 - useTouchEvents: false,
68 -
69 - /**
70 - * This is a hook provided to support rendering React components while
71 - * ensuring that the apparent scroll position of its `container` does not
72 - * change.
73 - *
74 - * @param {DOMElement} container The `container` being rendered into.
75 - * @param {function} renderCallback This must be called once to do the render.
76 - */
77 - scrollMonitor: function(container, renderCallback) {
78 - renderCallback();
79 - },
80 -
81 - /**
82 - * Ensures tht the top-level event delegation listener is set up. This will be
83 - * invoked some time before the first time any React component is rendered.
84 - *
85 - * @param {object} TopLevelCallbackCreator
86 - * @private
87 - */
88 - prepareTopLevelEvents: function(TopLevelCallbackCreator) {
89 - ReactEvent.ensureListening(
90 - ReactMount.useTouchEvents,
91 - TopLevelCallbackCreator
92 - );
93 - },
94 -
95 - /**
96 - * Renders a React component into the DOM in the supplied `container`.
97 - *
98 - * If the React component was previously rendered into `container`, this will
99 - * perform an update on it and only mutate the DOM as necessary to reflect the
100 - * latest React component.
101 - *
102 - * @param {ReactComponent} nextComponent Component instance to render.
103 - * @param {DOMElement} container DOM element to render into.
104 - * @return {ReactComponent} Component instance rendered in `container`.
105 - */
106 - renderComponent: function(nextComponent, container) {
107 - var prevComponent = instanceByReactRootID[getReactRootID(container)];
108 - if (prevComponent) {
109 - var nextProps = nextComponent.props;
110 - ReactMount.scrollMonitor(container, function() {
111 - prevComponent.replaceProps(nextProps);
112 - });
113 - return prevComponent;
114 - }
115 -
116 - ReactMount.prepareTopLevelEvents(ReactEventTopLevelCallback);
117 -
118 - var reactRootID = ReactMount.registerContainer(container);
119 - instanceByReactRootID[reactRootID] = nextComponent;
120 - nextComponent.mountComponentIntoNode(reactRootID, container);
121 - return nextComponent;
122 - },
123 -
124 - /**
125 - * Creates a function that accepts a `container` and renders the supplied
126 - * React component instance into it.
127 - *
128 - * var renderInto = ReactMount.createComponentRenderer(component);
129 - * // ...
130 - * var component = renderInto($('container'));
131 - *
132 - * @param {ReactComponent} component Component instance to render.
133 - * @return {function(DOMElement): ReactComponent}
134 - */
135 - createComponentRenderer: function(component) {
136 - return function(container) {
137 - return ReactMount.renderComponent(component, container);
138 - };
139 - },
140 -
141 - /**
142 - * Constructs a component instance of `constructor` with `initialProps` and
143 - * renders it into the supplied `container`.
144 - *
145 - * @param {function} constructor React component constructor.
146 - * @param {?object} props Initial props of the component instance.
147 - * @param {DOMElement} container DOM element to render into.
148 - * @return {ReactComponent} Component instance rendered in `container`.
149 - */
150 - constructAndRenderComponent: function(constructor, props, container) {
151 - return ReactMount.renderComponent(constructor(props), container);
152 - },
153 -
154 - /**
155 - * Constructs a component instance of `constructor` with `initialProps` and
156 - * renders it into a container node identified by supplied `id`.
157 - *
158 - * @param {function} componentConstructor React component constructor
159 - * @param {?object} props Initial props of the component instance.
160 - * @param {string} id ID of the DOM element to render into.
161 - * @return {ReactComponent} Component instance rendered in the container node.
162 - */
163 - constructAndRenderComponentByID: function(constructor, props, id) {
164 - return ReactMount.constructAndRenderComponent(constructor, props, $(id));
165 - },
166 -
167 - /**
168 - * Registers a container node into which React components will be rendered.
169 - * This also creates the "reatRoot" ID that will be assigned to the element
170 - * rendered within.
171 - *
172 - * @param {DOMElement} container DOM element to register as a container.
173 - * @return {string} The "reactRoot" ID of elements rendered within.
174 - */
175 - registerContainer: function(container) {
176 - var reactRootID = getReactRootID(container);
177 - if (reactRootID) {
178 - // If one exists, make sure it is a valid "reactRoot" ID.
179 - reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
180 - }
181 - if (!reactRootID) {
182 - // No valid "reactRoot" ID found, create one.
183 - reactRootID = ReactInstanceHandles.getReactRootID(
184 - globalMountPointCounter++
185 - );
186 - }
187 - containersByReactRootID[reactRootID] = container;
188 - return reactRootID;
189 - },
190 -
191 - /**
192 - * Unmounts and destroys the React component rendered in the `container`.
193 - *
194 - * @param {DOMElement} container DOM element containing a React component.
195 - */
196 - unmountAndReleaseReactRootNode: function(container) {
197 - var reactRootID = getReactRootID(container);
198 - var component = instanceByReactRootID[reactRootID];
199 - // TODO: Consider throwing if no `component` was found.
200 - component.unmountComponentFromNode(container);
201 - delete instanceByReactRootID[reactRootID];
202 - delete containersByReactRootID[reactRootID];
203 - },
204 -
205 - /**
206 - * Finds the container DOM element that contains React component to which the
207 - * supplied DOM `id` belongs.
208 - *
209 - * @param {string} id The ID of an element rendered by a React component.
210 - * @return {?DOMElement} DOM element that contains the `id`.
211 - */
212 - findReactContainerForID: function(id) {
213 - var reatRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
214 - // TODO: Consider throwing if `id` is not a valid React element ID.
215 - return containersByReactRootID[reatRootID];
216 - },
217 -
218 - /**
219 - * Given the ID of a DOM node rendered by a React component, finds the root
220 - * DOM node of the React component.
221 - *
222 - * @param {string} id ID of a DOM node in the React component.
223 - * @return {?DOMElement} Root DOM node of the React component.
224 - */
225 - findReactRenderedDOMNodeSlow: function(id) {
226 - var reactRoot = ReactMount.findReactContainerForID(id);
227 - return ReactInstanceHandles.findComponentRoot(reactRoot, id);
228 - }
229 -
230 -};
231 -
232 -module.exports = ReactMount;
React/ReactMultiChild.js deleted
-208
@@ -1,208 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactMultiChild
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactComponent = require("./ReactComponent");
22 -
23 -/**
24 - * Given a `curChild` and `newChild`, determines if `curChild` should be managed
25 - * as it exists, as opposed to being destroyed and/or replaced.
26 - * @param {?ReactComponent} curChild
27 - * @param {?ReactComponent} newChild
28 - * @return {!boolean} Whether or not `curChild` should be updated with
29 - * `newChild`'s props
30 - */
31 -function shouldManageExisting(curChild, newChild) {
32 - return curChild && newChild && curChild.constructor === newChild.constructor;
33 -}
34 -
35 -/**
36 - * `ReactMultiChild` provides common functionality for components that have
37 - * multiple children. Standard `ReactCompositeComponent`s do not currently have
38 - * multiple children. `ReactNativeComponent`s do, however. Other specially
39 - * reconciled components will also have multiple children. Contains three
40 - * internally used properties that are used to keep track of state throughout
41 - * the `updateMultiChild` process.
42 - *
43 - * @class ReactMultiChild
44 - */
45 -
46 -/**
47 - * @lends `ReactMultiChildMixin`.
48 - */
49 -var ReactMultiChildMixin = {
50 -
51 - enqueueMarkupAt: function(markup, insertAt) {
52 - this.domOperations = this.domOperations || [];
53 - this.domOperations.push({insertMarkup: markup, finalIndex: insertAt});
54 - },
55 -
56 - enqueueMove: function(originalIndex, finalIndex) {
57 - this.domOperations = this.domOperations || [];
58 - this.domOperations.push({moveFrom: originalIndex, finalIndex: finalIndex});
59 - },
60 -
61 - enqueueUnmountChildByName: function(name, removeChild) {
62 - if (ReactComponent.isValidComponent(removeChild)) {
63 - this.domOperations = this.domOperations || [];
64 - this.domOperations.push({removeAt: removeChild._domIndex});
65 - removeChild.unmountComponent && removeChild.unmountComponent();
66 - delete this._renderedChildren[name];
67 - }
68 - },
69 -
70 - /**
71 - * Process any pending DOM operations that have been accumulated when updating
72 - * the UI. By default, we execute the injected `DOMIDOperations` module's
73 - * `manageChildrenByParentID` which does executes the DOM operations without
74 - * any animation. It can be used as a reference implementation for special
75 - * animation based implementations.
76 - *
77 - * @abstract
78 - */
79 - processChildDOMOperationsQueue: function() {
80 - if (this.domOperations) {
81 - ReactComponent.DOMIDOperations
82 - .manageChildrenByParentID(this._rootNodeID, this.domOperations);
83 - this.domOperations = null;
84 - }
85 - },
86 -
87 - unmountMultiChild: function() {
88 - var renderedChildren = this._renderedChildren;
89 - for (var name in renderedChildren) {
90 - if (renderedChildren.hasOwnProperty(name) && renderedChildren[name]) {
91 - var renderedChild = renderedChildren[name];
92 - renderedChild.unmountComponent && renderedChild.unmountComponent();
93 - }
94 - }
95 - this._renderedChildren = null;
96 - },
97 -
98 - /**
99 - * Generates markup for a component that holds multiple children. #todo: Allow
100 - * all `ReactMultiChildMixin`s to support having arrays of children without a
101 - * container node. This current implementation may assume that children exist
102 - * at domIndices [0, parentNode.length].
103 - *
104 - * Has side effects of (likely) causing events to be registered. Also, every
105 - * component instance may only be rendered once.
106 - *
107 - * @param {?Object} children Flattened children object.
108 - * @return {!String} The rendered markup.
109 - */
110 - mountMultiChild: function(children, transaction) {
111 - var accum = '';
112 - var index = 0;
113 - for (var name in children) {
114 - var child = children[name];
115 - if (children.hasOwnProperty(name) && child) {
116 - accum += child.mountComponent(
117 - this._rootNodeID + '.' + name,
118 - transaction
119 - );
120 - child._domIndex = index;
121 - index++;
122 - }
123 - }
124 - this._renderedChildren = children; // children are in just the right form!
125 - this.domOperations = null;
126 - return accum;
127 - },
128 -
129 - /**
130 - * Reconciles new children with old children in three phases.
131 - *
132 - * - Adds new content while updating existing children that should remain.
133 - * - Remove children that are no longer present in the next children.
134 - * - As a very last step, moves existing dom structures around.
135 - * - (Comment 1) `curChildrenDOMIndex` is the largest index of the current
136 - * rendered children that appears in the next children and did not need to
137 - * be "moved".
138 - * - (Comment 2) This is the key insight. If any non-removed child's previous
139 - * index is less than `curChildrenDOMIndex` it must be moved.
140 - *
141 - * @param {?Object} children Flattened children object.
142 - */
143 - updateMultiChild: function(nextChildren, transaction) {
144 - if (!nextChildren && !this._renderedChildren) {
145 - return;
146 - } else if (nextChildren && !this._renderedChildren) {
147 - this._renderedChildren = {}; // lazily allocate backing store with nothing
148 - } else if (!nextChildren && this._renderedChildren) {
149 - nextChildren = {};
150 - }
151 - var rootDomIdDot = this._rootNodeID + '.';
152 - var markupBuffer = null; // Accumulate adjacent new children markup.
153 - var numPendingInsert = 0; // How many root nodes are waiting in markupBuffer
154 - var loopDomIndex = 0; // Index of loop through new children.
155 - var curChildrenDOMIndex = 0; // See (Comment 1)
156 - for (var name in nextChildren) {
157 - if (!nextChildren.hasOwnProperty(name)) {continue;}
158 - var curChild = this._renderedChildren[name];
159 - var nextChild = nextChildren[name];
160 - if (shouldManageExisting(curChild, nextChild)) {
161 - if (markupBuffer) {
162 - this.enqueueMarkupAt(markupBuffer, loopDomIndex - numPendingInsert);
163 - markupBuffer = null;
164 - }
165 - numPendingInsert = 0;
166 - if (curChild._domIndex < curChildrenDOMIndex) { // (Comment 2)
167 - this.enqueueMove(curChild._domIndex, loopDomIndex);
168 - }
169 - curChildrenDOMIndex = Math.max(curChild._domIndex, curChildrenDOMIndex);
170 - !nextChild.props.isStatic &&
171 - curChild.receiveProps(nextChild.props, transaction);
172 - curChild._domIndex = loopDomIndex;
173 - } else {
174 - if (curChild) { // !shouldUpdate && curChild => delete
175 - this.enqueueUnmountChildByName(name, curChild);
176 - curChildrenDOMIndex =
177 - Math.max(curChild._domIndex, curChildrenDOMIndex);
178 - }
179 - if (nextChild) { // !shouldUpdate && nextChild => insert
180 - this._renderedChildren[name] = nextChild;
181 - var nextMarkup =
182 - nextChild.mountComponent(rootDomIdDot + name, transaction);
183 - markupBuffer = markupBuffer ? markupBuffer + nextMarkup : nextMarkup;
184 - numPendingInsert++;
185 - nextChild._domIndex = loopDomIndex;
186 - }
187 - }
188 - loopDomIndex = nextChild ? loopDomIndex + 1 : loopDomIndex;
189 - }
190 - if (markupBuffer) {
191 - this.enqueueMarkupAt(markupBuffer, loopDomIndex - numPendingInsert);
192 - }
193 - for (var childName in this._renderedChildren) { // from other direction
194 - if (!this._renderedChildren.hasOwnProperty(childName)) { continue; }
195 - var child = this._renderedChildren[childName];
196 - if (child && !nextChildren[childName]) {
197 - this.enqueueUnmountChildByName(childName, child);
198 - }
199 - }
200 - this.processChildDOMOperationsQueue();
201 - }
202 -};
203 -
204 -var ReactMultiChild = {
205 - Mixin: ReactMultiChildMixin
206 -};
207 -
208 -module.exports = ReactMultiChild;
React/ReactNativeComponent.js deleted
-331
@@ -1,331 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactNativeComponent
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var CSSPropertyOperations = require("./CSSPropertyOperations");
23 -var DOMPropertyOperations = require("./DOMPropertyOperations");
24 -var ReactComponent = require("./ReactComponent");
25 -var ReactEvent = require("./ReactEvent");
26 -var ReactMultiChild = require("./ReactMultiChild");
27 -
28 -var escapeTextForBrowser = require("./escapeTextForBrowser");
29 -var flattenChildren = require("./flattenChildren");
30 -var invariant = require("./invariant");
31 -var keyOf = require("./keyOf");
32 -var merge = require("./merge");
33 -var mixInto = require("./mixInto");
34 -
35 -var putListener = ReactEvent.putListener;
36 -var registrationNames = ReactEvent.registrationNames;
37 -
38 -// For quickly matching children type, to test if can be treated as content.
39 -var CONTENT_TYPES = {'string': true, 'number': true};
40 -
41 -var CONTENT = keyOf({content: null});
42 -var DANGEROUSLY_SET_INNER_HTML = keyOf({dangerouslySetInnerHTML: null});
43 -var STYLE = keyOf({style: null});
44 -
45 -/**
46 - * @param {?object} props
47 - */
48 -function assertValidProps(props) {
49 - if (!props) {
50 - return;
51 - }
52 - // Note the use of `!=` which checks for null or undefined.
53 - var hasChildren = props.children != null ? 1 : 0;
54 - var hasContent = props.content != null ? 1 : 0;
55 - var hasInnerHTML = props.dangerouslySetInnerHTML != null ? 1 : 0;
56 - invariant(
57 - hasChildren + hasContent + hasInnerHTML <= 1,
58 - 'Can only set one of `children`, `props.content`, or ' +
59 - '`props.dangerouslySetInnerHTML`.'
60 - );
61 - invariant(
62 - props.style == null || typeof props.style === 'object',
63 - 'The `style` prop expects a mapping from style properties to values, ' +
64 - 'not a string.'
65 - );
66 -}
67 -
68 -/**
69 - * @constructor ReactNativeComponent
70 - * @extends ReactComponent
71 - * @extends ReactMultiChild
72 - */
73 -function ReactNativeComponent(tag, omitClose) {
74 - this._tagOpen = '<' + tag + ' ';
75 - this._tagClose = omitClose ? '' : '</' + tag + '>';
76 - this.tagName = tag.toUpperCase();
77 -}
78 -
79 -ReactNativeComponent.Mixin = {
80 -
81 - /**
82 - * Generates root tag markup then recurses. This method has side effects and
83 - * is not idempotent.
84 - *
85 - * @internal
86 - * @param {string} rootID The root DOM ID for this node.
87 - * @param {ReactReconcileTransaction} transaction
88 - * @return {string} The computed markup.
89 - */
90 - mountComponent: function(rootID, transaction) {
91 - ReactComponent.Mixin.mountComponent.call(this, rootID, transaction);
92 - assertValidProps(this.props);
93 - return (
94 - this._createOpenTagMarkup() +
95 - this._createContentMarkup(transaction) +
96 - this._tagClose
97 - );
98 - },
99 -
100 - /**
101 - * Creates markup for the open tag and all attributes.
102 - *
103 - * This method has side effects because events get registered.
104 - *
105 - * Iterating over object properties is faster than iterating over arrays.
106 - * @see http://jsperf.com/obj-vs-arr-iteration
107 - *
108 - * @private
109 - * @return {string} Markup of opening tag.
110 - */
111 - _createOpenTagMarkup: function() {
112 - var props = this.props;
113 - var ret = this._tagOpen;
114 -
115 - for (var propKey in props) {
116 - if (!props.hasOwnProperty(propKey)) {
117 - continue;
118 - }
119 - var propValue = props[propKey];
120 - if (propValue == null) {
121 - continue;
122 - }
123 - if (registrationNames[propKey]) {
124 - putListener(this._rootNodeID, propKey, propValue);
125 - } else {
126 - if (propKey === STYLE) {
127 - if (propValue) {
128 - propValue = props.style = merge(props.style);
129 - }
130 - propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
131 - }
132 - var markup =
133 - DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
134 - if (markup) {
135 - ret += ' ' + markup;
136 - }
137 - }
138 - }
139 -
140 - return ret + ' id="' + this._rootNodeID + '">';
141 - },
142 -
143 - /**
144 - * Creates markup for the content between the tags.
145 - *
146 - * @private
147 - * @param {ReactReconcileTransaction} transaction
148 - * @return {string} Content markup.
149 - */
150 - _createContentMarkup: function(transaction) {
151 - // Intentional use of != to avoid catching zero/false.
152 - var innerHTML = this.props.dangerouslySetInnerHTML;
153 - if (innerHTML != null) {
154 - if (innerHTML.__html != null) {
155 - return innerHTML.__html;
156 - }
157 - } else {
158 - var contentToUse = this.props.content != null ? this.props.content :
159 - CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
160 - var childrenToUse = contentToUse != null ? null : this.props.children;
161 - if (contentToUse != null) {
162 - return escapeTextForBrowser(contentToUse);
163 - } else if (childrenToUse != null) {
164 - return this.mountMultiChild(
165 - flattenChildren(childrenToUse),
166 - transaction
167 - );
168 - }
169 - }
170 - return '';
171 - },
172 -
173 - /**
174 - * Controls a native DOM component after it has already been allocated and
175 - * attached to the DOM. Reconciles the root DOM node, then recurses.
176 - *
177 - * @internal
178 - * @param {object} nextProps
179 - * @param {ReactReconcileTransaction} transaction
180 - */
181 - receiveProps: function(nextProps, transaction) {
182 - invariant(
183 - this._rootNodeID,
184 - 'Trying to control a native dom element without a backing id'
185 - );
186 - assertValidProps(nextProps);
187 - ReactComponent.Mixin.receiveProps.call(this, nextProps, transaction);
188 - this._updateDOMProperties(nextProps);
189 - this._updateDOMChildren(nextProps, transaction);
190 - this.props = nextProps;
191 - },
192 -
193 - /**
194 - * Reconciles the properties by detecting differences in property values and
195 - * updating the DOM as necessary. This function is probably the single most
196 - * critical path for performance optimization.
197 - *
198 - * TODO: Benchmark whether checking for changed values in memory actually
199 - * improves performance (especially statically positioned elements).
200 - * TODO: Benchmark the effects of putting this at the top since 99% of props
201 - * do not change for a given reconciliation.
202 - * TODO: Benchmark areas that can be improved with caching.
203 - *
204 - * @private
205 - * @param {object} nextProps
206 - */
207 - _updateDOMProperties: function(nextProps) {
208 - var lastProps = this.props;
209 - for (var propKey in nextProps) {
210 - var nextProp = nextProps[propKey];
211 - var lastProp = lastProps[propKey];
212 - if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
213 - continue;
214 - }
215 - if (propKey === STYLE) {
216 - if (nextProp) {
217 - nextProp = nextProps.style = merge(nextProp);
218 - }
219 - var styleUpdates;
220 - for (var styleName in nextProp) {
221 - if (!nextProp.hasOwnProperty(styleName)) {
222 - continue;
223 - }
224 - if (!lastProp || lastProp[styleName] !== nextProp[styleName]) {
225 - if (!styleUpdates) {
226 - styleUpdates = {};
227 - }
228 - styleUpdates[styleName] = nextProp[styleName];
229 - }
230 - }
231 - if (styleUpdates) {
232 - ReactComponent.DOMIDOperations.updateStylesByID(
233 - this._rootNodeID,
234 - styleUpdates
235 - );
236 - }
237 - } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
238 - var lastHtml = lastProp && lastProp.__html;
239 - var nextHtml = nextProp && nextProp.__html;
240 - if (lastHtml !== nextHtml) {
241 - ReactComponent.DOMIDOperations.updateInnerHTMLByID(
242 - this._rootNodeID,
243 - nextProp
244 - );
245 - }
246 - } else if (propKey === CONTENT) {
247 - ReactComponent.DOMIDOperations.updateTextContentByID(
248 - this._rootNodeID,
249 - '' + nextProp
250 - );
251 - } else if (registrationNames[propKey]) {
252 - putListener(this._rootNodeID, propKey, nextProp);
253 - } else {
254 - ReactComponent.DOMIDOperations.updatePropertyByID(
255 - this._rootNodeID,
256 - propKey,
257 - nextProp
258 - );
259 - }
260 - }
261 - },
262 -
263 - /**
264 - * Reconciles the children with the various properties that affect the
265 - * children content.
266 - *
267 - * @param {object} nextProps
268 - * @param {ReactReconcileTransaction} transaction
269 - */
270 - _updateDOMChildren: function(nextProps, transaction) {
271 - var thisPropsContentType = typeof this.props.content;
272 - var thisPropsContentEmpty =
273 - this.props.content == null || thisPropsContentType === 'boolean';
274 - var nextPropsContentType = typeof nextProps.content;
275 - var nextPropsContentEmpty =
276 - nextProps.content == null || nextPropsContentType === 'boolean';
277 -
278 - var lastUsedContent = !thisPropsContentEmpty ? this.props.content :
279 - CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
280 -
281 - var contentToUse = !nextPropsContentEmpty ? nextProps.content :
282 - CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
283 -
284 - // Note the use of `!=` which checks for null or undefined.
285 -
286 - var lastUsedChildren =
287 - lastUsedContent != null ? null : this.props.children;
288 - var childrenToUse = contentToUse != null ? null : nextProps.children;
289 -
290 - if (contentToUse != null) {
291 - var childrenRemoved = lastUsedChildren != null && childrenToUse == null;
292 - if (childrenRemoved) {
293 - this.updateMultiChild(null, transaction);
294 - }
295 - if (lastUsedContent !== contentToUse) {
296 - ReactComponent.DOMIDOperations.updateTextContentByID(
297 - this._rootNodeID,
298 - '' + contentToUse
299 - );
300 - }
301 - } else {
302 - var contentRemoved = lastUsedContent != null && contentToUse == null;
303 - if (contentRemoved) {
304 - ReactComponent.DOMIDOperations.updateTextContentByID(
305 - this._rootNodeID,
306 - ''
307 - );
308 - }
309 - this.updateMultiChild(flattenChildren(nextProps.children), transaction);
310 - }
311 - },
312 -
313 - /**
314 - * Destroys all event registrations for this instance. Does not remove from
315 - * the DOM. That must be done by the parent.
316 - *
317 - * @internal
318 - */
319 - unmountComponent: function() {
320 - ReactComponent.Mixin.unmountComponent.call(this);
321 - this.unmountMultiChild();
322 - ReactEvent.deleteAllListeners(this._rootNodeID);
323 - }
324 -
325 -};
326 -
327 -mixInto(ReactNativeComponent, ReactComponent.Mixin);
328 -mixInto(ReactNativeComponent, ReactNativeComponent.Mixin);
329 -mixInto(ReactNativeComponent, ReactMultiChild.Mixin);
330 -
331 -module.exports = ReactNativeComponent;
React/ReactOnDOMReady.js deleted
-95
@@ -1,95 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactOnDOMReady
17 - */
18 -
19 -"use strict";
20 -
21 -var PooledClass = require("./PooledClass");
22 -
23 -var mixInto = require("./mixInto");
24 -
25 -/**
26 - * A specialized pseudo-event module to help keep track of components waiting to
27 - * be notified when their DOM representations are available for use.
28 - *
29 - * This implements `PooledClass`, so you should never need to instantiate this.
30 - * Instead, use `ReactOnDOMReady.getPooled()`.
31 - *
32 - * @param {?array<function>} initialCollection
33 - * @class ReactOnDOMReady
34 - * @implements PooledClass
35 - * @internal
36 - */
37 -function ReactOnDOMReady(initialCollection) {
38 - this._queue = initialCollection || null;
39 -}
40 -
41 -mixInto(ReactOnDOMReady, {
42 -
43 - /**
44 - * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used
45 - * to enqueue calls to `componentDidMount` and `componentDidUpdate`.
46 - *
47 - * @param {ReactComponent} component Component being rendered.
48 - * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked.
49 - * @internal
50 - */
51 - enqueue: function(component, callback) {
52 - this._queue = this._queue || [];
53 - this._queue.push({component: component, callback: callback});
54 - },
55 -
56 - /**
57 - * Invokes all enqueued callbacks and clears the queue. This is invoked after
58 - * the DOM representation of a component has been created or updated.
59 - *
60 - * @internal
61 - */
62 - notifyAll: function() {
63 - var queue = this._queue;
64 - if (queue) {
65 - this._queue = null;
66 - for (var i = 0, l = queue.length; i < l; i++) {
67 - var component = queue[i].component;
68 - var callback = queue[i].callback;
69 - callback.call(component, component.getDOMNode());
70 - }
71 - queue.length = 0;
72 - }
73 - },
74 -
75 - /**
76 - * Resets the internal queue.
77 - *
78 - * @internal
79 - */
80 - reset: function() {
81 - this._queue = null;
82 - },
83 -
84 - /**
85 - * `PooledClass` looks for this.
86 - */
87 - destructor: function() {
88 - this.reset();
89 - }
90 -
91 -});
92 -
93 -PooledClass.addPoolingTo(ReactOnDOMReady);
94 -
95 -module.exports = ReactOnDOMReady;
React/ReactOwner.js deleted
-146
@@ -1,146 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactOwner
17 - */
18 -
19 -"use strict";
20 -
21 -var invariant = require("./invariant");
22 -
23 -/**
24 - * ReactOwners are capable of storing references to owned components.
25 - *
26 - * All components are capable of //being// referenced by owner components, but
27 - * only ReactOwner components are capable of //referencing// owned components.
28 - * The named reference is known as a "ref".
29 - *
30 - * Refs are available when mounted and updated during reconciliation.
31 - *
32 - * var MyComponent = React.createClass({
33 - * render: function() {
34 - * return (
35 - * <div onClick={this.handleClick}>
36 - * <CustomComponent ref="custom" />
37 - * </div>
38 - * );
39 - * },
40 - * handleClick: React.autoBind(function() {
41 - * this.refs.custom.handleClick();
42 - * }),
43 - * componentDidMount: function() {
44 - * this.refs.custom.initialize();
45 - * }
46 - * });
47 - *
48 - * Refs should rarely be used. When refs are used, they should only be done to
49 - * control data that is not handled by React's data flow.
50 - *
51 - * @class ReactOwner
52 - */
53 -var ReactOwner = {
54 -
55 - /**
56 - * @param {?object} object
57 - * @return {boolean} True if `object` is a valid owner.
58 - * @final
59 - */
60 - isValidOwner: function(object) {
61 - return !!(
62 - object &&
63 - typeof object.attachRef === 'function' &&
64 - typeof object.detachRef === 'function'
65 - );
66 - },
67 -
68 - /**
69 - * Adds a component by ref to an owner component.
70 - *
71 - * @param {ReactComponent} component Component to reference.
72 - * @param {string} ref Name by which to refer to the component.
73 - * @param {ReactOwner} owner Component on which to record the ref.
74 - * @final
75 - * @internal
76 - */
77 - addComponentAsRefTo: function(component, ref, owner) {
78 - invariant(
79 - ReactOwner.isValidOwner(owner),
80 - 'addComponentAsRefTo(...): Only a ReactOwner can have refs.'
81 - );
82 - owner.attachRef(ref, component);
83 - },
84 -
85 - /**
86 - * Removes a component by ref from an owner component.
87 - *
88 - * @param {ReactComponent} component Component to dereference.
89 - * @param {string} ref Name of the ref to remove.
90 - * @param {ReactOwner} owner Component on which the ref is recorded.
91 - * @final
92 - * @internal
93 - */
94 - removeComponentAsRefFrom: function(component, ref, owner) {
95 - invariant(
96 - ReactOwner.isValidOwner(owner),
97 - 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs.'
98 - );
99 - // Check that `component` is still the current ref because we do not want to
100 - // detach the ref if another component stole it.
101 - if (owner.refs[ref] === component) {
102 - owner.detachRef(ref);
103 - }
104 - },
105 -
106 - /**
107 - * A ReactComponent must mix this in to have refs.
108 - *
109 - * @lends {ReactOwner.prototype}
110 - */
111 - Mixin: {
112 -
113 - /**
114 - * Lazily allocates the refs object and stores `component` as `ref`.
115 - *
116 - * @param {string} ref Reference name.
117 - * @param {component} component Component to store as `ref`.
118 - * @final
119 - * @private
120 - */
121 - attachRef: function(ref, component) {
122 - invariant(
123 - component.isOwnedBy(this),
124 - 'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
125 - ref
126 - );
127 - var refs = this.refs || (this.refs = {});
128 - refs[ref] = component;
129 - },
130 -
131 - /**
132 - * Detaches a reference name.
133 - *
134 - * @param {string} ref Name to dereference.
135 - * @final
136 - * @private
137 - */
138 - detachRef: function(ref) {
139 - delete this.refs[ref];
140 - }
141 -
142 - }
143 -
144 -};
145 -
146 -module.exports = ReactOwner;
React/ReactPropTransferer.js deleted
-114
@@ -1,114 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactPropTransferer
17 - */
18 -
19 -"use strict";
20 -
21 -var emptyFunction = require("./emptyFunction");
22 -var joinClasses = require("./joinClasses");
23 -var merge = require("./merge");
24 -
25 -/**
26 - * Creates a transfer strategy that will merge prop values using the supplied
27 - * `mergeStrategy`. If a prop was previously unset, this just sets it.
28 - *
29 - * @param {function} mergeStrategy
30 - * @return {function}
31 - */
32 -function createTransferStrategy(mergeStrategy) {
33 - return function(props, key, value) {
34 - if (!props.hasOwnProperty(key)) {
35 - props[key] = value;
36 - } else {
37 - props[key] = mergeStrategy(props[key], value);
38 - }
39 - };
40 -}
41 -
42 -/**
43 - * Transfer strategies dictate how props are transferred by `transferPropsTo`.
44 - */
45 -var TransferStrategies = {
46 - /**
47 - * Never transfer the `ref` prop.
48 - */
49 - ref: emptyFunction,
50 - /**
51 - * Transfer the `className` prop by merging them.
52 - */
53 - className: createTransferStrategy(joinClasses),
54 - /**
55 - * Transfer the `style` prop (which is an object) by merging them.
56 - */
57 - style: createTransferStrategy(merge)
58 -};
59 -
60 -/**
61 - * ReactPropTransferer are capable of transferring props to another component
62 - * using a `transferPropsTo` method.
63 - *
64 - * @class ReactPropTransferer
65 - */
66 -var ReactPropTransferer = {
67 -
68 - TransferStrategies: TransferStrategies,
69 -
70 - /**
71 - * @lends {ReactPropTransferer.prototype}
72 - */
73 - Mixin: {
74 -
75 - /**
76 - * Transfer props from this component to a target component.
77 - *
78 - * Props that do not have an explicit transfer strategy will be transferred
79 - * only if the target component does not already have the prop set.
80 - *
81 - * This is usually used to pass down props to a returned root component.
82 - *
83 - * @param {ReactComponent} component Component receiving the properties.
84 - * @return {ReactComponent} The supplied `component`.
85 - * @final
86 - * @protected
87 - */
88 - transferPropsTo: function(component) {
89 - var props = {};
90 - for (var thatKey in component.props) {
91 - if (component.props.hasOwnProperty(thatKey)) {
92 - props[thatKey] = component.props[thatKey];
93 - }
94 - }
95 - for (var thisKey in this.props) {
96 - if (!this.props.hasOwnProperty(thisKey)) {
97 - continue;
98 - }
99 - var transferStrategy = TransferStrategies[thisKey];
100 - if (transferStrategy) {
101 - transferStrategy(props, thisKey, this.props[thisKey]);
102 - } else if (!props.hasOwnProperty(thisKey)) {
103 - props[thisKey] = this.props[thisKey];
104 - }
105 - }
106 - component.props = props;
107 - return component;
108 - }
109 -
110 - }
111 -
112 -};
113 -
114 -module.exports = ReactPropTransferer;
React/ReactProps.js deleted
-157
@@ -1,157 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactProps
17 - */
18 -
19 -"use strict";
20 -
21 -var createObjectFrom = require("./createObjectFrom");
22 -var invariant = require("./invariant");
23 -
24 -/**
25 - * Collection of methods that allow declaration and validation of props that are
26 - * supplied to React components. Example usage:
27 - *
28 - * var Props = require('ReactProps');
29 - * var MyArticle = React.createClass({
30 - * props: {
31 - * // An optional string prop named "description".
32 - * description: Props.string,
33 - *
34 - * // A required enum prop named "category".
35 - * category: Props.oneOf(['News','Photos']).isRequired,
36 - *
37 - * // A prop named "dialog" that requires an instance of Dialog.
38 - * dialog: Props.instanceOf(Dialog).isRequired
39 - * },
40 - * render: function() { ... }
41 - * });
42 - *
43 - * A more formal specification of how these methods are used:
44 - *
45 - * type := array|bool|object|number|string|oneOf([...])|instanceOf(...)
46 - * decl := ReactProps.{type}(.isRequired)?
47 - *
48 - * Each and every declaration produces a function with the same signature. This
49 - * allows the creation of custom validation functions. For example:
50 - *
51 - * var Props = require('ReactProps');
52 - * var MyLink = React.createClass({
53 - * props: {
54 - * // An optional string or URI prop named "href".
55 - * href: function(props, propName, componentName) {
56 - * var propValue = props[propName];
57 - * invariant(
58 - * propValue == null ||
59 - * typeof propValue === string ||
60 - * propValue instanceof URI,
61 - * 'Invalid `%s` supplied to `%s`, expected string or URI.',
62 - * propName,
63 - * componentName
64 - * );
65 - * }
66 - * },
67 - * render: function() { ... }
68 - * });
69 - *
70 - * @internal
71 - */
72 -var Props = {
73 -
74 - array: createPrimitiveTypeChecker('array'),
75 - bool: createPrimitiveTypeChecker('boolean'),
76 - number: createPrimitiveTypeChecker('number'),
77 - object: createPrimitiveTypeChecker('object'),
78 - string: createPrimitiveTypeChecker('string'),
79 -
80 - oneOf: createEnumTypeChecker,
81 -
82 - instanceOf: createInstanceTypeChecker
83 -
84 -};
85 -
86 -var ANONYMOUS = '<<anonymous>>';
87 -
88 -function createPrimitiveTypeChecker(expectedType) {
89 - function validatePrimitiveType(propValue, propName, componentName) {
90 - var propType = typeof propValue;
91 - if (propType === 'object' && Array.isArray(propValue)) {
92 - propType = 'array';
93 - }
94 - invariant(
95 - propType === expectedType,
96 - 'Invalid prop `%s` of type `%s` supplied to `%s`, expected `%s`.',
97 - propName,
98 - propType,
99 - componentName,
100 - expectedType
101 - );
102 - }
103 - return createChainableTypeChecker(validatePrimitiveType);
104 -}
105 -
106 -function createEnumTypeChecker(expectedValues) {
107 - var expectedEnum = createObjectFrom(expectedValues);
108 - function validateEnumType(propValue, propName, componentName) {
109 - invariant(
110 - expectedEnum[propValue],
111 - 'Invalid prop `%s` supplied to `%s`, expected one of %s.',
112 - propName,
113 - componentName,
114 - JSON.stringify(Object.keys(expectedEnum))
115 - );
116 - }
117 - return createChainableTypeChecker(validateEnumType);
118 -}
119 -
120 -function createInstanceTypeChecker(expectedClass) {
121 - function validateInstanceType(propValue, propName, componentName) {
122 - invariant(
123 - propValue instanceof expectedClass,
124 - 'Invalid prop `%s` supplied to `%s`, expected instance of `%s`.',
125 - propName,
126 - componentName,
127 - expectedClass.name || ANONYMOUS
128 - );
129 - }
130 - return createChainableTypeChecker(validateInstanceType);
131 -}
132 -
133 -function createChainableTypeChecker(validate) {
134 - function createTypeChecker(isRequired) {
135 - function checkType(props, propName, componentName) {
136 - var propValue = props[propName];
137 - if (propValue != null) {
138 - // Only validate if there is a value to check.
139 - validate(propValue, propName, componentName || ANONYMOUS);
140 - } else {
141 - invariant(
142 - !isRequired,
143 - 'Required prop `%s` was not specified in `%s`.',
144 - propName,
145 - componentName || ANONYMOUS
146 - );
147 - }
148 - }
149 - if (!isRequired) {
150 - checkType.isRequired = createTypeChecker(true);
151 - }
152 - return checkType;
153 - }
154 - return createTypeChecker(false);
155 -}
156 -
157 -module.exports = Props;
React/ReactReconcileTransaction.js deleted
-161
@@ -1,161 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactReconcileTransaction
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var ExecutionEnvironment = require("./ExecutionEnvironment");
23 -var PooledClass = require("./PooledClass");
24 -var ReactEvent = require("./ReactEvent");
25 -var ReactInputSelection = require("./ReactInputSelection");
26 -var ReactOnDOMReady = require("./ReactOnDOMReady");
27 -var Transaction = require("./Transaction");
28 -
29 -var mixInto = require("./mixInto");
30 -
31 -/**
32 - * Ensures that, when possible, the selection range (currently selected text
33 - * input) is not disturbed by performing the transaction.
34 - */
35 -var SELECTION_RESTORATION = {
36 - /**
37 - * @return {Selection} Selection information.
38 - */
39 - initialize: ReactInputSelection.getSelectionInformation,
40 - /**
41 - * @param {Selection} sel Selection information returned from `initialize`.
42 - */
43 - close: ReactInputSelection.restoreSelection
44 -};
45 -
46 -/**
47 - * Suppresses events (blur/focus) that could be inadvertently dispatched due to
48 - * high level DOM manipulations (like temporarily removing a text input from the
49 - * DOM).
50 - */
51 -var EVENT_SUPPRESSION = {
52 - /**
53 - * @return {boolean} The enabled status of `ReactEvent` before the
54 - * reconciliation.
55 - */
56 - initialize: function() {
57 - var currentlyEnabled = ReactEvent.isEnabled();
58 - ReactEvent.setEnabled(false);
59 - return currentlyEnabled;
60 - },
61 -
62 - /**
63 - * @param {boolean} previouslyEnabled The enabled status of `ReactEvent`
64 - * before the reconciliation occured. `close` restores the previous value.
65 - */
66 - close: function(previouslyEnabled) {
67 - ReactEvent.setEnabled(previouslyEnabled);
68 - }
69 -};
70 -
71 -/**
72 - * Provides a `ReactOnDOMReady` queue for collecting `onDOMReady` callbacks
73 - * during the performing of the transaction.
74 - */
75 -var ON_DOM_READY_QUEUEING = {
76 - /**
77 - * Initializes the internal `onDOMReady` queue.
78 - */
79 - initialize: function() {
80 - this.reactOnDOMReady.reset();
81 - },
82 -
83 - /**
84 - * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
85 - */
86 - close: function() {
87 - this.reactOnDOMReady.notifyAll();
88 - }
89 -};
90 -
91 -/**
92 - * Executed within the scope of the `Transaction` instance. Consider these as
93 - * being member methods, but with an implied ordering while being isolated from
94 - * each other.
95 - */
96 -var TRANSACTION_WRAPPERS = [
97 - SELECTION_RESTORATION,
98 - EVENT_SUPPRESSION,
99 - ON_DOM_READY_QUEUEING
100 -];
101 -
102 -/**
103 - * Currently:
104 - * - The order that these are listed in the transaction is critical:
105 - * - Suppresses events.
106 - * - Restores selection range.
107 - *
108 - * Future:
109 - * - Restore document/overflow scroll positions that were unintentionally
110 - * modified via DOM insertions above the top viewport boundary.
111 - * - Implement/integrate with customized constraint based layout system and keep
112 - * track of which dimensions must be remeasured.
113 - *
114 - * @class ReactReconcileTransaction
115 - */
116 -function ReactReconcileTransaction() {
117 - this.reinitializeTransaction();
118 - this.reactOnDOMReady = ReactOnDOMReady.getPooled(null);
119 -}
120 -
121 -var Mixin = {
122 - /**
123 - * @see Transaction
124 - * @abstract
125 - * @final
126 - * @return {array<object>} List of operation wrap proceedures.
127 - * TODO: convert to array<TransactionWrapper>
128 - */
129 - getTransactionWrappers: function() {
130 - if (ExecutionEnvironment.canUseDOM) {
131 - return TRANSACTION_WRAPPERS;
132 - } else {
133 - return [];
134 - }
135 - },
136 -
137 - /**
138 - * @return {object} The queue to collect `onDOMReady` callbacks with.
139 - * TODO: convert to ReactOnDOMReady
140 - */
141 - getReactOnDOMReady: function() {
142 - return this.reactOnDOMReady;
143 - },
144 -
145 - /**
146 - * `PooledClass` looks for this, and will invoke this before allowing this
147 - * instance to be resused.
148 - */
149 - destructor: function() {
150 - ReactOnDOMReady.release(this.reactOnDOMReady);
151 - this.reactOnDOMReady = null;
152 - }
153 -};
154 -
155 -
156 -mixInto(ReactReconcileTransaction, Transaction.Mixin);
157 -mixInto(ReactReconcileTransaction, Mixin);
158 -
159 -PooledClass.addPoolingTo(ReactReconcileTransaction);
160 -
161 -module.exports = ReactReconcileTransaction;
React/ReactStateSetters.js deleted
-111
@@ -1,111 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactStateSetters
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactStateSetters = {
22 - /**
23 - * Returns a function that calls the provided function, and uses the result
24 - * of that to set the component's state.
25 - *
26 - * @param {ReactCompositeComponent} component
27 - * @param {function} funcReturningState Returned callback uses this to
28 - * determine how to update state.
29 - * @return {function} callback that when invoked uses funcReturningState to
30 - * determined the object literal to setState.
31 - */
32 - createStateSetter: function(component, funcReturningState) {
33 - return function(a, b, c, d, e, f) {
34 - var partialState = funcReturningState.call(component, a, b, c, d, e, f);
35 - if (partialState) {
36 - component.setState(partialState);
37 - }
38 - };
39 - },
40 -
41 - /**
42 - * Returns a single-argument callback that can be used to update a single
43 - * key in the component's state.
44 - *
45 - * Note: this is memoized function, which makes it inexpensive to call.
46 - *
47 - * @param {ReactCompositeComponent} component
48 - * @param {string} key The key in the state that you should update.
49 - * @return {function} callback of 1 argument which calls setState() with
50 - * the provided keyName and callback argument.
51 - */
52 - createStateKeySetter: function(component, key) {
53 - // Memoize the setters.
54 - var cache = component.__keySetters || (component.__keySetters = {});
55 - return cache[key] || (cache[key] = createStateKeySetter(component, key));
56 - }
57 -};
58 -
59 -function createStateKeySetter(component, key) {
60 - // Partial state is allocated outside of the function closure so it can be
61 - // reused with every call, avoiding memory allocation when this function
62 - // is called.
63 - var partialState = {};
64 - return function stateKeySetter(value) {
65 - partialState[key] = value;
66 - component.setState(partialState);
67 - };
68 -}
69 -
70 -ReactStateSetters.Mixin = {
71 - /**
72 - * Returns a function that calls the provided function, and uses the result
73 - * of that to set the component's state.
74 - *
75 - * For example, these statements are equivalent:
76 - *
77 - * this.setState({x: 1});
78 - * this.createStateSetter(function(xValue) {
79 - * return {x: xValue};
80 - * })(1);
81 - *
82 - * @param {function} funcReturningState Returned callback uses this to
83 - * determine how to update state.
84 - * @return {function} callback that when invoked uses funcReturningState to
85 - * determined the object literal to setState.
86 - */
87 - createStateSetter: function(funcReturningState) {
88 - return ReactStateSetters.createStateSetter(this, funcReturningState);
89 - },
90 -
91 - /**
92 - * Returns a single-argument callback that can be used to update a single
93 - * key in the component's state.
94 - *
95 - * For example, these statements are equivalent:
96 - *
97 - * this.setState({x: 1});
98 - * this.createStateKeySetter('x')(1);
99 - *
100 - * Note: this is memoized function, which makes it inexpensive to call.
101 - *
102 - * @param {string} key The key in the state that you should update.
103 - * @return {function} callback of 1 argument which calls setState() with
104 - * the provided keyName and callback argument.
105 - */
106 - createStateKeySetter: function(key) {
107 - return ReactStateSetters.createStateKeySetter(this, key);
108 - }
109 -};
110 -
111 -module.exports = ReactStateSetters;
React/ReactTestUtils.js deleted
-284
@@ -1,284 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactTestUtils
17 - */
18 -
19 -var EventConstants = require("./EventConstants");
20 -var React = require("./React");
21 -var ReactComponent = require("./ReactComponent");
22 -var ReactEvent = require("./ReactEvent");
23 -var ReactTextComponent = require("./ReactTextComponent");
24 -
25 -var ge = require("./ge");
26 -var mergeInto = require("./mergeInto");
27 -
28 -var topLevelTypes = EventConstants.topLevelTypes;
29 -
30 -function Event(suffix) {}
31 -
32 -/**
33 - * @class ReactTestUtils
34 - */
35 -
36 -/**
37 - * Todo: Support the entire DOM.scry query syntax. For now, these simple
38 - * utilities will suffice for testing purposes.
39 - * @lends ReactTestUtils
40 - */
41 -var ReactTestUtils = {
42 - renderIntoDocument: function(instance) {
43 - var div = document.createElement('div');
44 - document.documentElement.appendChild(div);
45 - return React.renderComponent(instance, div);
46 - },
47 -
48 - isDOMComponent: function(inst) {
49 - return !!(inst &&
50 - ReactComponent.isValidComponent(inst) &&
51 - !!inst.tagName);
52 - },
53 -
54 - isCompositeComponent: function(inst) {
55 - return !!(
56 - inst &&
57 - ReactComponent.isValidComponent(inst) &&
58 - typeof inst.render === 'function' &&
59 - typeof inst.setState === 'function' &&
60 - typeof inst.updateComponent === 'function'
61 - );
62 - },
63 -
64 - isCompositeComponentWithType: function(inst, type) {
65 - return !!(ReactTestUtils.isCompositeComponent(inst) &&
66 - (inst.constructor === type.componentConstructor ||
67 - inst.constructor === type));
68 - },
69 -
70 - isTextComponent: function(inst) {
71 - return inst instanceof ReactTextComponent;
72 - },
73 -
74 - findAllInRenderedTree: function(inst, test) {
75 - if (!inst) {
76 - return [];
77 - }
78 - var ret = test(inst) ? [inst] : [];
79 - if (ReactTestUtils.isDOMComponent(inst)) {
80 - var renderedChildren = inst._renderedChildren;
81 - var key;
82 - for (key in renderedChildren) {
83 - if (!renderedChildren.hasOwnProperty(key)) {
84 - continue;
85 - }
86 - ret = ret.concat(
87 - ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test)
88 - );
89 - }
90 - } else if (ReactTestUtils.isCompositeComponent(inst)) {
91 - ret = ret.concat(
92 - ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test)
93 - );
94 - }
95 - return ret;
96 - },
97 -
98 - /**
99 - * Finds all instance of components in the rendered tree that are DOM
100 - * components with the class name matching `className`.
101 - * @return an array of all the matches.
102 - */
103 - scryRenderedDOMComponentsWithClass: function(root, className) {
104 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
105 - var instClassName = inst.props.className;
106 - return ReactTestUtils.isDOMComponent(inst) && (
107 - instClassName &&
108 - (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1
109 - );
110 - });
111 - },
112 -
113 - /**
114 - * Like scryRenderedDOMComponentsWithClass but expects there to be one result,
115 - * and returns that one result, or throws exception if there is any other
116 - * number of matches besides one.
117 - * @return {!ReactNativeComponent} The one match.
118 - */
119 - findRenderedDOMComponentWithClass: function(root, className) {
120 - var all =
121 - ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className);
122 - if (all.length !== 1) {
123 - throw new Error('Did not find exactly one match for class:' + className);
124 - }
125 - return all[0];
126 - },
127 -
128 -
129 - /**
130 - * Finds all instance of components in the rendered tree that are DOM
131 - * components with the tag name matching `tagName`.
132 - * @return an array of all the matches.
133 - */
134 - scryRenderedDOMComponentsWithTag: function(root, tagName) {
135 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
136 - return ReactTestUtils.isDOMComponent(inst) &&
137 - inst.tagName === tagName.toUpperCase();
138 - });
139 - },
140 -
141 - /**
142 - * Like scryRenderedDOMComponentsWithTag but expects there to be one result,
143 - * and returns that one result, or throws exception if there is any other
144 - * number of matches besides one.
145 - * @return {!ReactNativeComponent} The one match.
146 - */
147 - findRenderedDOMComponentWithTag: function(root, tagName) {
148 - var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName);
149 - if (all.length !== 1) {
150 - throw new Error('Did not find exactly one match for tag:' + tagName);
151 - }
152 - return all[0];
153 - },
154 -
155 -
156 - /**
157 - * Finds all instances of components with type equal to `componentType`.
158 - * @return an array of all the matches.
159 - */
160 - scryRenderedComponentsWithType: function(root, componentType) {
161 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
162 - return ReactTestUtils.isCompositeComponentWithType(inst, componentType);
163 - });
164 - },
165 -
166 - /**
167 - * Same as `scryRenderedComponentsWithType` but expects there to be one result
168 - * and returns that one result, or throws exception if there is any other
169 - * number of matches besides one.
170 - * @return {!ReactComponent} The one match.
171 - */
172 - findRenderedComponentWithType: function(root, componentType) {
173 - var all = ReactTestUtils.scryRenderedComponentsWithType(
174 - root,
175 - componentType
176 - );
177 - if (all.length !== 1) {
178 - throw new Error(
179 - 'Did not find exactly one match for componentType:' + componentType
180 - );
181 - }
182 - return all[0];
183 - },
184 -
185 - /**
186 - * Simulates a top level event being dispatched from a raw event that occured
187 - * on and `Element` node.
188 - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`
189 - * @param {!Element} node The dom to simulate an event occurring on.
190 - * @param {?Event} fakeNativeEvent Fake native event to pass to ReactEvent.
191 - */
192 - simulateEventOnNode: function(topLevelType, node, fakeNativeEvent) {
193 - var virtualHandler =
194 - ReactEvent.TopLevelCallbackCreator.createTopLevelCallback(topLevelType);
195 - fakeNativeEvent.target = node;
196 - virtualHandler(fakeNativeEvent);
197 - },
198 -
199 - /**
200 - * Simulates a top level event being dispatched from a raw event that occured
201 - * on the `ReactNativeComponent` `comp`.
202 - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`.
203 - * @param comp {!ReactNativeComponent}
204 - * @param {?Event} fakeNativeEvent Fake native event to pass to ReactEvent.
205 - */
206 - simulateEventOnDOMComponent: function(topLevelType, comp, fakeNativeEvent) {
207 - var reactRootID = comp._rootNodeID || comp._rootDomId;
208 - if (!reactRootID) {
209 - throw new Error('Simulating event on non-rendered component');
210 - }
211 - var virtualHandler =
212 - ReactEvent.TopLevelCallbackCreator.createTopLevelCallback(topLevelType);
213 - var node = ge(reactRootID);
214 - fakeNativeEvent.target = node;
215 - /* jsdom is returning nodes without id's - fixing that issue here. */
216 - node.id = reactRootID;
217 - virtualHandler(fakeNativeEvent);
218 - },
219 -
220 - nativeTouchData: function(x, y) {
221 - return {
222 - touches: [
223 - {pageX: x, pageY: y}
224 - ]
225 - };
226 - },
227 -
228 - Simulate: null // Will populate
229 -};
230 -
231 -/**
232 - * Exports:
233 - *
234 - * - `ReactTestUtils.Simulate.click(Element/ReactNativeComponent)`
235 - * - `ReactTestUtils.Simulate.mouseMove(Element/ReactNativeComponent)`
236 - * - `ReactTestUtils.Simulate.mouseIn/ReactNativeComponent)`
237 - * - `ReactTestUtils.Simulate.mouseOut(Element/ReactNativeComponent)`
238 - * - ... (All keys from `EventConstants.topLevelTypes`)
239 - *
240 - * Note: Top level event types are a subset of the entire set of handler types
241 - * (which include a broader set of "synthetic" events). For example, onDragDone
242 - * is a synthetic event. You certainly may write test cases for these event
243 - * types, but it doesn't make sense to simulate them at this low of a level. In
244 - * this case, the way you test an `onDragDone` event is by simulating a series
245 - * of `mouseMove`/ `mouseDown`/`mouseUp` events - Then, a synthetic event of
246 - * type `onDragDone` will be constructed and dispached through your system
247 - * automatically.
248 - */
249 -
250 -function makeSimulator(eventType) {
251 - return function(domComponentOrNode, nativeEventData) {
252 - var fakeNativeEvent = new Event(eventType);
253 - mergeInto(fakeNativeEvent, nativeEventData);
254 - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
255 - ReactTestUtils.simulateEventOnDOMComponent(
256 - eventType,
257 - domComponentOrNode,
258 - fakeNativeEvent
259 - );
260 - } else if (!!domComponentOrNode.tagName) {
261 - // Will allow on actual dom nodes.
262 - ReactTestUtils.simulateEventOnNode(
263 - eventType,
264 - domComponentOrNode,
265 - fakeNativeEvent
266 - );
267 - }
268 - };
269 -}
270 -
271 -ReactTestUtils.Simulate = {};
272 -var eventType;
273 -for (eventType in topLevelTypes) {
274 - // Event type is stored as 'topClick' - we transform that to 'click'
275 - var convenienceName = eventType.indexOf('top') === 0 ?
276 - eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType;
277 - /**
278 - * @param {!Element || ReactNativeComponent} domComponentOrNode
279 - * @param {?Event} nativeEventData Fake native event to pass to ReactEvent.
280 - */
281 - ReactTestUtils.Simulate[convenienceName] = makeSimulator(eventType);
282 -}
283 -
284 -module.exports = ReactTestUtils;
React/ReactTextComponent.js deleted
-85
@@ -1,85 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ReactTextComponent
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var ReactComponent = require("./ReactComponent");
23 -
24 -var escapeTextForBrowser = require("./escapeTextForBrowser");
25 -var mixInto = require("./mixInto");
26 -
27 -/**
28 - * Text nodes violate a couple assumptions that React makes about components:
29 - *
30 - * - When mounting text into the DOM, adjacent text nodes are merged.
31 - * - Text nodes cannot be assigned a React root ID.
32 - *
33 - * This component is used to wrap strings in elements so that they can undergo
34 - * the same reconciliation that is applied to elements.
35 - *
36 - * TODO: Investigate representing React components in the DOM with text nodes.
37 - *
38 - * @class ReactTextComponent
39 - * @extends ReactComponent
40 - * @internal
41 - */
42 -var ReactTextComponent = function(initialText) {
43 - this.construct({text: initialText});
44 -};
45 -
46 -mixInto(ReactTextComponent, ReactComponent.Mixin);
47 -mixInto(ReactTextComponent, {
48 -
49 - /**
50 - * Creates the markup for this text node. This node is not intended to have
51 - * any features besides containing text content.
52 - *
53 - * @param {string} rootID DOM ID of the root node.
54 - * @return {string} Markup for this text node.
55 - * @internal
56 - */
57 - mountComponent: function(rootID) {
58 - ReactComponent.Mixin.mountComponent.call(this, rootID);
59 - return (
60 - '<span id="' + rootID + '">' +
61 - escapeTextForBrowser(this.props.text) +
62 - '</span>'
63 - );
64 - },
65 -
66 - /**
67 - * Updates this component by updating the text content.
68 - *
69 - * @param {object} nextProps Contains the next text content.
70 - * @param {ReactReconcileTransaction} transaction
71 - * @internal
72 - */
73 - receiveProps: function(nextProps, transaction) {
74 - if (nextProps.text !== this.props.text) {
75 - this.props.text = nextProps.text;
76 - ReactComponent.DOMIDOperations.updateTextContentByID(
77 - this._rootNodeID,
78 - nextProps.text
79 - );
80 - }
81 - }
82 -
83 -});
84 -
85 -module.exports = ReactTextComponent;
React/ResponderEventPlugin.js deleted
-312
@@ -1,312 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ResponderEventPlugin
17 - */
18 -
19 -"use strict";
20 -
21 -var AbstractEvent = require("./AbstractEvent");
22 -var EventConstants = require("./EventConstants");
23 -var EventPluginUtils = require("./EventPluginUtils");
24 -var EventPropagators = require("./EventPropagators");
25 -
26 -var accumulate = require("./accumulate");
27 -var keyOf = require("./keyOf");
28 -
29 -var isStartish = EventPluginUtils.isStartish;
30 -var isMoveish = EventPluginUtils.isMoveish;
31 -var isEndish = EventPluginUtils.isEndish;
32 -var executeDirectDispatch = EventPluginUtils.executeDirectDispatch;
33 -var hasDispatches = EventPluginUtils.hasDispatches;
34 -var executeDispatchesInOrderStopAtTrue =
35 - EventPluginUtils.executeDispatchesInOrderStopAtTrue;
36 -
37 -/**
38 - * ID of element that should respond to touch/move types of interactions, as
39 - * indicated explicitly by relevant callbacks.
40 - */
41 -var responderID = null;
42 -var isPressing = false;
43 -
44 -var getResponderID = function() {
45 - return responderID;
46 -};
47 -
48 -var abstractEventTypes = {
49 - /**
50 - * On a `touchStart`/`mouseDown`, is it desired that this element become the
51 - * responder?
52 - */
53 - startShouldSetResponder: {
54 - phasedRegistrationNames: {
55 - bubbled: keyOf({onStartShouldSetResponder: null}),
56 - captured: keyOf({onStartShouldSetResponderCapture: null})
57 - }
58 - },
59 -
60 - /**
61 - * On a `scroll`, is it desired that this element become the responder? This
62 - * is usually not needed, but should be used to retroactively infer that a
63 - * `touchStart` had occured during momentum scroll. During a momentum scroll,
64 - * a touch start will be immediately followed by a scroll event if the view is
65 - * currently scrolling.
66 - */
67 - scrollShouldSetResponder: {
68 - phasedRegistrationNames: {
69 - bubbled: keyOf({onScrollShouldSetResponder: null}),
70 - captured: keyOf({onScrollShouldSetResponderCapture: null})
71 - }
72 - },
73 -
74 - /**
75 - * On a `touchMove`/`mouseMove`, is it desired that this element become the
76 - * responder?
77 - */
78 - moveShouldSetResponder: {
79 - phasedRegistrationNames: {
80 - bubbled: keyOf({onMoveShouldSetResponder: null}),
81 - captured: keyOf({onMoveShouldSetResponderCapture: null})
82 - }
83 - },
84 -
85 - /**
86 - * Direct responder events dispatched directly to responder. Do not bubble.
87 - */
88 - responderMove: {registrationName: keyOf({onResponderMove: null})},
89 - responderRelease: {registrationName: keyOf({onResponderRelease: null})},
90 - responderTerminationRequest: {
91 - registrationName: keyOf({onResponderTerminationRequest: null})
92 - },
93 - responderGrant: {registrationName: keyOf({onResponderGrant: null})},
94 - responderReject: {registrationName: keyOf({onResponderReject: null})},
95 - responderTerminate: {registrationName: keyOf({onResponderTerminate: null})}
96 -};
97 -
98 -/**
99 - * Performs negotiation between any existing/current responder, checks to see if
100 - * any new entity is interested in becoming responder, performs that handshake
101 - * and returns any events that must be emitted to notify the relevant parties.
102 - *
103 - * A note about event ordering in the `EventPluginHub`.
104 - *
105 - * Suppose plugins are injected in the following order:
106 - *
107 - * `[R, S, C]`
108 - *
109 - * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
110 - * `onClick` etc) and `R` is `ResponderEventPlugin`.
111 - *
112 - * "Deferred-Dispatched Events":
113 - *
114 - * - The current event plugin system will traverse the list of injected plugins,
115 - * in order, and extract events by collecting the plugin's return value of
116 - * `extractAbstractEvents()`.
117 - * - These events that are returned from `extractAbstractEvents` are "deferred
118 - * dispatched events".
119 - * - When returned from `extractAbstractEvents`, deferred dispatched events
120 - * contain an "accumulation" of deferred dispatches.
121 - * -- These deferred dispatches are accumulated/collected before they are
122 - * returned, but processed at a later time by the `EventPluginHub` (hence the
123 - * name deferred).
124 - *
125 - * In the process of returning their deferred dispatched events, event plugins
126 - * themselves can dispatch events on-demand without returning them from
127 - * `extractAbstractEvents`. Plugins might want to do this, so that they can use
128 - * event dispatching as a tool that helps them decide which events should be
129 - * extracted in the first place.
130 - *
131 - * "On-Demand-Dispatched Events":
132 - *
133 - * - On-demand dispatched are not returned from `extractAbstractEvents`.
134 - * - On-demand dispatched events are dispatched during the process of returning
135 - * the deferred-dispatched events.
136 - * - They should not have side effects.
137 - * - They should be avoided, and/or eventually be replaced with another
138 - * abstraction that allows event plugins to perform multiple "rounds" of event
139 - * extraction.
140 - *
141 - * Therefore, the sequence of event dispatches becomes:
142 - *
143 - * - `R`s on-demand events (if any) (dispatched by `R` on-demand)
144 - * - `S`s on-demand events (if any) (dispatched by `S` on-demand)
145 - * - `C`s on-demand events (if any) (dispatched by `C` on-demand)
146 - * - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
147 - * - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
148 - * - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
149 - *
150 - * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
151 - * on-demand dispatch returns `true` (and some other details are satisfied) the
152 - * `onResponderGrant` deferred dispatched event is returned from
153 - * `extractAbstractEvents`. The sequence of dispatch executions in this case
154 - * will appear as follows:
155 - *
156 - * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
157 - * - `touchStartCapture` (`EventPluginHub` dispatches as usual)
158 - * - `touchStart` (`EventPluginHub` dispatches as usual)
159 - * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
160 - *
161 - * @returns {Accumulation<AbstractEvent>}
162 - */
163 -
164 -/**
165 - * @param {TopLevelTypes} topLevelType Top level event type being examined.
166 - * @param {DOMEvent} nativeEvent Native DOM event.
167 - * @param {string} renderedTargetID ID of deepest React rendered element.
168 - *
169 - * @return {Accumulation<AbstractEvent>} Extracted events.
170 - */
171 -var setResponderAndExtractTransfer =
172 - function(topLevelType, nativeEvent, renderedTargetID) {
173 - var type;
174 - var shouldSetEventType =
175 - isStartish(topLevelType) ? abstractEventTypes.startShouldSetResponder :
176 - isMoveish(topLevelType) ? abstractEventTypes.moveShouldSetResponder :
177 - abstractEventTypes.scrollShouldSetResponder;
178 -
179 - var bubbleShouldSetFrom = responderID || renderedTargetID;
180 - var shouldSetEvent = AbstractEvent.getPooled(
181 - shouldSetEventType,
182 - bubbleShouldSetFrom,
183 - topLevelType,
184 - nativeEvent,
185 - AbstractEvent.normalizePointerData(nativeEvent)
186 - );
187 - EventPropagators.accumulateTwoPhaseDispatches(shouldSetEvent);
188 - var wantsResponderID = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
189 - AbstractEvent.release(shouldSetEvent);
190 -
191 - if (!wantsResponderID || wantsResponderID === responderID) {
192 - return null;
193 - }
194 - var extracted;
195 - var grantEvent = AbstractEvent.getPooled(
196 - abstractEventTypes.responderGrant,
197 - wantsResponderID,
198 - topLevelType,
199 - nativeEvent
200 - );
201 -
202 - EventPropagators.accumulateDirectDispatches(grantEvent);
203 - if (responderID) {
204 - type = abstractEventTypes.responderTerminationRequest;
205 - var terminationRequestEvent = AbstractEvent.getPooled(type, responderID);
206 - EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
207 - var shouldSwitch = !hasDispatches(terminationRequestEvent) ||
208 - executeDirectDispatch(terminationRequestEvent);
209 - AbstractEvent.release(terminationRequestEvent);
210 - if (shouldSwitch) {
211 - var terminateType = abstractEventTypes.responderTerminate;
212 - var terminateEvent = AbstractEvent.getPooled(
213 - terminateType,
214 - responderID,
215 - topLevelType,
216 - nativeEvent
217 - );
218 - EventPropagators.accumulateDirectDispatches(terminateEvent);
219 - extracted = accumulate(extracted, [grantEvent, terminateEvent]);
220 - responderID = wantsResponderID;
221 - } else {
222 - var rejectEvent = AbstractEvent.getPooled(
223 - abstractEventTypes.responderReject,
224 - wantsResponderID,
225 - topLevelType,
226 - nativeEvent
227 - );
228 - EventPropagators.accumulateDirectDispatches(rejectEvent);
229 - extracted = accumulate(extracted, rejectEvent);
230 - }
231 - } else {
232 - extracted = accumulate(extracted, grantEvent);
233 - responderID = wantsResponderID;
234 - }
235 - return extracted;
236 - };
237 -
238 -
239 -/**
240 - * A transfer is a negotiation between a currently set responder and the next
241 - * element to claim responder status. Any start event could trigger a transfer
242 - * of responderID. Any move event could trigger a transfer, so long as there is
243 - * currently a responder set (in other words as long as the user is pressing
244 - * down).
245 - *
246 - * @param {EventConstants.topLevelTypes} topLevelType
247 - * @return {boolean} Whether or not a transfer of responder could possibly
248 - * occur.
249 - */
250 -function canTriggerTransfer(topLevelType) {
251 - return topLevelType === EventConstants.topLevelTypes.topScroll ||
252 - isStartish(topLevelType) ||
253 - (isPressing && isMoveish(topLevelType));
254 -}
255 -
256 -var extractAbstractEvents =
257 - function(topLevelType, nativeEvent, renderedTargetID, renderedTarget) {
258 - var extracted;
259 - // Must have missed an end event - reset the state here.
260 - if (responderID && isStartish(topLevelType)) {
261 - responderID = null;
262 - }
263 - if (isStartish(topLevelType)) {
264 - isPressing = true;
265 - } else if (isEndish(topLevelType)) {
266 - isPressing = false;
267 - }
268 - if (canTriggerTransfer(topLevelType)) {
269 - var transfer = setResponderAndExtractTransfer(
270 - topLevelType,
271 - nativeEvent,
272 - renderedTargetID,
273 - renderedTarget
274 - );
275 - if (transfer) {
276 - extracted = accumulate(extracted, transfer);
277 - }
278 - }
279 - // Now that we know the responder is set correctly, we can dispatch
280 - // responder type events (directly to the responder).
281 - var type = isMoveish(topLevelType) ? abstractEventTypes.responderMove :
282 - isEndish(topLevelType) ? abstractEventTypes.responderRelease :
283 - isStartish(topLevelType) ? abstractEventTypes.responderStart : null;
284 - if (type) {
285 - var data = AbstractEvent.normalizePointerData(nativeEvent);
286 - var gesture = AbstractEvent.getPooled(
287 - type,
288 - responderID,
289 - topLevelType,
290 - nativeEvent,
291 - data
292 - );
293 - EventPropagators.accumulateDirectDispatches(gesture);
294 - extracted = accumulate(extracted, gesture);
295 - }
296 - if (type === abstractEventTypes.responderRelease) {
297 - responderID = null;
298 - }
299 - return extracted;
300 - };
301 -
302 -/**
303 - * Event plugin for formalizing the negotiation between claiming locks on
304 - * receiving touches.
305 - */
306 -var ResponderEventPlugin = {
307 - abstractEventTypes: abstractEventTypes,
308 - extractAbstractEvents: extractAbstractEvents,
309 - getResponderID: getResponderID
310 -};
311 -
312 -module.exports = ResponderEventPlugin;
React/SimpleEventPlugin.js deleted
-232
@@ -1,232 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule SimpleEventPlugin
17 - */
18 -
19 -"use strict";
20 -
21 -var AbstractEvent = require("./AbstractEvent");
22 -var EventConstants = require("./EventConstants");
23 -var EventPropagators = require("./EventPropagators");
24 -
25 -var keyOf = require("./keyOf");
26 -
27 -var topLevelTypes = EventConstants.topLevelTypes;
28 -
29 -var SimpleEventPlugin = {
30 - abstractEventTypes: {
31 - // Note: We do not allow listening to mouseOver events. Instead, use the
32 - // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
33 - mouseDown: {
34 - phasedRegistrationNames: {
35 - bubbled: keyOf({onMouseDown: true}),
36 - captured: keyOf({onMouseDownCapture: true})
37 - }
38 - },
39 - mouseUp: {
40 - phasedRegistrationNames: {
41 - bubbled: keyOf({onMouseUp: true}),
42 - captured: keyOf({onMouseUpCapture: true})
43 - }
44 - },
45 - mouseMove: {
46 - phasedRegistrationNames: {
47 - bubbled: keyOf({onMouseMove: true}),
48 - captured: keyOf({onMouseMoveCapture: true})
49 - }
50 - },
51 - doubleClick: {
52 - phasedRegistrationNames: {
53 - bubbled: keyOf({onDoubleClick: true}),
54 - captured: keyOf({onDoubleClickCapture: true})
55 - }
56 - },
57 - click: {
58 - phasedRegistrationNames: {
59 - bubbled: keyOf({onClick: true}),
60 - captured: keyOf({onClickCapture: true})
61 - }
62 - },
63 - mouseWheel: {
64 - phasedRegistrationNames: {
65 - bubbled: keyOf({onMouseWheel: true}),
66 - captured: keyOf({onMouseWheelCapture: true})
67 - }
68 - },
69 - touchStart: {
70 - phasedRegistrationNames: {
71 - bubbled: keyOf({onTouchStart: true}),
72 - captured: keyOf({onTouchStartCapture: true})
73 - }
74 - },
75 - touchEnd: {
76 - phasedRegistrationNames: {
77 - bubbled: keyOf({onTouchEnd: true}),
78 - captured: keyOf({onTouchEndCapture: true})
79 - }
80 - },
81 - touchCancel: {
82 - phasedRegistrationNames: {
83 - bubbled: keyOf({onTouchCancel: true}),
84 - captured: keyOf({onTouchCancelCapture: true})
85 - }
86 - },
87 - touchMove: {
88 - phasedRegistrationNames: {
89 - bubbled: keyOf({onTouchMove: true}),
90 - captured: keyOf({onTouchMoveCapture: true})
91 - }
92 - },
93 - keyUp: {
94 - phasedRegistrationNames: {
95 - bubbled: keyOf({onKeyUp: true}),
96 - captured: keyOf({onKeyUpCapture: true})
97 - }
98 - },
99 - keyPress: {
100 - phasedRegistrationNames: {
101 - bubbled: keyOf({onKeyPress: true}),
102 - captured: keyOf({onKeyPressCapture: true})
103 - }
104 - },
105 - keyDown: {
106 - phasedRegistrationNames: {
107 - bubbled: keyOf({onKeyDown: true}),
108 - captured: keyOf({onKeyDownCapture: true})
109 - }
110 - },
111 - focus: {
112 - phasedRegistrationNames: {
113 - bubbled: keyOf({onFocus: true}),
114 - captured: keyOf({onFocusCapture: true})
115 - }
116 - },
117 - blur: {
118 - phasedRegistrationNames: {
119 - bubbled: keyOf({onBlur: true}),
120 - captured: keyOf({onBlurCapture: true})
121 - }
122 - },
123 - scroll: {
124 - phasedRegistrationNames: {
125 - bubbled: keyOf({onScroll: true}),
126 - captured: keyOf({onScrollCapture: true})
127 - }
128 - },
129 - change: {
130 - phasedRegistrationNames: {
131 - bubbled: keyOf({onChange: true}),
132 - captured: keyOf({onChangeCapture: true})
133 - }
134 - },
135 - submit: {
136 - phasedRegistrationNames: {
137 - bubbled: keyOf({onSubmit: true}),
138 - captured: keyOf({onSubmitCapture: true})
139 - }
140 - },
141 - DOMCharacterDataModified: {
142 - phasedRegistrationNames: {
143 - bubbled: keyOf({onDOMCharacterDataModified: true}),
144 - captured: keyOf({onDOMCharacterDataModifiedCapture: true})
145 - }
146 - }
147 - },
148 -
149 - /**
150 - * Same as the default implementation, except cancels the event when return
151 - * value is false.
152 - * @param {AbstractEvent} AbstractEvent to handle
153 - * @param {function} Application-level callback
154 - * @param {string} domID DOM id to pass to the callback.
155 - */
156 - executeDispatch: function(abstractEvent, listener, domID) {
157 - var returnValue = listener(abstractEvent, domID);
158 - if (returnValue === false) {
159 - abstractEvent.stopPropagation();
160 - abstractEvent.preventDefault();
161 - }
162 - },
163 -
164 - /**
165 - * @see EventPluginHub.extractAbstractEvents
166 - */
167 - extractAbstractEvents:
168 - function(topLevelType, nativeEvent, renderedTargetID, renderedTarget) {
169 - var data;
170 - var abstractEventType =
171 - SimpleEventPlugin.topLevelTypesToAbstract[topLevelType];
172 - if (!abstractEventType) {
173 - return null;
174 - }
175 - switch(topLevelType) {
176 - case topLevelTypes.topMouseWheel:
177 - data = AbstractEvent.normalizeMouseWheelData(nativeEvent);
178 - break;
179 - case topLevelTypes.topScroll:
180 - data = AbstractEvent.normalizeScrollDataFromTarget(renderedTarget);
181 - break;
182 - case topLevelTypes.topClick:
183 - case topLevelTypes.topDoubleClick:
184 - case topLevelTypes.topChange:
185 - case topLevelTypes.topDOMCharacterDataModified:
186 - case topLevelTypes.topMouseDown:
187 - case topLevelTypes.topMouseUp:
188 - case topLevelTypes.topMouseMove:
189 - case topLevelTypes.topTouchMove:
190 - case topLevelTypes.topTouchStart:
191 - case topLevelTypes.topTouchEnd:
192 - data = AbstractEvent.normalizePointerData(nativeEvent);
193 - break;
194 - default:
195 - data = null;
196 - }
197 - var abstractEvent = AbstractEvent.getPooled(
198 - abstractEventType,
199 - renderedTargetID,
200 - topLevelType,
201 - nativeEvent,
202 - data
203 - );
204 - EventPropagators.accumulateTwoPhaseDispatches(abstractEvent);
205 - return abstractEvent;
206 - }
207 -};
208 -
209 -SimpleEventPlugin.topLevelTypesToAbstract = {
210 - topMouseDown: SimpleEventPlugin.abstractEventTypes.mouseDown,
211 - topMouseUp: SimpleEventPlugin.abstractEventTypes.mouseUp,
212 - topMouseMove: SimpleEventPlugin.abstractEventTypes.mouseMove,
213 - topClick: SimpleEventPlugin.abstractEventTypes.click,
214 - topDoubleClick: SimpleEventPlugin.abstractEventTypes.doubleClick,
215 - topMouseWheel: SimpleEventPlugin.abstractEventTypes.mouseWheel,
216 - topTouchStart: SimpleEventPlugin.abstractEventTypes.touchStart,
217 - topTouchEnd: SimpleEventPlugin.abstractEventTypes.touchEnd,
218 - topTouchMove: SimpleEventPlugin.abstractEventTypes.touchMove,
219 - topTouchCancel: SimpleEventPlugin.abstractEventTypes.touchCancel,
220 - topKeyUp: SimpleEventPlugin.abstractEventTypes.keyUp,
221 - topKeyPress: SimpleEventPlugin.abstractEventTypes.keyPress,
222 - topKeyDown: SimpleEventPlugin.abstractEventTypes.keyDown,
223 - topFocus: SimpleEventPlugin.abstractEventTypes.focus,
224 - topBlur: SimpleEventPlugin.abstractEventTypes.blur,
225 - topScroll: SimpleEventPlugin.abstractEventTypes.scroll,
226 - topChange: SimpleEventPlugin.abstractEventTypes.change,
227 - topSubmit: SimpleEventPlugin.abstractEventTypes.submit,
228 - topDOMCharacterDataModified:
229 - SimpleEventPlugin.abstractEventTypes.DOMCharacterDataModified
230 -};
231 -
232 -module.exports = SimpleEventPlugin;
React/TapEventPlugin.js deleted
-89
@@ -1,89 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule TapEventPlugin
17 - */
18 -
19 -"use strict";
20 -
21 -var AbstractEvent = require("./AbstractEvent");
22 -var EventPluginUtils = require("./EventPluginUtils");
23 -var EventPropagators = require("./EventPropagators");
24 -
25 -var keyOf = require("./keyOf");
26 -
27 -var isStartish = EventPluginUtils.isStartish;
28 -var isEndish = EventPluginUtils.isEndish;
29 -var storePageCoordsIn = EventPluginUtils.storePageCoordsIn;
30 -var eventDistance = EventPluginUtils.eventDistance;
31 -
32 -/**
33 - * The number of pixels that are tolerated in between a touchStart and
34 - * touchEnd in order to still be considered a 'tap' event.
35 - */
36 -var tapMoveThreshold = 10;
37 -var startCoords = {x: null, y: null};
38 -
39 -var abstractEventTypes = {
40 - touchTap: {
41 - phasedRegistrationNames: {
42 - bubbled: keyOf({onTouchTap: null}),
43 - captured: keyOf({onTouchTapCapture: null})
44 - }
45 - }
46 -};
47 -
48 -/**
49 - * @see EventPluginHub.extractAbstractEvents
50 - */
51 -var extractAbstractEvents = function(
52 - topLevelType,
53 - nativeEvent,
54 - renderedTargetID,
55 - renderedTarget) {
56 -
57 - if (!isStartish(topLevelType) && !isEndish(topLevelType)) {
58 - return;
59 - }
60 - var abstractEvent;
61 - var dist = eventDistance(startCoords, nativeEvent);
62 - if (isEndish(topLevelType) && dist < tapMoveThreshold) {
63 - var type = abstractEventTypes.touchTap;
64 - var abstractTargetID = renderedTargetID;
65 - abstractEvent = AbstractEvent.getPooled(
66 - type,
67 - abstractTargetID,
68 - topLevelType,
69 - nativeEvent
70 - );
71 - }
72 - if (isStartish(topLevelType)) {
73 - storePageCoordsIn(startCoords, nativeEvent);
74 - } else if (isEndish(topLevelType)) {
75 - startCoords.x = 0;
76 - startCoords.y = 0;
77 - }
78 - EventPropagators.accumulateTwoPhaseDispatches(abstractEvent);
79 - return abstractEvent;
80 -};
81 -
82 -var TapEventPlugin = {
83 - tapMoveThreshold: tapMoveThreshold,
84 - startCoords: startCoords,
85 - abstractEventTypes: abstractEventTypes,
86 - extractAbstractEvents: extractAbstractEvents
87 -};
88 -
89 -module.exports = TapEventPlugin;
React/TouchEventUtils.js deleted
-42
@@ -1,42 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule TouchEventUtils
17 - */
18 -
19 -var TouchEventUtils = {
20 - /**
21 - * Utility function for common case of extracting out the primary touch from a
22 - * touch event.
23 - * - `touchEnd` events usually do not have the `touches` property.
24 - * http://stackoverflow.com/questions/3666929/
25 - * mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed
26 - *
27 - * @param {Event} nativeEvent Native event that may or may not be a touch.
28 - * @return {TouchesObject?} an object with pageX and pageY or null.
29 - */
30 - extractSingleTouch: function(nativeEvent) {
31 - var touches = nativeEvent.touches;
32 - var changedTouches = nativeEvent.changedTouches;
33 - var hasTouches = touches && touches.length > 0;
34 - var hasChangedTouches = changedTouches && changedTouches.length > 0;
35 -
36 - return !hasTouches && hasChangedTouches ? changedTouches[0] :
37 - hasTouches ? touches[0] :
38 - nativeEvent;
39 - }
40 -};
41 -
42 -module.exports = TouchEventUtils;
React/Transaction.js deleted
-252
@@ -1,252 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule Transaction
17 - */
18 -
19 -"use strict";
20 -
21 -var throwIf = require("./throwIf");
22 -
23 -var DUAL_TRANSACTION = 'DUAL_TRANSACTION';
24 -var MISSING_TRANSACTION = 'MISSING_TRANSACTION';
25 -if (true) {
26 - DUAL_TRANSACTION =
27 - 'Cannot initialize transaction when there is already an outstanding ' +
28 - 'transaction. Common causes of this are trying to render a component ' +
29 - 'when you are already rendering a component or attempting a state ' +
30 - 'transition while in a render function. Another possibility is that ' +
31 - 'you are rendering new content (or state transitioning) in a ' +
32 - 'componentDidRender callback. If this is not the case, please report the ' +
33 - 'issue immediately.';
34 -
35 - MISSING_TRANSACTION =
36 - 'Cannot close transaction when there is none open.';
37 -}
38 -
39 -/**
40 - * `Transaction` creates a black box that is able to wrap any method such that
41 - * certain invariants are maintained before and after the method is invoked
42 - * (Even if an exception is thrown while invoking the wrapped method). Whoever
43 - * instantiates a transaction can provide enforcers of the invariants at
44 - * creation time. The `Transaction` class itself will supply one additional
45 - * automatic invariant for you - the invariant that any transaction instance
46 - * should not be ran while it is already being ran. You would typically create a
47 - * single instance of a `Transaction` for reuse multiple times, that potentially
48 - * is used to wrap several different methods. Wrappers are extremely simple -
49 - * they only require implementing two methods.
50 - *
51 - * <pre>
52 - * wrappers (injected at creation time)
53 - * + +
54 - * | |
55 - * +-----------------|--------|--------------+
56 - * | v | |
57 - * | +---------------+ | |
58 - * | +--| wrapper1 |---|----+ |
59 - * | | +---------------+ v | |
60 - * | | +-------------+ | |
61 - * | | +----| wrapper2 |--------+ |
62 - * | | | +-------------+ | | |
63 - * | | | | | |
64 - * | v v v v | wrapper
65 - * | +---+ +---+ +---------+ +---+ +---+ | invariants
66 - * perform(anyMethod) | | | | | | | | | | | | maintained
67 - * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
68 - * | | | | | | | | | | | |
69 - * | | | | | | | | | | | |
70 - * | | | | | | | | | | | |
71 - * | +---+ +---+ +---------+ +---+ +---+ |
72 - * | initialize close |
73 - * +-----------------------------------------+
74 - * </pre>
75 - *
76 - * Bonus:
77 - * - Reports timing metrics by method name and wrapper index.
78 - *
79 - * Use cases:
80 - * - Preserving the input selection ranges before/after reconciliation.
81 - * Restoring selection even in the event of an unexpected error.
82 - * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
83 - * while guaranteeing that afterwards, the event system is reactivated.
84 - * - Flushing a queue of collected DOM mutations to the main UI thread after a
85 - * reconciliation takes place in a worker thread.
86 - * - Invoking any collected `componentDidRender` callbacks after rendering new
87 - * content.
88 - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
89 - * to preserve the `scrollTop` (an automatic scroll aware DOM).
90 - * - (Future use case): Layout calculations before and after DOM upates.
91 - *
92 - * Transactional plugin API:
93 - * - A module that has an `initialize` method that returns any precomputation.
94 - * - and a `close` method that accepts the precomputation. `close` is invoked
95 - * when the wrapped process is completed, or has failed.
96 - *
97 - * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
98 - * that implement `initialize` and `close`.
99 - * @return {Transaction} Single transaction for reuse in thread.
100 - *
101 - * @class Transaction
102 - */
103 -var Mixin = {
104 - /**
105 - * Sets up this instance so that it is prepared for collecting metrics. Does
106 - * so such that this setup method may be used on an instance that is already
107 - * initialized, in a way that does not consume additional memory upon reuse.
108 - * That can be useful if you decide to make your subclass of this mixin a
109 - * "PooledClass".
110 - */
111 - reinitializeTransaction: function() {
112 - this.transactionWrappers = this.getTransactionWrappers();
113 - if (!this.wrapperInitData) {
114 - this.wrapperInitData = [];
115 - } else {
116 - this.wrapperInitData.length = 0;
117 - }
118 - if (!this.timingMetrics) {
119 - this.timingMetrics = {};
120 - }
121 - this.timingMetrics.methodInvocationTime = 0;
122 - if (!this.timingMetrics.wrapperInitTimes) {
123 - this.timingMetrics.wrapperInitTimes = [];
124 - } else {
125 - this.timingMetrics.wrapperInitTimes.length = 0;
126 - }
127 - if (!this.timingMetrics.wrapperCloseTimes) {
128 - this.timingMetrics.wrapperCloseTimes = [];
129 - } else {
130 - this.timingMetrics.wrapperCloseTimes.length = 0;
131 - }
132 - this._isInTransaction = false;
133 - },
134 -
135 - _isInTransaction: false,
136 -
137 - /**
138 - * @abstract
139 - * @return {Array<TransactionWrapper>} Array of transaction wrappers.
140 - */
141 - getTransactionWrappers: null,
142 -
143 - isInTransaction: function() {
144 - return !!this._isInTransaction;
145 - },
146 -
147 - /**
148 - * Executes the function within a safety window. Use this for the top level
149 - * methods that result in large amounts of computation/mutations that would
150 - * need to be safety checked.
151 - *
152 - * @param {function} method Member of scope to call.
153 - * @param {Object} scope Scope to invoke from.
154 - * @param {Object?=} args... Arguments to pass to the method (optional).
155 - * Helps prevent need to bind in many cases.
156 - * @returns Return value from `method`.
157 - */
158 - perform: function(method, scope, a, b, c, d, e, f) {
159 - throwIf(this.isInTransaction(), DUAL_TRANSACTION);
160 - var memberStart = Date.now();
161 - var err = null;
162 - var ret;
163 - try {
164 - this.initializeAll();
165 - ret = method.call(scope, a, b, c, d, e, f);
166 - } catch (ie_requires_catch) {
167 - err = ie_requires_catch;
168 - } finally {
169 - var memberEnd = Date.now();
170 - this.methodInvocationTime += (memberEnd - memberStart);
171 - try {
172 - this.closeAll();
173 - } catch (closeAllErr) {
174 - err = err || closeAllErr;
175 - }
176 - }
177 - if (err) {
178 - throw err;
179 - }
180 - return ret;
181 - },
182 -
183 - initializeAll: function() {
184 - this._isInTransaction = true;
185 - var transactionWrappers = this.transactionWrappers;
186 - var wrapperInitTimes = this.timingMetrics.wrapperInitTimes;
187 - var err = null;
188 - for (var i = 0; i < transactionWrappers.length; i++) {
189 - var initStart = Date.now();
190 - var wrapper = transactionWrappers[i];
191 - try {
192 - this.wrapperInitData[i] =
193 - wrapper.initialize ? wrapper.initialize.call(this) : null;
194 - } catch (initErr) {
195 - err = err || initErr; // Remember the first error.
196 - this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
197 - } finally {
198 - var curInitTime = wrapperInitTimes[i];
199 - var initEnd = Date.now();
200 - wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart);
201 - }
202 - }
203 - if (err) {
204 - throw err;
205 - }
206 - },
207 -
208 - /**
209 - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
210 - * them the respective return values of `this.transactionWrappers.init[i]`
211 - * (`close`rs that correspond to initializers that failed will not be
212 - * invoked).
213 - */
214 - closeAll: function() {
215 - throwIf(!this.isInTransaction(), MISSING_TRANSACTION);
216 - var transactionWrappers = this.transactionWrappers;
217 - var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes;
218 - var err = null;
219 - for (var i = 0; i < transactionWrappers.length; i++) {
220 - var wrapper = transactionWrappers[i];
221 - var closeStart = Date.now();
222 - var initData = this.wrapperInitData[i];
223 - try {
224 - if (initData !== Transaction.OBSERVED_ERROR) {
225 - wrapper.close && wrapper.close.call(this, initData);
226 - }
227 - } catch (closeErr) {
228 - err = err || closeErr; // Remember the first error.
229 - } finally {
230 - var closeEnd = Date.now();
231 - var curCloseTime = wrapperCloseTimes[i];
232 - wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart);
233 - }
234 - }
235 - this.wrapperInitData.length = 0;
236 - this._isInTransaction = false;
237 - if (err) {
238 - throw err;
239 - }
240 - }
241 -};
242 -
243 -var Transaction = {
244 - Mixin: Mixin,
245 - /**
246 - * Token to look for to determine if an error occured.
247 - */
248 - OBSERVED_ERROR: {}
249 -
250 -};
251 -
252 -module.exports = Transaction;
React/accumulate.js deleted
-70
@@ -1,70 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule accumulate
17 - */
18 -
19 -"use strict";
20 -
21 -var throwIf = require("./throwIf");
22 -
23 -var INVALID_ARGS = 'INVALID_ACCUM_ARGS';
24 -
25 -if (true) {
26 - INVALID_ARGS =
27 - 'accumulate requires non empty (non-null, defined) next ' +
28 - 'values. All arrays accumulated must not contain any empty items.';
29 -}
30 -
31 -/**
32 - * Accumulates items that must never be empty, into a result in a manner that
33 - * conserves memory - avoiding allocation of arrays until they are needed. The
34 - * accumulation may start and/or end up being a single element or an array
35 - * depending on the total count (if greater than one, an array is allocated).
36 - * Handles most common case first (starting with an empty current value and
37 - * acquiring one).
38 - * @returns {Accumulation} An accumulation which is either a single item or an
39 - * Array of items.
40 - */
41 -function accumulate(cur, next) {
42 - var curValIsEmpty = cur == null; // Will test for emptiness (null/undef)
43 - var nextValIsEmpty = next === null;
44 - if (true) {
45 - throwIf(nextValIsEmpty, INVALID_ARGS);
46 - }
47 - if (nextValIsEmpty) {
48 - return cur;
49 - } else {
50 - if (curValIsEmpty) {
51 - return next;
52 - } else {
53 - // Both are not empty. Warning: Never call x.concat(y) when you are not
54 - // certain that x is an Array (x could be a string with concat method).
55 - var curIsArray = Array.isArray(cur);
56 - var nextIsArray = Array.isArray(next);
57 - if (curIsArray) {
58 - return cur.concat(next);
59 - } else {
60 - if (nextIsArray) {
61 - return [cur].concat(next);
62 - } else {
63 - return [cur, next];
64 - }
65 - }
66 - }
67 - }
68 -}
69 -
70 -module.exports = accumulate;
React/copyProperties.js deleted
-54
@@ -1,54 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule copyProperties
17 - */
18 -
19 -/**
20 - * Copy properties from one or more objects (up to 5) into the first object.
21 - * This is a shallow copy. It mutates the first object and also returns it.
22 - *
23 - * NOTE: `arguments` has a very significant performance penalty, which is why
24 - * we don't support unlimited arguments.
25 - */
26 -function copyProperties(obj, a, b, c, d, e, f) {
27 - obj = obj || {};
28 -
29 - if (true) {
30 - if (f) {
31 - throw new Error('Too many arguments passed to copyProperties');
32 - }
33 - }
34 -
35 - var args = [a, b, c, d, e];
36 - var ii = 0, v;
37 - while (args[ii]) {
38 - v = args[ii++];
39 - for (var k in v) {
40 - obj[k] = v[k];
41 - }
42 -
43 - // IE ignores toString in object iteration.. See:
44 - // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html
45 - if (v.hasOwnProperty && v.hasOwnProperty('toString') &&
46 - (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {
47 - obj.toString = v.toString;
48 - }
49 - }
50 -
51 - return obj;
52 -}
53 -
54 -module.exports = copyProperties;
React/core/__tests__/ReactBind-test.js
React/core/__tests__/ReactComponent-test.js
React/core/__tests__/ReactComponentFlattenChildren-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: core/__tests__/ReactComponentFlattenChildren-test");
\ No newline at end of file
React/core/__tests__/ReactComponentLifeCycle-test.js
React/core/__tests__/ReactCompositeComponent-test.js
React/core/__tests__/ReactCompositeComponentDOMMinimalism-test.js deleted
-113
@@ -1,113 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -// Requires
23 -var React;
24 -var ReactTestUtils;
25 -var reactComponentExpect;
26 -
27 -// Test components
28 -var LowerLevelComposite;
29 -var MyCompositeComponent;
30 -
31 -var expectSingleChildlessDiv;
32 -
33 -/**
34 - * Integration test, testing the combination of JSX with our unit of
35 - * abstraction, `ReactCompositeComponent` does not ever add superfluous DOM
36 - * nodes.
37 - */
38 -describe('ReactCompositeComponentDOMMinimalism', function() {
39 -
40 - beforeEach(function() {
41 - reactComponentExpect = require("../../reactComponentExpect");
42 - React = require("../../React");
43 - ReactTestUtils = require("../../ReactTestUtils");
44 -
45 - LowerLevelComposite = React.createClass({
46 - render: function() {
47 - return (
48 - React.DOM.div(null,
49 - this.props.children
50 - )
51 - );
52 - }
53 - });
54 -
55 - MyCompositeComponent = React.createClass({
56 - render: function() {
57 - return (
58 - LowerLevelComposite(null,
59 - this.props.children
60 - )
61 - );
62 - }
63 - });
64 -
65 - expectSingleChildlessDiv = function(instance) {
66 - reactComponentExpect(instance)
67 - .expectRenderedChild()
68 - .toBeCompositeComponentWithType(LowerLevelComposite)
69 - .expectRenderedChild()
70 - .toBeDOMComponentWithTag('div')
71 - .toBeDOMComponentWithNoChildren();
72 - };
73 - });
74 -
75 - it('should not render extra nodes for non-interpolated text', function() {
76 - var instance = (
77 - MyCompositeComponent(null,
78 -" A string child " )
79 - );
80 - ReactTestUtils.renderIntoDocument(instance);
81 - expectSingleChildlessDiv(instance);
82 - });
83 -
84 - it('should not render extra nodes for non-interpolated text', function() {
85 - var instance = (
86 - MyCompositeComponent(null,
87 - 'Interpolated String Child'
88 - )
89 - );
90 - ReactTestUtils.renderIntoDocument(instance);
91 - expectSingleChildlessDiv(instance);
92 - });
93 -
94 - it('should not render extra nodes for non-interpolated text', function() {
95 - var instance = (
96 - MyCompositeComponent(null,
97 - React.DOM.ul(null,
98 -" This text causes no children in ul, just innerHTML " )
99 - )
100 - );
101 - ReactTestUtils.renderIntoDocument(instance);
102 - reactComponentExpect(instance)
103 - .expectRenderedChild()
104 - .toBeCompositeComponentWithType(LowerLevelComposite)
105 - .expectRenderedChild()
106 - .toBeDOMComponentWithTag('div')
107 - .toBeDOMComponentWithChildCount(1)
108 - .expectRenderedChildAt(0)
109 - .toBeDOMComponentWithTag('ul')
110 - .toBeDOMComponentWithNoChildren();
111 - });
112 -
113 -});
React/core/__tests__/ReactCompositeComponentMixin-test.js deleted
-82
@@ -1,82 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var mocks = require("../../mocks");
23 -
24 -var React;
25 -var ReactTestUtils;
26 -var reactComponentExpect;
27 -
28 -var TestComponent;
29 -
30 -describe('ReactCompositeComponent-mixin', function() {
31 -
32 - beforeEach(function() {
33 - React = require("../../React");
34 - ReactTestUtils = require("../../ReactTestUtils");
35 - reactComponentExpect = require("../../reactComponentExpect");
36 -
37 - var MixinA = {
38 - componentDidMount: function() {
39 - this.props.listener('MixinA didMount');
40 - }
41 - };
42 -
43 - var MixinB = {
44 - mixins: [MixinA],
45 - componentDidMount: function() {
46 - this.props.listener('MixinB didMount');
47 - }
48 - };
49 -
50 - var MixinC = {
51 - componentDidMount: function() {
52 - this.props.listener('MixinC didMount');
53 - }
54 - };
55 -
56 - TestComponent = React.createClass({
57 - mixins: [MixinB, MixinC],
58 -
59 - componentDidMount: function() {
60 - this.props.listener('Component didMount');
61 - },
62 -
63 - render: function() {
64 - return React.DOM.div(null, null );
65 - }
66 - });
67 -
68 - });
69 -
70 - it('should support chaining delegate functions', function() {
71 - var listener = mocks.getMockFunction();
72 - var instance = TestComponent( {listener:listener}, null );
73 - ReactTestUtils.renderIntoDocument(instance);
74 -
75 - expect(listener.mock.calls).toEqual([
76 - ['MixinA didMount'],
77 - ['MixinB didMount'],
78 - ['MixinC didMount'],
79 - ['Component didMount']
80 - ]);
81 - });
82 -});
React/core/__tests__/ReactCompositeComponentSpec-test.js
React/core/__tests__/ReactCompositeComponentState-test.js deleted
-169
@@ -1,169 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var mocks = require("../../mocks");
23 -
24 -var React;
25 -var ReactTestUtils;
26 -var reactComponentExpect;
27 -
28 -var TestComponent;
29 -
30 -describe('ReactCompositeComponent-state', function() {
31 -
32 - beforeEach(function() {
33 - React = require("../../React");
34 - ReactTestUtils = require("../../ReactTestUtils");
35 - reactComponentExpect = require("../../reactComponentExpect");
36 -
37 - TestComponent = React.createClass({
38 - peekAtState: function(from, state) {
39 - if (state) {
40 - this.props.stateListener(from, state && state.color);
41 - } else {
42 - this.props.stateListener(
43 - from,
44 - this.state && this.state.color,
45 - this._pendingState && this._pendingState.color
46 - );
47 - }
48 - },
49 -
50 - setFavoriteColor: function(nextColor) {
51 - this.setState({color: nextColor});
52 - },
53 -
54 - getInitialState: function() {
55 - this.peekAtState('getInitialState');
56 - return {color: 'red'};
57 - },
58 -
59 - render: function() {
60 - this.peekAtState('render');
61 - return React.DOM.div(null, this.state.color);
62 - },
63 -
64 - componentWillMount: function() {
65 - this.peekAtState('componentWillMount-start');
66 - this.setState({color: 'sunrise'});
67 - this.peekAtState('componentWillMount-after-sunrise');
68 - this.setState({color: 'orange'});
69 - this.peekAtState('componentWillMount-end');
70 - },
71 -
72 - componentDidMount: function() {
73 - this.peekAtState('componentDidMount-start');
74 - this.setState({color: 'yellow'});
75 - this.peekAtState('componentDidMount-end');
76 - },
77 -
78 - componentWillReceiveProps: function(newProps) {
79 - this.peekAtState('componentWillReceiveProps-start');
80 - if (newProps.nextColor) {
81 - this.setState({color: newProps.nextColor});
82 - }
83 - this.peekAtState('componentWillReceiveProps-end');
84 - },
85 -
86 - shouldComponentUpdate: function(nextProps, nextState) {
87 - this.peekAtState('shouldComponentUpdate-currentState');
88 - this.peekAtState('shouldComponentUpdate-nextState', nextState);
89 - return true;
90 - },
91 -
92 - componentWillUpdate: function(nextProps, nextState) {
93 - this.peekAtState('componentWillUpdate-currentState');
94 - this.peekAtState('componentWillUpdate-nextState', nextState);
95 - },
96 -
97 - componentDidUpdate: function(prevProps, prevState) {
98 - this.peekAtState('componentDidUpdate-currentState');
99 - this.peekAtState('componentDidUpdate-prevState', prevState);
100 - },
101 -
102 - componentWillUnmount: function() {
103 - this.peekAtState('componentWillUnmount');
104 - }
105 - });
106 -
107 - });
108 -
109 - it('should support setting state', function() {
110 - var stateListener = mocks.getMockFunction();
111 - var instance = TestComponent( {stateListener:stateListener}, null );
112 - ReactTestUtils.renderIntoDocument(instance);
113 - instance.setProps({nextColor: 'green'});
114 - instance.setFavoriteColor('blue');
115 - instance.forceUpdate();
116 - instance.unmountComponent();
117 -
118 - expect(stateListener.mock.calls).toEqual([
119 - // there is no state when getInitialState() is called
120 - [ 'getInitialState', null, null ],
121 - [ 'componentWillMount-start', 'red', null ],
122 - // setState() only enqueues a pending state.
123 - [ 'componentWillMount-after-sunrise', 'red', 'sunrise' ],
124 - [ 'componentWillMount-end', 'red', 'orange' ],
125 - // pending state has been applied
126 - [ 'render', 'orange', null ],
127 - [ 'componentDidMount-start', 'orange', null ],
128 - // componentDidMount() called setState({color:'yellow'}), currently this
129 - // occurs inline.
130 - // In a future where setState() is async, this test result will change.
131 - [ 'shouldComponentUpdate-currentState', 'orange', null ],
132 - [ 'shouldComponentUpdate-nextState', 'yellow' ],
133 - [ 'componentWillUpdate-currentState', 'orange', null ],
134 - [ 'componentWillUpdate-nextState', 'yellow' ],
135 - [ 'render', 'yellow', null ],
136 - [ 'componentDidUpdate-currentState', 'yellow', null ],
137 - [ 'componentDidUpdate-prevState', 'orange' ],
138 - // componentDidMount() finally closes.
139 - [ 'componentDidMount-end', 'yellow', null ],
140 - [ 'componentWillReceiveProps-start', 'yellow', null ],
141 - // setState({color:'green'}) only enqueues a pending state.
142 - [ 'componentWillReceiveProps-end', 'yellow', 'green' ],
143 - [ 'shouldComponentUpdate-currentState', 'yellow', null ],
144 - [ 'shouldComponentUpdate-nextState', 'green' ],
145 - [ 'componentWillUpdate-currentState', 'yellow', null ],
146 - [ 'componentWillUpdate-nextState', 'green' ],
147 - [ 'render', 'green', null ],
148 - [ 'componentDidUpdate-currentState', 'green', null ],
149 - [ 'componentDidUpdate-prevState', 'yellow' ],
150 - // setFavoriteColor('blue')
151 - [ 'shouldComponentUpdate-currentState', 'green', null ],
152 - [ 'shouldComponentUpdate-nextState', 'blue' ],
153 - [ 'componentWillUpdate-currentState', 'green', null ],
154 - [ 'componentWillUpdate-nextState', 'blue' ],
155 - [ 'render', 'blue', null ],
156 - [ 'componentDidUpdate-currentState', 'blue', null ],
157 - [ 'componentDidUpdate-prevState', 'green' ],
158 - // forceUpdate()
159 - [ 'componentWillUpdate-currentState', 'blue', null ],
160 - [ 'componentWillUpdate-nextState', 'blue' ],
161 - [ 'render', 'blue', null ],
162 - [ 'componentDidUpdate-currentState', 'blue', null ],
163 - [ 'componentDidUpdate-prevState', 'blue' ],
164 - // unmountComponent()
165 - // state is available within `componentWillUnmount()`
166 - [ 'componentWillUnmount', 'blue', null ]
167 - ]);
168 - });
169 -});
React/core/__tests__/ReactCompositeComponentTransferProps-test.js
React/core/__tests__/ReactDOM-test.js deleted
-112
@@ -1,112 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var React = require("../../React");
23 -var ReactDOM = require("../../ReactDOM");
24 -var ReactTestUtils = require("../../ReactTestUtils");
25 -var React = require("../../React");
26 -
27 -describe('ref swapping', function() {
28 - // TODO: uncomment this test once we can run in phantom, which
29 - // supports real submit events.
30 - /*
31 - it('should bubble onSubmit', function() {
32 - var count = 0;
33 - var form;
34 - var Parent = React.createClass({
35 - handleSubmit: function() {
36 - count++;
37 - return false;
38 - },
39 - render: function() {
40 - return <Child />;
41 - }
42 - });
43 - var Child = React.createClass({
44 - render: function() {
45 - return <form><input type="submit" value="Submit" /></form>;
46 - },
47 - componentDidMount: function(node) {
48 - form = node;
49 - }
50 - });
51 - var instance = ReactTestUtils.renderIntoDocument(<Parent />);
52 - form.submit();
53 - expect(count).toEqual(1);
54 - });
55 - */
56 -
57 - it("should allow children to be passed as an argument", function() {
58 - var argDiv = ReactTestUtils.renderIntoDocument(
59 - ReactDOM.div(null, 'child')
60 - );
61 - var argNode = document.getElementById(argDiv._rootNodeID);
62 - expect(argNode.innerHTML).toBe('child');
63 - });
64 -
65 - it("should overwrite props.children with children argument", function() {
66 - var conflictDiv = ReactTestUtils.renderIntoDocument(
67 - ReactDOM.div({children: 'fakechild'}, 'child')
68 - );
69 - var conflictNode = document.getElementById(conflictDiv._rootNodeID);
70 - expect(conflictNode.innerHTML).toBe('child');
71 - });
72 -
73 - /**
74 - * We need to make sure that updates occur to the actual node that's in the
75 - * DOM, instead of a stale cache.
76 - */
77 - it("should purge the DOM cache when removing nodes", function() {
78 - var myDiv = ReactTestUtils.renderIntoDocument(
79 - React.DOM.div(null, {
80 - theDog: React.DOM.div( {className:"dog"}, null ),
81 - theBird: React.DOM.div( {className:"bird"}, null )
82 - })
83 - );
84 - myDiv.setProps({
85 - children: {
86 - theDog: React.DOM.div( {className:"dogbeforedelete"}, null ), // Warm the cache with theDog
87 - theBird: React.DOM.div( {className:"bird"}, null )
88 - }
89 - });
90 - myDiv.setProps({
91 - children: { // This better purge that cache
92 - theBird: React.DOM.div( {className:"bird"}, null )
93 - }
94 - });
95 - // Now, put the dog back.
96 - myDiv.setProps({
97 - children: {
98 - theDog: React.DOM.div( {className:"dog"}, null ), // This is a different node than before
99 - theBird: React.DOM.div( {className:"bird"}, null )
100 - }
101 - });
102 - myDiv.setProps({
103 - children: { // className changed to bigdog.
104 - theDog: React.DOM.div( {className:"bigdog"}, null ), // but will it use the proper element
105 - theBird: React.DOM.div( {className:"bird"}, null )
106 - }
107 - });
108 - var root = document.getElementById(myDiv._rootNodeID);
109 - var dog = root.childNodes[0];
110 - expect(dog.className).toBe('bigdog');
111 - });
112 -});
React/core/__tests__/ReactDOMIDOperations-test.js deleted
-65
@@ -1,65 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -/*jslint evil: true */
20 -
21 -"use strict";
22 -
23 -describe('ReactDOMIDOperations', function() {
24 - var DOMPropertyOperations = require("../../DOMPropertyOperations");
25 - var ReactDOMIDOperations = require("../../ReactDOMIDOperations");
26 - var ReactDOMNodeCache = require("../../ReactDOMNodeCache");
27 - var keyOf = require("../../keyOf");
28 -
29 - it('should disallow updating special properties', function() {
30 - spyOn(ReactDOMNodeCache, "getCachedNodeByID");
31 - spyOn(DOMPropertyOperations, "setValueForProperty");
32 -
33 - expect(function() {
34 - ReactDOMIDOperations.updatePropertyByID(
35 - 'testID',
36 - keyOf({content: null}),
37 - 'testContent'
38 - );
39 - }).toThrow();
40 -
41 - expect(
42 - ReactDOMNodeCache.getCachedNodeByID.argsForCall[0][0]
43 - ).toBe('testID');
44 -
45 - expect(
46 - DOMPropertyOperations.setValueForProperty.callCount
47 - ).toBe(0);
48 - });
49 -
50 - it('should update innerHTML and special-case whitespace', function() {
51 - var stubNode = document.createElement('div');
52 - spyOn(ReactDOMNodeCache, "getCachedNodeByID").andReturn(stubNode);
53 -
54 - ReactDOMIDOperations.updateInnerHTMLByID(
55 - 'testID',
56 - {__html: ' testContent'}
57 - );
58 -
59 - expect(
60 - ReactDOMNodeCache.getCachedNodeByID.argsForCall[0][0]
61 - ).toBe('testID');
62 -
63 - expect(stubNode.innerHTML).toBe('&nbsp;testContent');
64 - });
65 -});
React/core/__tests__/ReactEvent-test.js deleted
-335
@@ -1,335 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -require("../../mock-modules")
22 - .dontMock('BrowserScroll')
23 - .dontMock('CallbackRegistry')
24 - .dontMock('EventPluginHub')
25 - .dontMock('ReactEvent')
26 - .dontMock('ReactInstanceHandles')
27 - .dontMock('EventPluginHub')
28 - .dontMock('TapEventPlugin')
29 - .dontMock('TouchEventUtils')
30 - .dontMock('keyOf');
31 -
32 -
33 -var keyOf = require("../../keyOf");
34 -var mocks = require("../../mocks");
35 -
36 -var EventPluginHub;
37 -var ReactEvent;
38 -var ReactEventTopLevelCallback;
39 -var ReactTestUtils;
40 -var TapEventPlugin;
41 -
42 -var tapMoveThreshold;
43 -var idCallOrder = [];
44 -var recordID = function(id) {
45 - idCallOrder.push(id);
46 -};
47 -var recordIDAndStopPropagation = function(id, event) {
48 - recordID(id);
49 - event.stopPropagation();
50 -};
51 -var recordIDAndReturnFalse = function(id, event) {
52 - recordID(id);
53 - return false;
54 -};
55 -var LISTENER = mocks.getMockFunction();
56 -var ON_CLICK_KEY = keyOf({onClick: null});
57 -var ON_TOUCH_TAP_KEY = keyOf({onTouchTap: null});
58 -
59 -
60 -/**
61 - * Since `ReactEvent` is fairly well separated from the DOM, we can test almost
62 - * all of `ReactEvent` without ever rendering anything in the DOM. As long as we
63 - * provide IDs that follow `React's` conventional id namespace hierarchy.
64 - * The only reason why we create these DOM nodes, is so that when we feed them
65 - * into `ReactEvent` (through `ReactTestUtils`), the event handlers may receive
66 - * a DOM node to inspect.
67 - */
68 -var CHILD = document.createElement('div');
69 -var PARENT = document.createElement('div');
70 -var GRANDPARENT = document.createElement('div');
71 -CHILD.id = '.reactRoot.[0].[0].[0]';
72 -PARENT.id = '.reactRoot.[0].[0]';
73 -GRANDPARENT.id = '.reactRoot.[0]';
74 -
75 -function registerSimpleTestHandler() {
76 - ReactEvent.putListener(CHILD.id, ON_CLICK_KEY, LISTENER);
77 - var listener = ReactEvent.getListener(CHILD.id, ON_CLICK_KEY);
78 - expect(listener).toEqual(LISTENER);
79 - return ReactEvent.getListener(CHILD.id, ON_CLICK_KEY);
80 -}
81 -
82 -
83 -describe('ReactEvent', function() {
84 - beforeEach(function() {
85 - require("../../mock-modules").dumpCache();
86 - EventPluginHub = require("../../EventPluginHub");
87 - TapEventPlugin = require("../../TapEventPlugin");
88 - ReactEvent = require("../../ReactEvent");
89 - ReactTestUtils = require("../../ReactTestUtils");
90 - ReactEventTopLevelCallback = require("../../ReactEventTopLevelCallback");
91 - idCallOrder = [];
92 - tapMoveThreshold = TapEventPlugin.tapMoveThreshold;
93 - ReactEvent.ensureListening(false, ReactEventTopLevelCallback);
94 - EventPluginHub.injection.injectEventPluginsByName({
95 - TapEventPlugin: TapEventPlugin
96 - });
97 - });
98 -
99 - it('should store a listener correctly', function() {
100 - registerSimpleTestHandler();
101 - var listener = ReactEvent.getListener(CHILD.id, ON_CLICK_KEY);
102 - expect(listener).toBe(LISTENER);
103 - });
104 -
105 - it('should retrieve a listener correctly', function() {
106 - registerSimpleTestHandler();
107 - var listener = ReactEvent.getListener(CHILD.id, ON_CLICK_KEY);
108 - expect(listener).toEqual(LISTENER);
109 - });
110 -
111 - it('should clear all handlers when asked to', function() {
112 - registerSimpleTestHandler();
113 - ReactEvent.deleteAllListeners(CHILD.id);
114 - var listener = ReactEvent.getListener(CHILD.id, ON_CLICK_KEY);
115 - expect(listener).toBe(undefined);
116 - });
117 -
118 - it('should invoke a simple handler registered on a node', function() {
119 - registerSimpleTestHandler();
120 - ReactTestUtils.Simulate.click(CHILD);
121 - expect(LISTENER.mock.calls.length).toBe(1);
122 - });
123 -
124 - it('should not invoke handlers when ReactEvent is disabled', function() {
125 - registerSimpleTestHandler();
126 - ReactEvent.setEnabled(false);
127 - ReactTestUtils.Simulate.click(CHILD);
128 - expect(LISTENER.mock.calls.length).toBe(0);
129 - ReactEvent.setEnabled(true);
130 - ReactTestUtils.Simulate.click(CHILD);
131 - expect(LISTENER.mock.calls.length).toBe(1);
132 - });
133 -
134 - it('should bubble simply', function() {
135 - ReactEvent.putListener(
136 - CHILD.id,
137 - ON_CLICK_KEY,
138 - recordID.bind(null, CHILD.id)
139 - );
140 - ReactEvent.putListener(
141 - PARENT.id,
142 - ON_CLICK_KEY,
143 - recordID.bind(null, PARENT.id)
144 - );
145 - ReactEvent.putListener(
146 - GRANDPARENT.id,
147 - ON_CLICK_KEY,
148 - recordID.bind(null, GRANDPARENT.id)
149 - );
150 - ReactTestUtils.Simulate.click(CHILD);
151 - expect(idCallOrder.length).toBe(3);
152 - expect(idCallOrder[0]).toBe(CHILD.id);
153 - expect(idCallOrder[1]).toBe(PARENT.id);
154 - expect(idCallOrder[2]).toBe(GRANDPARENT.id);
155 - });
156 -
157 - it('should support stopPropagation()', function() {
158 - ReactEvent.putListener(
159 - CHILD.id,
160 - ON_CLICK_KEY,
161 - recordID.bind(null, CHILD.id)
162 - );
163 - ReactEvent.putListener(
164 - PARENT.id,
165 - ON_CLICK_KEY,
166 - recordIDAndStopPropagation.bind(null, PARENT.id)
167 - );
168 - ReactEvent.putListener(
169 - GRANDPARENT.id,
170 - ON_CLICK_KEY,
171 - recordID.bind(null, GRANDPARENT.id)
172 - );
173 - ReactTestUtils.Simulate.click(CHILD);
174 - expect(idCallOrder.length).toBe(2);
175 - expect(idCallOrder[0]).toBe(CHILD.id);
176 - expect(idCallOrder[1]).toBe(PARENT.id);
177 - });
178 -
179 - it('should stop after first dispatch if stopPropagation', function() {
180 - ReactEvent.putListener(
181 - CHILD.id,
182 - ON_CLICK_KEY,
183 - recordIDAndStopPropagation.bind(null, CHILD.id)
184 - );
185 - ReactEvent.putListener(
186 - PARENT.id,
187 - ON_CLICK_KEY,
188 - recordID.bind(null, PARENT.id)
189 - );
190 - ReactEvent.putListener(
191 - GRANDPARENT.id,
192 - ON_CLICK_KEY,
193 - recordID.bind(null, GRANDPARENT.id)
194 - );
195 - ReactTestUtils.Simulate.click(CHILD);
196 - expect(idCallOrder.length).toBe(1);
197 - expect(idCallOrder[0]).toBe(CHILD.id);
198 - });
199 -
200 - it('should stopPropagation if false is returned', function() {
201 - ReactEvent.putListener(
202 - CHILD.id,
203 - ON_CLICK_KEY,
204 - recordIDAndReturnFalse.bind(null, CHILD.id)
205 - );
206 - ReactEvent.putListener(
207 - PARENT.id,
208 - ON_CLICK_KEY,
209 - recordID.bind(null, PARENT.id)
210 - );
211 - ReactEvent.putListener(
212 - GRANDPARENT.id,
213 - ON_CLICK_KEY,
214 - recordID.bind(null, GRANDPARENT.id)
215 - );
216 - ReactTestUtils.Simulate.click(CHILD);
217 - expect(idCallOrder.length).toBe(1);
218 - expect(idCallOrder[0]).toBe(CHILD.id);
219 - });
220 -
221 - /**
222 - * The entire event registration state of the world should be "locked-in" at
223 - * the time the event occurs. This is to resolve many edge cases that come
224 - * about from a listener on a lower-in-DOM node causing structural changes at
225 - * places higher in the DOM. If this lower-in-DOM node causes new content to
226 - * be rendered at a place higher-in-DOM, we need to be careful not to invoke
227 - * these new listeners.
228 - */
229 -
230 - it('should invoke handlers that were removed while bubbling', function() {
231 - var handleParentClick = mocks.getMockFunction();
232 - var handleChildClick = function(abstractEvent) {
233 - ReactEvent.deleteAllListeners(PARENT.id);
234 - };
235 - ReactEvent.putListener(CHILD.id, ON_CLICK_KEY, handleChildClick);
236 - ReactEvent.putListener(PARENT.id, ON_CLICK_KEY, handleParentClick);
237 - ReactTestUtils.Simulate.click(CHILD);
238 - expect(handleParentClick.mock.calls.length).toBe(1);
239 - });
240 -
241 - it('should not invoke newly inserted handlers while bubbling', function() {
242 - var handleParentClick = mocks.getMockFunction();
243 - var handleChildClick = function(abstractEvent) {
244 - ReactEvent.putListener(PARENT.id, ON_CLICK_KEY, handleParentClick);
245 - };
246 - ReactEvent.putListener(CHILD.id, ON_CLICK_KEY, handleChildClick);
247 - ReactTestUtils.Simulate.click(CHILD);
248 - expect(handleParentClick.mock.calls.length).toBe(0);
249 - });
250 -
251 - it('should infer onTouchTap from a touchStart/End', function() {
252 - ReactEvent.putListener(
253 - CHILD.id,
254 - ON_TOUCH_TAP_KEY,
255 - recordID.bind(null, CHILD.id)
256 - );
257 - ReactTestUtils.Simulate.touchStart(
258 - CHILD,
259 - ReactTestUtils.nativeTouchData(0, 0)
260 - );
261 - ReactTestUtils.Simulate.touchEnd(
262 - CHILD,
263 - ReactTestUtils.nativeTouchData(0, 0)
264 - );
265 - expect(idCallOrder.length).toBe(1);
266 - expect(idCallOrder[0]).toBe(CHILD.id);
267 - });
268 -
269 - it('should infer onTouchTap from when dragging below threshold', function() {
270 - ReactEvent.putListener(
271 - CHILD.id,
272 - ON_TOUCH_TAP_KEY,
273 - recordID.bind(null, CHILD.id)
274 - );
275 - ReactTestUtils.Simulate.touchStart(
276 - CHILD,
277 - ReactTestUtils.nativeTouchData(0, 0)
278 - );
279 - ReactTestUtils.Simulate.touchEnd(
280 - CHILD,
281 - ReactTestUtils.nativeTouchData(0, tapMoveThreshold - 1)
282 - );
283 - expect(idCallOrder.length).toBe(1);
284 - expect(idCallOrder[0]).toBe(CHILD.id);
285 - });
286 -
287 - it('should not onTouchTap from when dragging beyond threshold', function() {
288 - ReactEvent.putListener(
289 - CHILD.id,
290 - ON_TOUCH_TAP_KEY,
291 - recordID.bind(null, CHILD.id)
292 - );
293 - ReactTestUtils.Simulate.touchStart(
294 - CHILD,
295 - ReactTestUtils.nativeTouchData(0, 0)
296 - );
297 - ReactTestUtils.Simulate.touchEnd(
298 - CHILD,
299 - ReactTestUtils.nativeTouchData(0, tapMoveThreshold + 1)
300 - );
301 - expect(idCallOrder.length).toBe(0);
302 - });
303 -
304 -
305 - it('should bubble onTouchTap', function() {
306 - ReactEvent.putListener(
307 - CHILD.id,
308 - ON_TOUCH_TAP_KEY,
309 - recordID.bind(null, CHILD.id)
310 - );
311 - ReactEvent.putListener(
312 - PARENT.id,
313 - ON_TOUCH_TAP_KEY,
314 - recordID.bind(null, PARENT.id)
315 - );
316 - ReactEvent.putListener(
317 - GRANDPARENT.id,
318 - ON_TOUCH_TAP_KEY,
319 - recordID.bind(null, GRANDPARENT.id)
320 - );
321 - ReactTestUtils.Simulate.touchStart(
322 - CHILD,
323 - ReactTestUtils.nativeTouchData(0, 0)
324 - );
325 - ReactTestUtils.Simulate.touchEnd(
326 - CHILD,
327 - ReactTestUtils.nativeTouchData(0, 0)
328 - );
329 - expect(idCallOrder.length).toBe(3);
330 - expect(idCallOrder[0]).toBe(CHILD.id);
331 - expect(idCallOrder[1]).toBe(PARENT.id);
332 - expect(idCallOrder[2]).toBe(GRANDPARENT.id);
333 - });
334 -
335 -});
React/core/__tests__/ReactIdentity-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: core/__tests__/ReactIdentity-test");
\ No newline at end of file
React/core/__tests__/ReactInstanceHandles-test.js
React/core/__tests__/ReactMount-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: core/__tests__/ReactMount-test");
\ No newline at end of file
React/core/__tests__/ReactMountDestruction-test.js deleted
-64
@@ -1,64 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var ReactMount = require("../../ReactMount");
23 -var React = require("../../React");
24 -var ReactTestUtils = require("../../ReactTestUtils");
25 -var ReactMount = require("../../ReactMount");
26 -
27 -var reactComponentExpect = require("../../reactComponentExpect");
28 -
29 -describe('ReactMount', function() {
30 - it("should destroy a react root upon request", function() {
31 - var mainContainerDiv = document.createElement('div');
32 - document.documentElement.appendChild(mainContainerDiv);
33 -
34 - var instanceOne = (
35 - React.DOM.div( {className:"firstReactDiv"}, null
36 - )
37 - );
38 - var firstRootDiv = document.createElement('div');
39 - mainContainerDiv.appendChild(firstRootDiv);
40 - React.renderComponent(instanceOne, firstRootDiv);
41 -
42 - var instanceTwo = (
43 - React.DOM.div( {className:"secondReactDiv"}, null
44 - )
45 - );
46 - var secondRootDiv = document.createElement('div');
47 - mainContainerDiv.appendChild(secondRootDiv);
48 - React.renderComponent(instanceTwo, secondRootDiv);
49 -
50 - // Test that two react roots are rendered in isolation
51 - expect(firstRootDiv.getElementsByClassName('firstReactDiv').length)
52 - .toBe(1);
53 - expect(secondRootDiv.getElementsByClassName('secondReactDiv').length)
54 - .toBe(1);
55 -
56 - // Test that after unmounting each, they are no longer in the document.
57 - React.unmountAndReleaseReactRootNode(firstRootDiv);
58 - expect(firstRootDiv.getElementsByClassName('firstReactDiv').length)
59 - .toBe(0);
60 - React.unmountAndReleaseReactRootNode(secondRootDiv);
61 - expect(secondRootDiv.getElementsByClassName('secondReactDiv').length)
62 - .toBe(0);
63 - });
64 -});
React/core/__tests__/ReactMultiChildReconcile-test.js
React/core/__tests__/ReactMultiChildText-test.js
React/core/__tests__/ReactNativeComponent-test.js deleted
-242
@@ -1,242 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -/*jslint evil: true */
21 -
22 -"use strict";
23 -
24 -describe('ReactNativeComponent', function() {
25 -
26 - describe('updateDOM', function() {
27 - var React;
28 - var ReactTestUtils;
29 - var transaction;
30 -
31 - beforeEach(function() {
32 - React = require("../../React");
33 - ReactTestUtils = require("../../ReactTestUtils");
34 -
35 - var ReactReconcileTransaction = require("../../ReactReconcileTransaction");
36 - transaction = new ReactReconcileTransaction();
37 - });
38 -
39 - it("should handle className", function() {
40 - var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:{}}, null ));
41 -
42 - stub.receiveProps({ className: 'foo' }, transaction);
43 - expect(stub.getDOMNode().className).toEqual('foo');
44 - stub.receiveProps({ className: 'bar' }, transaction);
45 - expect(stub.getDOMNode().className).toEqual('bar');
46 - stub.receiveProps({ className: null }, transaction);
47 - expect(stub.getDOMNode().className).toEqual('');
48 - });
49 -
50 - it("should gracefully handle various style value types", function() {
51 - var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:{}}, null ));
52 - var stubStyle = stub.getDOMNode().style;
53 -
54 - // set initial style
55 - var setup = { display: 'block', left: '1', top: 2, fontFamily: 'Arial' };
56 - stub.receiveProps({ style: setup }, transaction);
57 - expect(stubStyle.display).toEqual('block');
58 - expect(stubStyle.left).toEqual('1px');
59 - expect(stubStyle.fontFamily).toEqual('Arial');
60 -
61 - // reset the style to their default state
62 - var reset = { display: '', left: null, top: false, fontFamily: true };
63 - stub.receiveProps({ style: reset }, transaction);
64 - expect(stubStyle.display).toEqual('');
65 - expect(stubStyle.left).toEqual('');
66 - expect(stubStyle.top).toEqual('');
67 - expect(stubStyle.fontFamily).toEqual('');
68 - });
69 -
70 - it("should update styles when mutating style object", function() {
71 - var styles = { display: 'none', fontFamily: 'Arial' };
72 - var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles}, null ));
73 -
74 - var stubStyle = stub.getDOMNode().style;
75 - stubStyle.display = styles.display;
76 - stubStyle.fontFamily = styles.fontFamily;
77 -
78 - styles.display = 'block';
79 -
80 - stub.receiveProps({ style: styles }, transaction);
81 - expect(stubStyle.display).toEqual('block');
82 - expect(stubStyle.fontFamily).toEqual('Arial');
83 -
84 - styles.fontFamily = 'Helvetica';
85 -
86 - stub.receiveProps({ style: styles }, transaction);
87 - expect(stubStyle.display).toEqual('block');
88 - expect(stubStyle.fontFamily).toEqual('Helvetica');
89 - });
90 -
91 - it("should update styles if initially null", function() {
92 - var styles = null;
93 - var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles}, null ));
94 -
95 - var stubStyle = stub.getDOMNode().style;
96 -
97 - styles = {display: 'block'};
98 -
99 - stub.receiveProps({ style: styles }, transaction);
100 - expect(stubStyle.display).toEqual('block');
101 - });
102 -
103 - });
104 -
105 - describe('createOpenTagMarkup', function() {
106 - var genMarkup;
107 -
108 - function quoteRegexp(str) {
109 - return (str+'').replace(/([.?*+\^$\[\]\\(){}|-])/g, "\\$1");
110 - }
111 -
112 - beforeEach(function() {
113 - require("../../mock-modules").dumpCache();
114 -
115 - var mixInto = require("../../mixInto");
116 - var ReactNativeComponent = require("../../ReactNativeComponent");
117 -
118 - var NodeStub = function(initialProps) {
119 - this.props = initialProps || {};
120 - this._rootNodeID = 'test';
121 - };
122 - mixInto(NodeStub, ReactNativeComponent.Mixin);
123 -
124 - genMarkup = function(props) {
125 - return (new NodeStub(props))._createOpenTagMarkup();
126 - };
127 -
128 - this.addMatchers({
129 - toHaveAttribute: function(attr, value) {
130 - var expected = '(?:^|\\s)' + attr + '=[\\\'"]';
131 - if (typeof value != 'undefined') {
132 - expected += quoteRegexp(value) + '[\\\'"]';
133 - }
134 - return this.actual.match(new RegExp(expected));
135 - }
136 - });
137 - });
138 -
139 - it("should handle className", function() {
140 - expect(genMarkup({ className: 'a' })).toHaveAttribute('class', 'a');
141 - expect(genMarkup({ className: 'a b' })).toHaveAttribute('class', 'a b');
142 - expect(genMarkup({ className: '' })).toHaveAttribute('class', '');
143 - });
144 - });
145 -
146 - describe('createContentMarkup', function() {
147 - var genMarkup;
148 -
149 - function quoteRegexp(str) {
150 - return (str+'').replace(/([.?*+\^$\[\]\\(){}|-])/g, "\\$1");
151 - }
152 -
153 - beforeEach(function() {
154 - require("../../mock-modules").dumpCache();
155 -
156 - var mixInto = require("../../mixInto");
157 - var ReactNativeComponent = require("../../ReactNativeComponent");
158 - var ReactReconcileTransaction = require("../../ReactReconcileTransaction");
159 -
160 - var NodeStub = function(initialProps) {
161 - this.props = initialProps || {};
162 - this._rootNodeID = 'test';
163 - };
164 - mixInto(NodeStub, ReactNativeComponent.Mixin);
165 -
166 - genMarkup = function(props) {
167 - var transaction = new ReactReconcileTransaction();
168 - return (new NodeStub(props))._createContentMarkup(transaction);
169 - };
170 -
171 - this.addMatchers({
172 - toHaveInnerhtml: function(html) {
173 - var expected = '^' + quoteRegexp(html) + '$';
174 - return this.actual.match(new RegExp(expected));
175 - }
176 - });
177 - });
178 -
179 - it("should handle dangerouslySetInnerHTML", function() {
180 - var innerHTML = {__html: 'testContent'};
181 - expect(
182 - genMarkup({ dangerouslySetInnerHTML: innerHTML })
183 - ).toHaveInnerhtml('testContent');
184 - });
185 - });
186 -
187 - describe('mountComponent', function() {
188 - var mountComponent;
189 -
190 - beforeEach(function() {
191 - require("../../mock-modules").dumpCache();
192 -
193 - var mixInto = require("../../mixInto");
194 - var ReactComponent = require("../../ReactComponent");
195 - var ReactNativeComponent = require("../../ReactNativeComponent");
196 - var ReactReconcileTransaction = require("../../ReactReconcileTransaction");
197 -
198 - var NodeStub = function(initialProps) {
199 - ReactComponent.Mixin.construct.call(this, initialProps);
200 - };
201 - mixInto(NodeStub, ReactNativeComponent.Mixin);
202 -
203 - mountComponent = function(props) {
204 - var transaction = new ReactReconcileTransaction();
205 - return (new NodeStub(props)).mountComponent('test', transaction);
206 - };
207 - });
208 -
209 - it("should validate against multiple children props", function() {
210 - expect(function() {
211 - mountComponent({ content: '', children: '' });
212 - }).toThrow(
213 - 'Invariant Violation: Can only set one of `children`, ' +
214 - '`props.content`, or `props.dangerouslySetInnerHTML`.'
215 - );
216 -
217 - expect(function() {
218 - mountComponent({ content: '', dangerouslySetInnerHTML: '' });
219 - }).toThrow(
220 - 'Invariant Violation: Can only set one of `children`, ' +
221 - '`props.content`, or `props.dangerouslySetInnerHTML`.'
222 - );
223 -
224 - expect(function() {
225 - mountComponent({ children: '', dangerouslySetInnerHTML: '' });
226 - }).toThrow(
227 - 'Invariant Violation: Can only set one of `children`, ' +
228 - '`props.content`, or `props.dangerouslySetInnerHTML`.'
229 - );
230 - });
231 -
232 - it("should validate against invalid styles", function() {
233 - expect(function() {
234 - mountComponent({ style: 'display: none' });
235 - }).toThrow(
236 - 'Invariant Violation: The `style` prop expects a mapping from style ' +
237 - 'properties to values, not a string.'
238 - );
239 - });
240 - });
241 -
242 -});
React/core/__tests__/ReactProps-test.js deleted
-142
@@ -1,142 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var Props = require("../../ReactProps");
23 -
24 -function typeCheck(declaration, value) {
25 - var props = {};
26 - if (arguments.length > 1) {
27 - props.testProp = value;
28 - }
29 - return declaration.bind(this, props, 'testProp', 'testComponent');
30 -}
31 -
32 -describe('Primitive Types', function() {
33 - beforeEach(function() {
34 - require("../../mock-modules").dumpCache();
35 - });
36 -
37 - it("should throw for invalid strings", function() {
38 - expect(typeCheck(Props.string, [])).toThrow(
39 - 'Invariant Violation: Invalid prop `testProp` of type `array` ' +
40 - 'supplied to `testComponent`, expected `string`.'
41 - );
42 - expect(typeCheck(Props.string, false)).toThrow(
43 - 'Invariant Violation: Invalid prop `testProp` of type `boolean` ' +
44 - 'supplied to `testComponent`, expected `string`.'
45 - );
46 - expect(typeCheck(Props.string, 1)).toThrow(
47 - 'Invariant Violation: Invalid prop `testProp` of type `number` ' +
48 - 'supplied to `testComponent`, expected `string`.'
49 - );
50 - expect(typeCheck(Props.string, {})).toThrow(
51 - 'Invariant Violation: Invalid prop `testProp` of type `object` ' +
52 - 'supplied to `testComponent`, expected `string`.'
53 - );
54 - });
55 -
56 - it("should not throw for valid values", function() {
57 - expect(typeCheck(Props.array, [])).not.toThrow();
58 - expect(typeCheck(Props.bool, false)).not.toThrow();
59 - expect(typeCheck(Props.number, 0)).not.toThrow();
60 - expect(typeCheck(Props.object, {})).not.toThrow();
61 - expect(typeCheck(Props.string, '')).not.toThrow();
62 - });
63 -
64 - it("should be implicitly optional and not throw without values", function() {
65 - expect(typeCheck(Props.string, null)).not.toThrow();
66 - expect(typeCheck(Props.string, undefined)).not.toThrow();
67 - });
68 -
69 - it("should throw for missing required values", function() {
70 - expect(typeCheck(Props.string.isRequired, null)).toThrow(
71 - 'Invariant Violation: Required prop `testProp` was not specified in ' +
72 - '`testComponent`.'
73 - );
74 - expect(typeCheck(Props.string.isRequired, undefined)).toThrow(
75 - 'Invariant Violation: Required prop `testProp` was not specified in ' +
76 - '`testComponent`.'
77 - );
78 - });
79 -});
80 -
81 -describe('Enum Types', function() {
82 - beforeEach(function() {
83 - require("../../mock-modules").dumpCache();
84 - });
85 -
86 - it("should throw for invalid strings", function() {
87 - expect(typeCheck(Props.oneOf(['red', 'blue']), true)).toThrow(
88 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
89 - '`testComponent`, expected one of ["blue","red"].'
90 - );
91 - expect(typeCheck(Props.oneOf(['red', 'blue']), [])).toThrow(
92 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
93 - '`testComponent`, expected one of ["blue","red"].'
94 - );
95 - expect(typeCheck(Props.oneOf(['red', 'blue']), '')).toThrow(
96 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
97 - '`testComponent`, expected one of ["blue","red"].'
98 - );
99 - });
100 -
101 - it("should not throw for valid values", function() {
102 - expect(typeCheck(Props.oneOf(['red', 'blue']), 'red')).not.toThrow();
103 - expect(typeCheck(Props.oneOf(['red', 'blue']), 'blue')).not.toThrow();
104 - });
105 -
106 - it("should be implicitly optional and not throw without values", function() {
107 - expect(typeCheck(Props.oneOf(['red', 'blue']), null)).not.toThrow();
108 - expect(typeCheck(Props.oneOf(['red', 'blue']), undefined)).not.toThrow();
109 - });
110 -});
111 -
112 -describe('Instance Types', function() {
113 - beforeEach(function() {
114 - require("../../mock-modules").dumpCache();
115 - });
116 -
117 - it("should throw for invalid instances", function() {
118 - function Person() {}
119 -
120 - expect(typeCheck(Props.instanceOf(Person), false)).toThrow(
121 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
122 - '`testComponent`, expected instance of `Person`.'
123 - );
124 - expect(typeCheck(Props.instanceOf(Person), {})).toThrow(
125 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
126 - '`testComponent`, expected instance of `Person`.'
127 - );
128 - expect(typeCheck(Props.instanceOf(Person), '')).toThrow(
129 - 'Invariant Violation: Invalid prop `testProp` supplied to ' +
130 - '`testComponent`, expected instance of `Person`.'
131 - );
132 - });
133 -
134 - it("should not throw for valid values", function() {
135 - function Person() {}
136 - function Engineer() {}
137 - Engineer.prototype = new Person();
138 -
139 - expect(typeCheck(Props.instanceOf(Person), new Person())).not.toThrow();
140 - expect(typeCheck(Props.instanceOf(Person), new Engineer())).not.toThrow();
141 - });
142 -});
React/core/__tests__/ReactStateSetters-test.js deleted
-162
@@ -1,162 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -var React = require("../../React");
23 -var ReactStateSetters = require("../../ReactStateSetters");
24 -var ReactTestUtils = require("../../ReactTestUtils");
25 -
26 -var TestComponent;
27 -var TestComponentWithMixin;
28 -
29 -describe('ReactStateSetters', function() {
30 - beforeEach(function() {
31 - require("../../mock-modules").dumpCache();
32 -
33 - TestComponent = React.createClass({
34 - getInitialState: function() {
35 - return {foo: 'foo'};
36 - },
37 -
38 - render: function() {
39 - return React.DOM.div(null, null );
40 - }
41 - });
42 -
43 - TestComponentWithMixin = React.createClass({
44 - mixins: [ReactStateSetters.Mixin],
45 -
46 - getInitialState: function() {
47 - return {foo: 'foo'};
48 - },
49 -
50 - render: function() {
51 - return React.DOM.div(null, null );
52 - }
53 - });
54 - });
55 -
56 - it('createStateSetter should update state', function() {
57 - var instance = TestComponent(null, null );
58 - ReactTestUtils.renderIntoDocument(instance);
59 - expect(instance.state).toEqual({foo: 'foo'});
60 -
61 - var setter = ReactStateSetters.createStateSetter(
62 - instance,
63 - function(a, b, c) {
64 - return {
65 - foo: a + b + c,
66 - bar: a * b * c
67 - };
68 - }
69 - );
70 - expect(instance.state).toEqual({foo: 'foo'});
71 -
72 - setter(1, 2, 3);
73 - expect(instance.state).toEqual({foo: 6, bar: 6});
74 -
75 - setter(10, 11, 12);
76 - expect(instance.state).toEqual({foo: 33, bar: 1320});
77 - });
78 -
79 - it('createStateKeySetter should update state', function() {
80 - var instance = TestComponent(null, null );
81 - ReactTestUtils.renderIntoDocument(instance);
82 - expect(instance.state).toEqual({foo: 'foo'});
83 -
84 - var setter = ReactStateSetters.createStateKeySetter(instance, 'foo');
85 -
86 - expect(instance.state).toEqual({foo: 'foo'});
87 -
88 - setter('bar');
89 - expect(instance.state).toEqual({foo: 'bar'});
90 -
91 - setter('baz');
92 - expect(instance.state).toEqual({foo: 'baz'});
93 - });
94 -
95 - it('createStateKeySetter is memoized', function() {
96 - var instance = TestComponent(null, null );
97 - ReactTestUtils.renderIntoDocument(instance);
98 - expect(instance.state).toEqual({foo: 'foo'});
99 -
100 - var foo1 = ReactStateSetters.createStateKeySetter(instance, 'foo');
101 - var bar1 = ReactStateSetters.createStateKeySetter(instance, 'bar');
102 -
103 - var foo2 = ReactStateSetters.createStateKeySetter(instance, 'foo');
104 - var bar2 = ReactStateSetters.createStateKeySetter(instance, 'bar');
105 -
106 - expect(foo2).toBe(foo1);
107 - expect(bar2).toBe(bar1);
108 - });
109 -
110 - it('createStateSetter should update state from mixin', function() {
111 - var instance = TestComponentWithMixin(null, null );
112 - ReactTestUtils.renderIntoDocument(instance);
113 - expect(instance.state).toEqual({foo: 'foo'});
114 -
115 - var setter = instance.createStateSetter(
116 - function(a, b, c) {
117 - return {
118 - foo: a + b + c,
119 - bar: a * b * c
120 - };
121 - }
122 - );
123 - expect(instance.state).toEqual({foo: 'foo'});
124 -
125 - setter(1, 2, 3);
126 - expect(instance.state).toEqual({foo: 6, bar: 6});
127 -
128 - setter(10, 11, 12);
129 - expect(instance.state).toEqual({foo: 33, bar: 1320});
130 - });
131 -
132 - it('createStateKeySetter should update state with mixin', function() {
133 - var instance = TestComponentWithMixin(null, null );
134 - ReactTestUtils.renderIntoDocument(instance);
135 - expect(instance.state).toEqual({foo: 'foo'});
136 -
137 - var setter = instance.createStateKeySetter('foo');
138 -
139 - expect(instance.state).toEqual({foo: 'foo'});
140 -
141 - setter('bar');
142 - expect(instance.state).toEqual({foo: 'bar'});
143 -
144 - setter('baz');
145 - expect(instance.state).toEqual({foo: 'baz'});
146 - });
147 -
148 - it('createStateKeySetter is memoized with mixin', function() {
149 - var instance = TestComponentWithMixin(null, null );
150 - ReactTestUtils.renderIntoDocument(instance);
151 - expect(instance.state).toEqual({foo: 'foo'});
152 -
153 - var foo1 = instance.createStateKeySetter('foo');
154 - var bar1 = instance.createStateKeySetter('bar');
155 -
156 - var foo2 = instance.createStateKeySetter('foo');
157 - var bar2 = instance.createStateKeySetter('bar');
158 -
159 - expect(foo2).toBe(foo1);
160 - expect(bar2).toBe(bar1);
161 - });
162 -});
React/core/__tests__/refs-destruction-test.js
React/core/__tests__/refs-test.js
React/createObjectFrom.js deleted
-63
@@ -1,63 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule createObjectFrom
17 - */
18 -
19 -var hasArrayNature = require("./hasArrayNature");
20 -
21 -/**
22 - * Construct an object from an array of keys
23 - * and optionally specified value or list of values.
24 - *
25 - * >>> createObjectFrom(['a','b','c']);
26 - * {a: true, b: true, c: true}
27 - *
28 - * >>> createObjectFrom(['a','b','c'], false);
29 - * {a: false, b: false, c: false}
30 - *
31 - * >>> createObjectFrom(['a','b','c'], 'monkey');
32 - * {c:'monkey', b:'monkey' c:'monkey'}
33 - *
34 - * >>> createObjectFrom(['a','b','c'], [1,2,3]);
35 - * {a: 1, b: 2, c: 3}
36 - *
37 - * >>> createObjectFrom(['women', 'men'], [true, false]);
38 - * {women: true, men: false}
39 - *
40 - * @param Array list of keys
41 - * @param mixed optional value or value array. defaults true.
42 - * @returns object
43 - */
44 -function createObjectFrom(keys, values /* = true */) {
45 - if (true) {
46 - if (!hasArrayNature(keys)) {
47 - throw new TypeError('Must pass an array of keys.');
48 - }
49 - }
50 -
51 - var object = {};
52 - var is_array = hasArrayNature(values);
53 - if (typeof values == 'undefined') {
54 - values = true;
55 - }
56 -
57 - for (var ii = keys.length; ii--;) {
58 - object[keys[ii]] = is_array ? values[ii] : values;
59 - }
60 - return object;
61 -}
62 -
63 -module.exports = createObjectFrom;
React/cx.js deleted
-44
@@ -1,44 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule cx
17 - */
18 -
19 -/**
20 - * This function is used to mark string literals representing CSS class names
21 - * so that they can be transformed statically. This allows for modularization
22 - * and minification of CSS class names.
23 - *
24 - * In static_upstream, this function is actually implemented, but it should
25 - * eventually be replaced with something more descriptive, and the transform
26 - * that is used in the main stack should be ported for use elsewhere.
27 - *
28 - * @param string|object className to modularize, or an object of key/values.
29 - * In the object case, the values are conditions that
30 - * determine if the className keys should be included.
31 - * @param [string ...] Variable list of classNames in the string case.
32 - * @return string Renderable space-separated CSS className.
33 - */
34 -function cx(classNames) {
35 - if (typeof classNames == 'object') {
36 - return Object.keys(classNames).map(function(className) {
37 - return classNames[className] ? className : '';
38 - }).join(' ');
39 - } else {
40 - return Array.prototype.join.call(arguments, ' ');
41 - }
42 -}
43 -
44 -module.exports = cx;
React/dangerousStyleValue.js deleted
-51
@@ -1,51 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule dangerousStyleValue
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var CSSProperty = require("./CSSProperty");
23 -
24 -/**
25 - * Convert a value into the proper css writable value. The `styleName` name
26 - * name should be logical (no hyphens), as specified in `CSSProperty.isNumber`.
27 - *
28 - * @param {string} styleName CSS property name such as `topMargin`.
29 - * @param {*} value CSS property value such as `10px`.
30 - * @return {string} Normalized style value with dimensions applied.
31 - */
32 -function dangerousStyleValue(styleName, value) {
33 - // Note that we've removed escapeTextForBrowser() calls here since the
34 - // whole string will be escaped when the attribute is injected into
35 - // the markup. If you provide unsafe user data here they can inject
36 - // arbitrary CSS which may be problematic (I couldn't repro this):
37 - // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
38 - // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
39 - // This is not an XSS hole but instead a potential CSS injection issue
40 - // which has lead to a greater discussion about how we're going to
41 - // trust URLs moving forward. See #2115901
42 - if (value === null || value === false || value === true || value === '') {
43 - return '';
44 - }
45 - if (isNaN(value)) {
46 - return !value ? '' : '' + value;
47 - }
48 - return CSSProperty.isNumber[styleName] ? '' + value : (value + 'px');
49 -}
50 -
51 -module.exports = dangerousStyleValue;
React/dom/__tests__/CSSPropertyOperations-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: dom/__tests__/CSSPropertyOperations-test");
\ No newline at end of file
React/dom/__tests__/DOMPropertyOperations-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: dom/__tests__/DOMPropertyOperations-test");
\ No newline at end of file
React/domUtils/__tests__/CSSPropertyOperations-test.js deleted
-52
@@ -1,52 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -describe('CSSPropertyOperations', function() {
23 - var CSSPropertyOperations;
24 -
25 - beforeEach(function() {
26 - require("../../mock-modules").dumpCache();
27 - CSSPropertyOperations = require("../../CSSPropertyOperations");
28 - });
29 -
30 - it('should create markup for simple styles', function() {
31 - expect(CSSPropertyOperations.createMarkupForStyles({
32 - backgroundColor: '#3b5998',
33 - display: 'none'
34 - })).toBe('background-color:#3b5998;display:none;');
35 - });
36 -
37 - it('should ignore undefined styles', function() {
38 - expect(CSSPropertyOperations.createMarkupForStyles({
39 - backgroundColor: undefined,
40 - display: 'none'
41 - })).toBe('display:none;');
42 - });
43 -
44 - it('should automatically append `px` to relevant styles', function() {
45 - expect(CSSPropertyOperations.createMarkupForStyles({
46 - margin: 16,
47 - opacity: 0.5,
48 - padding: '4px'
49 - })).toBe('margin:16px;opacity:0.5;padding:4px;');
50 - });
51 -
52 -});
React/domUtils/__tests__/DOMPropertyOperations-test.js deleted
-129
@@ -1,129 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @jsx React.DOM
17 - * @emails react-core
18 - */
19 -
20 -"use strict";
21 -
22 -describe('DOMPropertyOperations', function() {
23 - var DOMPropertyOperations;
24 -
25 - beforeEach(function() {
26 - require("../../mock-modules").dumpCache();
27 - DOMPropertyOperations = require("../../DOMPropertyOperations");
28 - });
29 -
30 - describe('createMarkupForProperty', function() {
31 -
32 - it('should create markup for simple properties', function() {
33 - expect(DOMPropertyOperations.createMarkupForProperty(
34 - 'name',
35 - 'simple'
36 - )).toBe('name="simple"');
37 -
38 - expect(DOMPropertyOperations.createMarkupForProperty(
39 - 'name',
40 - false
41 - )).toBe('name="false"');
42 -
43 - expect(DOMPropertyOperations.createMarkupForProperty(
44 - 'name',
45 - null
46 - )).toBe('');
47 - });
48 -
49 - it('should create markup for boolean properties', function() {
50 - expect(DOMPropertyOperations.createMarkupForProperty(
51 - 'checked',
52 - 'simple'
53 - )).toBe('checked="simple"');
54 -
55 - expect(DOMPropertyOperations.createMarkupForProperty(
56 - 'checked',
57 - true
58 - )).toBe('checked="true"');
59 -
60 - expect(DOMPropertyOperations.createMarkupForProperty(
61 - 'checked',
62 - false
63 - )).toBe('');
64 - });
65 -
66 - it('should create markup for custom attributes', function() {
67 - expect(DOMPropertyOperations.createMarkupForProperty(
68 - 'aria-label',
69 - 'simple'
70 - )).toBe('aria-label="simple"');
71 -
72 - expect(DOMPropertyOperations.createMarkupForProperty(
73 - 'aria-label',
74 - false
75 - )).toBe('aria-label="false"');
76 -
77 - expect(DOMPropertyOperations.createMarkupForProperty(
78 - 'aria-label',
79 - null
80 - )).toBe('');
81 - });
82 -
83 - });
84 -
85 - describe('setValueForProperty', function() {
86 - var stubNode;
87 -
88 - beforeEach(function() {
89 - stubNode = document.createElement('div');
90 - });
91 -
92 - it('should set values as properties by default', function() {
93 - DOMPropertyOperations.setValueForProperty(stubNode, 'title', 'Tip!');
94 - expect(stubNode.title).toBe('Tip!');
95 - });
96 -
97 - it('should set values as attributes if necessary', function() {
98 - DOMPropertyOperations.setValueForProperty(stubNode, 'ajaxify', '#');
99 - expect(stubNode.getAttribute('ajaxify')).toBe('#');
100 - expect(stubNode.ajaxify).toBeUndefined();
101 - });
102 -
103 - it('should remove for falsey boolean properties', function() {
104 - DOMPropertyOperations.setValueForProperty(
105 - stubNode,
106 - 'allowFullScreen',
107 - false
108 - );
109 - expect(stubNode.hasAttribute('allowFullScreen')).toBe(false);
110 - });
111 -
112 - it('should use mutation method where applicable', function() {
113 - DOMPropertyOperations.setValueForProperty(
114 - stubNode,
115 - 'className',
116 - 'selected'
117 - );
118 - expect(stubNode.className).toBe('selected');
119 -
120 - DOMPropertyOperations.setValueForProperty(
121 - stubNode,
122 - 'className',
123 - null
124 - );
125 - expect(stubNode.className).toBe('');
126 - });
127 -
128 - });
129 -});
React/emptyFunction.js deleted
-50
@@ -1,50 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule emptyFunction
17 - */
18 -
19 -var copyProperties = require("./copyProperties");
20 -
21 -function makeEmptyFunction(arg) {
22 - return function() {
23 - return arg;
24 - };
25 -}
26 -
27 -/**
28 - * This function accepts and discards inputs; it has no side effects. This is
29 - * primarily useful idiomatically for overridable function endpoints which
30 - * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
31 - */
32 -function emptyFunction() {}
33 -
34 -copyProperties(emptyFunction, {
35 - thatReturns: makeEmptyFunction,
36 - thatReturnsFalse: makeEmptyFunction(false),
37 - thatReturnsTrue: makeEmptyFunction(true),
38 - thatReturnsNull: makeEmptyFunction(null),
39 - thatReturnsThis: function() { return this; },
40 - thatReturnsArgument: function(arg) { return arg; },
41 - mustImplement: function(module, property) {
42 - return function() {
43 - if (true) {
44 - throw new Error(module + '.' + property + ' must be implemented!');
45 - }
46 - };
47 - }
48 -});
49 -
50 -module.exports = emptyFunction;
React/environment/__tests__/ReactServerRendering-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: environment/__tests__/ReactServerRendering-test");
\ No newline at end of file
React/erx.js deleted
-71
@@ -1,71 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule erx
17 - * @typechecks
18 - * @nostacktrace
19 - */
20 -
21 -var ex = require("./ex");
22 -
23 -/**
24 - * This function reverse transform done by `ex()`.
25 - *
26 - * This function only transforms plain text message back to error message with
27 - * arguments. If the error message is minified by the server, it has to be
28 - * looked up on the server.
29 - *
30 - * This function is designed to be idempotent, so erx(erx(whatever)) will be
31 - * the same as erx(whatever).
32 - *
33 - * @param {string|array<string>} transformedMessage
34 - */
35 -
36 -var erx = function(transformedMessage) {
37 - if (typeof transformedMessage !== 'string') {
38 - // possibly double `erx`ed and return original value
39 - return transformedMessage;
40 - }
41 -
42 - var prefixLeft = transformedMessage.indexOf(ex._prefix);
43 - var suffixLeft = transformedMessage.lastIndexOf(ex._suffix);
44 - if (prefixLeft < 0 || suffixLeft < 0) {
45 - // plain error message without any transformation
46 - return [transformedMessage];
47 - }
48 -
49 - var prefixRight = prefixLeft + ex._prefix.length;
50 - var suffixRight = suffixLeft + ex._suffix.length;
51 - if (prefixRight >= suffixLeft) {
52 - return ['erx slice failure: %s', transformedMessage];
53 - }
54 -
55 - var leftSlice = transformedMessage.substring(0, prefixLeft);
56 - var rightSlice = transformedMessage.substring(suffixRight);
57 - transformedMessage = transformedMessage.substring(prefixRight, suffixLeft);
58 -
59 - var messageWithParams;
60 - try {
61 - messageWithParams = JSON.parse(transformedMessage);
62 - messageWithParams[0] =
63 - leftSlice + messageWithParams[0] + rightSlice;
64 - } catch(err) {
65 - return ['erx parse failure: %s', transformedMessage];
66 - }
67 -
68 - return messageWithParams;
69 -};
70 -
71 -module.exports = erx;
React/escapeTextForBrowser.js deleted
-61
@@ -1,61 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule escapeTextForBrowser
17 - */
18 -
19 -"use strict";
20 -
21 -var throwIf = require("./throwIf");
22 -
23 -var ESCAPE_TYPE_ERR;
24 -
25 -if (true) {
26 - ESCAPE_TYPE_ERR =
27 - 'The React core has attempted to escape content that is of a ' +
28 - 'mysterious type (object etc) Escaping only works on numbers and strings';
29 -}
30 -
31 -var ESCAPE_LOOKUP = {
32 - "&": "&amp;",
33 - ">": "&gt;",
34 - "<": "&lt;",
35 - "\"": "&quot;",
36 - "'": "&#x27;",
37 - "/": "&#x2f;"
38 -};
39 -
40 -function escaper(match) {
41 - return ESCAPE_LOOKUP[match];
42 -}
43 -
44 -var escapeTextForBrowser = function (text) {
45 - var type = typeof text;
46 - var invalid = type === 'object';
47 - if (true) {
48 - throwIf(invalid, ESCAPE_TYPE_ERR);
49 - }
50 - if (text === '' || invalid) {
51 - return '';
52 - } else {
53 - if (type === 'string') {
54 - return text.replace(/[&><"'\/]/g, escaper);
55 - } else {
56 - return (''+text).replace(/[&><"'\/]/g, escaper);
57 - }
58 - }
59 -};
60 -
61 -module.exports = escapeTextForBrowser;
React/event/__tests__/EventPluginRegistry-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: event/__tests__/EventPluginRegistry-test");
\ No newline at end of file
React/event/synthetic/__tests__/SyntheticEvent-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: event/synthetic/__tests__/SyntheticEvent-test");
\ No newline at end of file
React/event/synthetic/__tests__/SyntheticWheelEvent-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: event/synthetic/__tests__/SyntheticWheelEvent-test");
\ No newline at end of file
React/eventPlugins/__tests__/AnalyticsEventPlugin-test.js
React/eventPlugins/__tests__/ResponderEventPlugin-test.js deleted
-501
@@ -1,501 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -var CallbackRegistry;
22 -var EventConstants;
23 -var EventPropagators;
24 -var ReactInstanceHandles;
25 -var ResponderEventPlugin;
26 -var AbstractEvent;
27 -
28 -var GRANDPARENT_ID = '.reactRoot[0]';
29 -var PARENT_ID = '.reactRoot[0].0';
30 -var CHILD_ID = '.reactRoot[0].0.0';
31 -
32 -var topLevelTypes;
33 -var responderAbstractEventTypes;
34 -var spies;
35 -
36 -var DUMMY_NATIVE_EVENT = {};
37 -var DUMMY_RENDERED_TARGET = {};
38 -
39 -var onStartShouldSetResponder = function(id, cb, capture) {
40 - var registrationNames = responderAbstractEventTypes
41 - .startShouldSetResponder
42 - .phasedRegistrationNames;
43 - CallbackRegistry.putListener(
44 - id,
45 - capture ? registrationNames.captured : registrationNames.bubbled,
46 - cb
47 - );
48 -};
49 -
50 -var onScrollShouldSetResponder = function(id, cb, capture) {
51 - var registrationNames = responderAbstractEventTypes
52 - .scrollShouldSetResponder
53 - .phasedRegistrationNames;
54 - CallbackRegistry.putListener(
55 - id,
56 - capture ? registrationNames.captured : registrationNames.bubbled,
57 - cb
58 - );
59 -};
60 -
61 -var onMoveShouldSetResponder = function(id, cb, capture) {
62 - var registrationNames = responderAbstractEventTypes
63 - .moveShouldSetResponder
64 - .phasedRegistrationNames;
65 - CallbackRegistry.putListener(
66 - id,
67 - capture ? registrationNames.captured : registrationNames.bubbled,
68 - cb
69 - );
70 -};
71 -
72 -
73 -var onResponderGrant = function(id, cb) {
74 - CallbackRegistry.putListener(
75 - id,
76 - responderAbstractEventTypes.responderGrant.registrationName,
77 - cb
78 - );
79 -};
80 -
81 -var extractForTouchStart = function(renderedTargetID) {
82 - return ResponderEventPlugin.extractAbstractEvents(
83 - topLevelTypes.topTouchStart,
84 - DUMMY_NATIVE_EVENT,
85 - renderedTargetID,
86 - DUMMY_RENDERED_TARGET
87 - );
88 -};
89 -
90 -var extractForTouchMove = function(renderedTargetID) {
91 - return ResponderEventPlugin.extractAbstractEvents(
92 - topLevelTypes.topTouchMove,
93 - DUMMY_NATIVE_EVENT,
94 - renderedTargetID,
95 - DUMMY_RENDERED_TARGET
96 - );
97 -};
98 -
99 -var extractForTouchEnd = function(renderedTargetID) {
100 - return ResponderEventPlugin.extractAbstractEvents(
101 - topLevelTypes.topTouchEnd,
102 - DUMMY_NATIVE_EVENT,
103 - renderedTargetID,
104 - DUMMY_RENDERED_TARGET
105 - );
106 -};
107 -
108 -var extractForMouseDown = function(renderedTargetID) {
109 - return ResponderEventPlugin.extractAbstractEvents(
110 - topLevelTypes.topMouseDown,
111 - DUMMY_NATIVE_EVENT,
112 - renderedTargetID,
113 - DUMMY_RENDERED_TARGET
114 - );
115 -};
116 -
117 -var extractForMouseMove = function(renderedTargetID) {
118 - return ResponderEventPlugin.extractAbstractEvents(
119 - topLevelTypes.topMouseMove,
120 - DUMMY_NATIVE_EVENT,
121 - renderedTargetID,
122 - DUMMY_RENDERED_TARGET
123 - );
124 -};
125 -
126 -
127 -var extractForMouseUp = function(renderedTargetID) {
128 - return ResponderEventPlugin.extractAbstractEvents(
129 - topLevelTypes.topMouseUp,
130 - DUMMY_NATIVE_EVENT,
131 - renderedTargetID,
132 - DUMMY_RENDERED_TARGET
133 - );
134 -};
135 -
136 -var extractForScroll = function(renderedTargetID) {
137 - return ResponderEventPlugin.extractAbstractEvents(
138 - topLevelTypes.topScroll,
139 - DUMMY_NATIVE_EVENT,
140 - renderedTargetID,
141 - DUMMY_RENDERED_TARGET
142 - );
143 -};
144 -
145 -
146 -var onGrantChild;
147 -var onGrantParent;
148 -var onGrantGrandParent;
149 -
150 -
151 -var existsInExtraction = function(extracted, test) {
152 - if (Array.isArray(extracted)) {
153 - for (var i = 0; i < extracted.length; i++) {
154 - if (test(extracted[i])) {
155 - return true;
156 - }
157 - }
158 - } else if (extracted) {
159 - return test(extracted);
160 - }
161 - return false;
162 -};
163 -
164 -/**
165 - * Helper validators.
166 - */
167 -function assertGrantEvent(id, extracted) {
168 - var test = function(abstractEvent) {
169 - return abstractEvent instanceof AbstractEvent &&
170 - abstractEvent.type === responderAbstractEventTypes.responderGrant &&
171 - abstractEvent.abstractTargetID === id;
172 - };
173 - expect(ResponderEventPlugin.getResponderID()).toBe(id);
174 - expect(existsInExtraction(extracted, test)).toBe(true);
175 -}
176 -
177 -function assertResponderMoveEvent(id, extracted) {
178 - var test = function(abstractEvent) {
179 - return abstractEvent instanceof AbstractEvent &&
180 - abstractEvent.type === responderAbstractEventTypes.responderMove &&
181 - abstractEvent.abstractTargetID === id;
182 - };
183 - expect(ResponderEventPlugin.getResponderID()).toBe(id);
184 - expect(existsInExtraction(extracted, test)).toBe(true);
185 -}
186 -
187 -function assertTerminateEvent(id, extracted) {
188 - var test = function(abstractEvent) {
189 - return abstractEvent instanceof AbstractEvent &&
190 - abstractEvent.type === responderAbstractEventTypes.responderTerminate &&
191 - abstractEvent.abstractTargetID === id;
192 - };
193 - expect(ResponderEventPlugin.getResponderID()).not.toBe(id);
194 - expect(existsInExtraction(extracted, test)).toBe(true);
195 -}
196 -
197 -function assertRelease(id, extracted) {
198 - var test = function(abstractEvent) {
199 - return abstractEvent instanceof AbstractEvent &&
200 - abstractEvent.type === responderAbstractEventTypes.responderRelease &&
201 - abstractEvent.abstractTargetID === id;
202 - };
203 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
204 - expect(existsInExtraction(extracted, test)).toBe(true);
205 -}
206 -
207 -
208 -function assertNothingExtracted(extracted) {
209 - expect(Array.isArray(extracted)).toBe(false); // No grant events.
210 - expect(Array.isArray(extracted)).toBeFalsy();
211 -}
212 -
213 -
214 -/**
215 - * TODO:
216 - * - Test that returning false from `responderTerminationRequest` will never
217 - * cause the responder to be lost.
218 - * - Automate some of this testing by providing config data - generalize.
219 - */
220 -
221 -describe('ResponderEventPlugin', function() {
222 - beforeEach(function() {
223 - require("../../mock-modules").dumpCache();
224 -
225 - AbstractEvent = require("../../AbstractEvent");
226 - CallbackRegistry = require("../../CallbackRegistry");
227 - EventConstants = require("../../EventConstants");
228 - EventPropagators = require("../../EventPropagators");
229 - ReactInstanceHandles = require("../../ReactInstanceHandles");
230 - ResponderEventPlugin = require("../../ResponderEventPlugin");
231 - EventPropagators.injection.injectInstanceHandle(ReactInstanceHandles);
232 -
233 - // dumpCache, in open-source tests, only resets existing mocks. It does not
234 - // reset module-state though -- so we need to do this explicitly in the test
235 - // for now. Once that's no longer the case, we can delete this line.
236 - CallbackRegistry.__purge();
237 -
238 - topLevelTypes = EventConstants.topLevelTypes;
239 - responderAbstractEventTypes = ResponderEventPlugin.abstractEventTypes;
240 -
241 - spies = {
242 - onStartShouldSetResponderChild: function() {},
243 - onStartShouldSetResponderParent: function() {},
244 - onStartShouldSetResponderParentCapture: function() {},
245 - onStartShouldSetResponderGrandParent: function() {},
246 - onMoveShouldSetResponderParent: function() {},
247 - onScrollShouldSetResponderParent: function() {}
248 - };
249 -
250 - onGrantChild = function() {};
251 - onGrantParent = function() {};
252 - onGrantGrandParent = function() {};
253 - });
254 -
255 - it('should not auto-set responder on touch start', function() {
256 - // Notice we're not registering the startShould* handler.
257 - var extracted = extractForTouchStart(CHILD_ID);
258 - assertNothingExtracted(extracted);
259 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
260 - });
261 -
262 - it('should not auto-set responder on mouse down', function() {
263 - // Notice we're not registering the startShould* handler.
264 - var extracted = extractForMouseDown(CHILD_ID);
265 - assertNothingExtracted(extracted);
266 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
267 - extractForMouseUp(CHILD_ID); // Let up!
268 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
269 -
270 - // Register `onMoveShould*` handler.
271 - spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);
272 - onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);
273 - onResponderGrant(PARENT_ID, onGrantParent);
274 - // Move mouse while not pressing down
275 - extracted = extractForMouseMove(CHILD_ID);
276 - assertNothingExtracted(extracted);
277 - // Not going to call `onMoveShould`* if not touching.
278 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0);
279 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
280 -
281 - // Now try the move extraction again, this time while holding down, and not
282 - // letting up.
283 - extracted = extractForMouseDown(CHILD_ID);
284 - assertNothingExtracted(extracted);
285 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
286 -
287 - // Now moving can set the responder, if pressing down, even if there is no
288 - // current responder.
289 - extracted = extractForMouseMove(CHILD_ID);
290 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);
291 - expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);
292 - assertGrantEvent(PARENT_ID, extracted);
293 -
294 - extractForMouseUp(CHILD_ID);
295 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
296 - });
297 -
298 - it('should not extract a grant/release event if double start', function() {
299 - // Return true - we should become the responder.
300 - var extracted;
301 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
302 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
303 - onResponderGrant(CHILD_ID, onGrantChild);
304 -
305 - extracted = extractForTouchStart(CHILD_ID);
306 - assertGrantEvent(CHILD_ID, extracted);
307 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
308 -
309 - // Now we do *not* clear out the touch via a simulated touch end. This mocks
310 - // out an environment that likely will never happen, but could in some odd
311 - // error state so it's nice to make sure we recover gracefully.
312 - // extractForTouchEnd(CHILD_ID); // Clear the responder
313 - extracted = extractForTouchStart(CHILD_ID);
314 - assertNothingExtracted();
315 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);
316 - });
317 -
318 - it('should bubble/capture responder on start', function() {
319 - // Return true - we should become the responder.
320 - var extracted;
321 - spyOn(spies, 'onStartShouldSetResponderParent').andReturn(true);
322 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
323 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
324 - onStartShouldSetResponder(PARENT_ID, spies.onStartShouldSetResponderParent);
325 - onResponderGrant(CHILD_ID, onGrantChild);
326 - onResponderGrant(PARENT_ID, onGrantParent);
327 -
328 - // Nothing extracted if no responder.
329 - extracted = extractForTouchMove(GRANDPARENT_ID);
330 - assertNothingExtracted(extracted);
331 -
332 - extracted = extractForTouchStart(CHILD_ID);
333 - assertGrantEvent(CHILD_ID, extracted);
334 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
335 - expect(spies.onStartShouldSetResponderParent.callCount).toBe(0);
336 -
337 - // Even if moving on the grandparent, the child will receive responder moves
338 - // (This is even true for mouse interactions - which we should absolutely
339 - // test)
340 - extracted = extractForTouchMove(GRANDPARENT_ID);
341 - assertResponderMoveEvent(CHILD_ID, extracted);
342 - extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.
343 - assertResponderMoveEvent(CHILD_ID, extracted);
344 -
345 - // Reset the responder - id passed here shouldn't matter:
346 - // TODO: Test varying the id here.
347 - extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder
348 - assertRelease(CHILD_ID, extracted);
349 -
350 - // Now make sure the parent requests responder on capture.
351 - spyOn(spies, 'onStartShouldSetResponderParentCapture').andReturn(true);
352 - onStartShouldSetResponder(
353 - PARENT_ID,
354 - spies.onStartShouldSetResponderParent,
355 - true // Capture
356 - );
357 - onResponderGrant(PARENT_ID, onGrantGrandParent);
358 - extracted = extractForTouchStart(PARENT_ID);
359 - expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);
360 - assertGrantEvent(PARENT_ID, extracted);
361 - // Now move on various nodes, ensuring that the responder move is emitted to
362 - // the parent node.
363 - extracted = extractForTouchMove(GRANDPARENT_ID);
364 - assertResponderMoveEvent(PARENT_ID, extracted);
365 - extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.
366 - assertResponderMoveEvent(PARENT_ID, extracted);
367 -
368 - // Reset the responder - id passed here shouldn't matter:
369 - // TODO: Test varying the id here.
370 - extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder
371 - assertRelease(PARENT_ID, extracted);
372 -
373 - });
374 -
375 - it('should invoke callback to ask if responder is desired', function() {
376 - // Return true - we should become the responder.
377 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
378 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
379 -
380 - var extracted = extractForTouchStart(CHILD_ID);
381 - assertNothingExtracted(extracted);
382 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
383 - expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);
384 - extractForTouchEnd(CHILD_ID); // Clear the responder
385 -
386 - // Now try returning false - we should not become the responder.
387 - spies.onStartShouldSetResponderChild.andReturn(false);
388 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
389 - extracted = extractForTouchStart(CHILD_ID);
390 - assertNothingExtracted(extracted);
391 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);
392 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
393 - extractForTouchEnd(CHILD_ID);
394 - expect(ResponderEventPlugin.getResponderID()).toBe(null); // Still null
395 -
396 - // Same thing as before but return true from "shouldSet".
397 - spies.onStartShouldSetResponderChild.andReturn(true);
398 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
399 - onResponderGrant(CHILD_ID, onGrantChild);
400 - extracted = extractForTouchStart(CHILD_ID);
401 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);
402 - assertGrantEvent(CHILD_ID, extracted);
403 - extracted = extractForTouchEnd(CHILD_ID); // Clear the responder
404 - assertRelease(CHILD_ID, extracted);
405 - });
406 -
407 - it('should give up responder to parent on move iff allowed', function() {
408 - // Return true - we should become the responder.
409 - var extracted;
410 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
411 - spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);
412 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
413 - onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);
414 - onResponderGrant(CHILD_ID, onGrantChild);
415 - onResponderGrant(PARENT_ID, onGrantParent);
416 -
417 - spies.onStartShouldSetResponderChild.andReturn(true);
418 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
419 - extracted = extractForTouchStart(CHILD_ID);
420 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
421 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet
422 - assertGrantEvent(CHILD_ID, extracted); // Child is the current responder
423 -
424 - extracted = extractForTouchMove(CHILD_ID);
425 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);
426 - assertGrantEvent(PARENT_ID, extracted);
427 - assertTerminateEvent(CHILD_ID, extracted);
428 -
429 - extracted = extractForTouchEnd(CHILD_ID); // Clear the responder
430 - assertRelease(PARENT_ID, extracted);
431 - });
432 -
433 - it('should responder move only on direct responder', function() {
434 - // Return true - we should become the responder.
435 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
436 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
437 -
438 - var extracted = extractForTouchStart(CHILD_ID);
439 - assertNothingExtracted(extracted);
440 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
441 - expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);
442 - extractForTouchEnd(CHILD_ID); // Clear the responder
443 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
444 -
445 - // Now try returning false - we should not become the responder.
446 - spies.onStartShouldSetResponderChild.andReturn(false);
447 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
448 - extracted = extractForTouchStart(CHILD_ID);
449 - assertNothingExtracted(extracted);
450 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);
451 - expect(ResponderEventPlugin.getResponderID()).toBe(null);
452 - extractForTouchEnd(CHILD_ID); // Clear the responder
453 -
454 - // Same thing as before but return true from "shouldSet".
455 - spies.onStartShouldSetResponderChild.andReturn(true);
456 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
457 - onResponderGrant(CHILD_ID, onGrantChild);
458 - extracted = extractForTouchStart(CHILD_ID);
459 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);
460 - assertGrantEvent(CHILD_ID, extracted);
461 - extracted = extractForTouchEnd(CHILD_ID); // Clear the responder
462 - assertRelease(CHILD_ID, extracted);
463 - });
464 -
465 - it('should give up responder to parent on scroll iff allowed', function() {
466 - // Return true - we should become the responder.
467 - var extracted;
468 - spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);
469 - spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(false);
470 - spyOn(spies, 'onScrollShouldSetResponderParent').andReturn(true);
471 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
472 - onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);
473 - onScrollShouldSetResponder(
474 - PARENT_ID,
475 - spies.onScrollShouldSetResponderParent
476 - );
477 - onResponderGrant(CHILD_ID, onGrantChild);
478 - onResponderGrant(PARENT_ID, onGrantParent);
479 -
480 - spies.onStartShouldSetResponderChild.andReturn(true);
481 - onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);
482 - extracted = extractForTouchStart(CHILD_ID);
483 - expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);
484 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet
485 - assertGrantEvent(CHILD_ID, extracted); // Child is the current responder
486 -
487 - extracted = extractForTouchMove(CHILD_ID);
488 - expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);
489 - assertNothingExtracted(extracted);
490 -
491 - extracted = extractForScroll(CHILD_ID); // Could have been parent here too.
492 - expect(spies.onScrollShouldSetResponderParent.callCount).toBe(1);
493 - assertGrantEvent(PARENT_ID, extracted);
494 - assertTerminateEvent(CHILD_ID, extracted);
495 -
496 - extracted = extractForTouchEnd(CHILD_ID); // Clear the responder
497 - assertRelease(PARENT_ID, extracted);
498 - });
499 -
500 -
501 -});
React/ex.js deleted
-49
@@ -1,49 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ex
17 - * @typechecks
18 - * @nostacktrace
19 - */
20 -
21 -/**
22 - * This function transforms error message with arguments into plain text error
23 - * message, so that it can be passed to window.onerror without losing anything.
24 - * It can then be transformed back by `erx()` function.
25 - *
26 - * Usage:
27 - * throw new Error(ex('Error %s from %s', errorCode, userID));
28 - *
29 - * @param {string} errorMessage
30 - */
31 -
32 -var ex = function(errorMessage/*, arg1, arg2, ...*/) {
33 - var args = Array.prototype.slice.call(arguments).map(function(arg) {
34 - return String(arg);
35 - });
36 - var expectedLength = errorMessage.split('%s').length - 1;
37 -
38 - if (expectedLength !== args.length - 1) {
39 - // something wrong with the formatting string
40 - return ex('ex args number mismatch: %s', JSON.stringify(args));
41 - }
42 -
43 - return ex._prefix + JSON.stringify(args) + ex._suffix;
44 -};
45 -
46 -ex._prefix = '<![EX[';
47 -ex._suffix = ']]>';
48 -
49 -module.exports = ex;
React/flattenChildren.js deleted
-93
@@ -1,93 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule flattenChildren
17 - */
18 -
19 -"use strict";
20 -
21 -var ReactTextComponent = require("./ReactTextComponent");
22 -
23 -var escapeTextForBrowser = require("./escapeTextForBrowser");
24 -
25 -var throwIf = require("./throwIf");
26 -
27 -/**
28 - * @polyFill Array.isArray
29 - */
30 -
31 -
32 -var INVALID_CHILD = 'INVALID_CHILD';
33 -if (true) {
34 - INVALID_CHILD =
35 - 'You may not pass a child of that type to a React component. It ' +
36 - 'is a common mistake to try to pass a standard browser DOM element ' +
37 - 'as a child of a React component.';
38 -}
39 -
40 -/**
41 - * If there is only a single child, it still needs a name.
42 - */
43 -var ONLY_CHILD_NAME = '0';
44 -
45 -var flattenChildrenImpl = function(res, children, nameSoFar) {
46 - if (Array.isArray(children)) {
47 - for (var i = 0; i < children.length; i++) {
48 - flattenChildrenImpl(res, children[i], nameSoFar + '[' + i + ']');
49 - }
50 - } else {
51 - var type = typeof children;
52 - var isOnlyChild = nameSoFar === '';
53 - var storageName = isOnlyChild ? ONLY_CHILD_NAME : nameSoFar;
54 - if (children === null || children === undefined || type === 'boolean') {
55 - res[storageName] = null;
56 - } else if (children.mountComponentIntoNode) {
57 - /* We found a component instance */
58 - res[storageName] = children;
59 - } else {
60 - if (type === 'object') {
61 - throwIf(children && children.nodeType === 1, INVALID_CHILD);
62 - for (var key in children) {
63 - if (children.hasOwnProperty(key)) {
64 - flattenChildrenImpl(
65 - res,
66 - children[key],
67 - nameSoFar + '{' + escapeTextForBrowser(key) + '}'
68 - );
69 - }
70 - }
71 - } else if (type === 'string') {
72 - res[storageName] = new ReactTextComponent(children);
73 - } else if (type === 'number') {
74 - res[storageName] = new ReactTextComponent('' + children);
75 - }
76 - }
77 - }
78 -};
79 -
80 -/**
81 - * Flattens children that are typically specified as `props.children`.
82 - * @return {!Object} flattened children keyed by name.
83 - */
84 -function flattenChildren(children) {
85 - if (children === null || children === undefined) {
86 - return children;
87 - }
88 - var result = {};
89 - flattenChildrenImpl(result, children, '');
90 - return result;
91 -}
92 -
93 -module.exports = flattenChildren;
React/forEachAccumulated.js deleted
-36
@@ -1,36 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule forEachAccumulated
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * @param {array} an "accumulation" of items which is either an Array or
23 - * a single item. Useful when paired with the `accumulate` module. This is a
24 - * simple utility that allows us to reason about a collection of items, but
25 - * handling the case when there is exactly one item (and we do not need to
26 - * allocate an array).
27 - */
28 -var forEachAccumulated = function(arr, cb, scope) {
29 - if (Array.isArray(arr)) {
30 - arr.forEach(cb, scope);
31 - } else if (arr) {
32 - cb.call(scope, arr);
33 - }
34 -};
35 -
36 -module.exports = forEachAccumulated;
React/ge.js deleted
-76
@@ -1,76 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule ge
17 - */
18 -
19 -/**
20 - * Find a node by ID. Optionally search a sub-tree outside of the document
21 - *
22 - * Use ge if you're not sure whether or not the element exists. You can test
23 - * for existence yourself in your application code.
24 - *
25 - * If your application code depends on the existence of the element, use $
26 - * instead, which will throw in DEV if the element doesn't exist.
27 - */
28 -function ge(arg, root, tag) {
29 - return typeof arg != 'string' ? arg :
30 - !root ? document.getElementById(arg) :
31 - _geFromSubtree(arg, root, tag);
32 -}
33 -
34 -function _geFromSubtree(id, root, tag) {
35 - var elem, children, ii;
36 -
37 - if (_getNodeID(root) == id) {
38 - return root;
39 - } else if (root.getElementsByTagName) {
40 - // All Elements implement this, which does an iterative DFS, which is
41 - // faster than recursion and doesn't run into stack depth issues.
42 - children = root.getElementsByTagName(tag || '*');
43 - for (ii = 0; ii < children.length; ii++) {
44 - if (_getNodeID(children[ii]) == id) {
45 - return children[ii];
46 - }
47 - }
48 - } else {
49 - // DocumentFragment does not implement getElementsByTagName, so
50 - // recurse over its children. Its children must be Elements, so
51 - // each child will use the getElementsByTagName case instead.
52 - children = root.childNodes;
53 - for (ii = 0; ii < children.length; ii++) {
54 - elem = _geFromSubtree(id, children[ii]);
55 - if (elem) {
56 - return elem;
57 - }
58 - }
59 - }
60 -
61 - return null;
62 -}
63 -
64 -/**
65 - * Return the ID value for a given node. This allows us to avoid issues
66 - * with forms that contain inputs with name="id".
67 - *
68 - * @return string (null if attribute not set)
69 - */
70 -function _getNodeID(node) {
71 - // #document and #document-fragment do not have getAttributeNode.
72 - var id = node.getAttributeNode && node.getAttributeNode('id');
73 - return id ? id.value : null;
74 -}
75 -
76 -module.exports = ge;
React/getDOMNodeID.js deleted
-38
@@ -1,38 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule getDOMNodeID
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Accessing "id" or calling getAttribute('id') on a form element can return its
23 - * control whose name or ID is "id". However, not all DOM nodes support
24 - * `getAttributeNode` (document - which is not a form) so that is checked first.
25 - *
26 - * @param {Element} domNode DOM node element to return ID of.
27 - * @returns {string} The ID of `domNode`.
28 - */
29 -function getDOMNodeID(domNode) {
30 - if (domNode.getAttributeNode) {
31 - var attributeNode = domNode.getAttributeNode('id');
32 - return attributeNode && attributeNode.value || '';
33 - } else {
34 - return domNode.id || '';
35 - }
36 -}
37 -
38 -module.exports = getDOMNodeID;
React/getTextContentAccessor.js deleted
-40
@@ -1,40 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule getTextContentAccessor
17 - */
18 -
19 -"use strict";
20 -
21 -var ExecutionEnvironment = require("./ExecutionEnvironment");
22 -
23 -var contentKey = null;
24 -
25 -/**
26 - * Gets the key used to access text content on a DOM node.
27 - *
28 - * @return {?string} Key used to access text content.
29 - * @internal
30 - */
31 -function getTextContentAccessor() {
32 - if (!contentKey && ExecutionEnvironment.canUseDOM) {
33 - contentKey = 'innerText' in document.createElement('div') ?
34 - 'innerText' :
35 - 'textContent';
36 - }
37 - return contentKey;
38 -}
39 -
40 -module.exports = getTextContentAccessor;
React/hasArrayNature.js deleted
-52
@@ -1,52 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule hasArrayNature
17 - */
18 -
19 -/**
20 - * Perform a heuristic test to determine if an object is "array-like".
21 - *
22 - * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
23 - * Joshu replied: "Mu."
24 - *
25 - * This function determines if its argument has "array nature": it returns
26 - * true if the argument is an actual array, an `arguments' object, or an
27 - * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
28 - *
29 - * @param obj An object to test.
30 - * @return bool True if the object is array-like.
31 - */
32 -function hasArrayNature(obj) {
33 - return (
34 - // not null/false
35 - !!obj &&
36 - // arrays are objects, NodeLists are functions in Safari
37 - (typeof obj == 'object' || typeof obj == 'function') &&
38 - // quacks like an array
39 - ('length' in obj) &&
40 - // not window
41 - !('setInterval' in obj) &&
42 - (
43 - // a real array
44 - (Object.prototype.toString.call(obj) === "[object Array]" ||
45 - // arguments
46 - ('callee' in obj) || // HTMLCollection/NodeList
47 - 'item' in obj)
48 - )
49 - );
50 -}
51 -
52 -module.exports = hasArrayNature;
React/hyphenate.js deleted
-35
@@ -1,35 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule hyphenate
17 - * @typechecks
18 - */
19 -
20 -var _uppercasePattern = /([A-Z])/g;
21 -
22 -/**
23 - * Hyphenates a camelcased string, for example:
24 - *
25 - * > hyphenate('backgroundColor')
26 - * < "background-color"
27 - *
28 - * @param {string} string
29 - * @return {string}
30 - */
31 -function hyphenate(string) {
32 - return string.replace(_uppercasePattern, '-$1').toLowerCase();
33 -}
34 -
35 -module.exports = hyphenate;
React/insertNodeAt.js deleted
-46
@@ -1,46 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule insertNodeAt
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Inserts `node` at a particular child index. Other nodes move to make room.
23 - * @param {!Element} root The parent root node to insert into.
24 - * @param {!node} node The node to insert.
25 - * @param {!number} atIndex The index in `root` that `node` should exist at.
26 - */
27 -function insertNodeAt(root, node, atIndex) {
28 - var childNodes = root.childNodes;
29 - // Remove from parent so that if node is already child of root,
30 - // `childNodes[atIndex]` already takes into account the removal.
31 - var curAtIndex = root.childNodes[atIndex];
32 - if (curAtIndex === node) {
33 - return node;
34 - }
35 - if (node.parentNode) {
36 - node.parentNode.removeChild(node);
37 - }
38 - if (atIndex >= childNodes.length) {
39 - root.appendChild(node);
40 - } else {
41 - root.insertBefore(node, childNodes[atIndex]);
42 - }
43 - return node;
44 -}
45 -
46 -module.exports = insertNodeAt;
React/invariant.js deleted
-54
@@ -1,54 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule invariant
17 - */
18 -
19 -/**
20 - * Use invariant() to assert state which your program assumes to be true.
21 - *
22 - * Provide sprintf style format and arguments to provide information about
23 - * what broke and what you were expecting.
24 - *
25 - * The invariant message will be stripped in production, but the invariant
26 - * will remain to ensure logic does not differ in production.
27 - */
28 -
29 -function invariant(condition) {
30 - if (!condition) {
31 - throw new Error('Invariant Violation');
32 - }
33 -}
34 -
35 -module.exports = invariant;
36 -
37 -if (true) {
38 - var invariantDev = function(condition, format, a, b, c, d, e, f) {
39 - if (format === undefined) {
40 - throw new Error('invariant requires an error message argument');
41 - }
42 -
43 - if (!condition) {
44 - var args = [a, b, c, d, e, f];
45 - var argIndex = 0;
46 - throw new Error(
47 - 'Invariant Violation: ' +
48 - format.replace(/%s/g, function() { return args[argIndex++]; })
49 - );
50 - }
51 - };
52 -
53 - module.exports = invariantDev;
54 -}
React/isEventSupported.js deleted
-62
@@ -1,62 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule isEventSupported
17 - */
18 -
19 -"use strict";
20 -
21 -var ExecutionEnvironment = require("./ExecutionEnvironment");
22 -
23 -var testNode;
24 -if (ExecutionEnvironment.canUseDOM) {
25 - testNode = document.createElement('div');
26 -}
27 -
28 -/**
29 - * Checks if an event is supported in the current execution environment.
30 - *
31 - * NOTE: This will not work correctly for non-generic events such as `change`,
32 - * `reset`, `load`, `error`, and `select`.
33 - *
34 - * Borrows from Modernizr.
35 - *
36 - * @param {string} eventNameSuffix Event name, e.g. "click".
37 - * @param {?boolean} capture Check if the capture phase is supported.
38 - * @return {boolean} True if the event is supported.
39 - * @internal
40 - * @license Modernizr 3.0.0pre (Custom Build) | MIT
41 - */
42 -function isEventSupported(eventNameSuffix, capture) {
43 - if (!testNode || (capture && !testNode.addEventListener)) {
44 - return false;
45 - }
46 - var element = document.createElement('div');
47 - var eventName = 'on' + eventNameSuffix;
48 - var isSupported = eventName in element;
49 -
50 - if (!isSupported) {
51 - element.setAttribute(eventName, '');
52 - isSupported = typeof element[eventName] === 'function';
53 - if (typeof element[eventName] !== 'undefined') {
54 - element[eventName] = undefined;
55 - }
56 - element.removeAttribute(eventName);
57 - }
58 - element = null;
59 - return isSupported;
60 -}
61 -
62 -module.exports = isEventSupported;
React/joinClasses.js deleted
-44
@@ -1,44 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule joinClasses
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -/**
23 - * Combines multiple className strings into one.
24 - * http://jsperf.com/joinclasses-args-vs-array
25 - *
26 - * @param {...?string} classes
27 - * @return {string}
28 - */
29 -function joinClasses(className/*, ... */) {
30 - if (!className) {
31 - className = '';
32 - }
33 - var nextClass;
34 - var argLength = arguments.length;
35 - if (argLength > 1) {
36 - for (var ii = 1; ii < argLength; ii++) {
37 - nextClass = arguments[ii];
38 - nextClass && (className += ' ' + nextClass);
39 - }
40 - }
41 - return className;
42 -}
43 -
44 -module.exports = joinClasses;
React/keyMirror.js deleted
-56
@@ -1,56 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule keyMirror
17 - */
18 -
19 -"use strict";
20 -
21 -var throwIf = require("./throwIf");
22 -
23 -var NOT_OBJECT_ERROR = 'NOT_OBJECT_ERROR';
24 -if (true) {
25 - NOT_OBJECT_ERROR = 'keyMirror only works on objects';
26 -}
27 -
28 -/**
29 - * Utility for constructing enums with keys being equal to the associated
30 - * values, even when using advanced key crushing. This is useful for debugging,
31 - * but also for using the values themselves as lookups into the enum.
32 - * Example:
33 - * var COLORS = keyMirror({blue: null, red: null});
34 - * var myColor = COLORS.blue;
35 - * var isColorValid = !!COLORS[myColor]
36 - * The last line could not be performed if the values of the generated enum were
37 - * not equal to their keys.
38 - * Input: {key1: val1, key2: val2}
39 - * Output: {key1: key1, key2: key2}
40 - */
41 -var keyMirror = function(obj) {
42 - var ret = {};
43 - var key;
44 -
45 - throwIf(!(obj instanceof Object) || Array.isArray(obj), NOT_OBJECT_ERROR);
46 -
47 - for (key in obj) {
48 - if (!obj.hasOwnProperty(key)) {
49 - continue;
50 - }
51 - ret[key] = key;
52 - }
53 - return ret;
54 -};
55 -
56 -module.exports = keyMirror;
React/keyOf.js deleted
-41
@@ -1,41 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule keyOf
17 - */
18 -
19 -/**
20 - * Allows extraction of a minified key. Let's the build system minify keys
21 - * without loosing the ability to dynamically use key strings as values
22 - * themselves. Pass in an object with a single key/val pair and it will return
23 - * you the string key of that single record. Suppose you want to grab the
24 - * value for a key 'className' inside of an object. Key/val minification may
25 - * have aliased that key to be 'xa12'. keyOf({className: null}) will return
26 - * 'xa12' in that case. Resolve keys you want to use once at startup time, then
27 - * reuse those resolutions.
28 - */
29 -var keyOf = function(oneKeyObj) {
30 - var key;
31 - for (key in oneKeyObj) {
32 - if (!oneKeyObj.hasOwnProperty(key)) {
33 - continue;
34 - }
35 - return key;
36 - }
37 - return null;
38 -};
39 -
40 -
41 -module.exports = keyOf;
React/memoizeStringOnly.js deleted
-39
@@ -1,39 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule memoizeStringOnly
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -/**
23 - * Memoizes the return value of a function that accepts one string argument.
24 - *
25 - * @param {function} callback
26 - * @return {function}
27 - */
28 -function memoizeStringOnly(callback) {
29 - var cache = {};
30 - return function(string) {
31 - if (cache.hasOwnProperty(string)) {
32 - return cache[string];
33 - } else {
34 - return cache[string] = callback.call(this, string);
35 - }
36 - };
37 -}
38 -
39 -module.exports = memoizeStringOnly;
React/merge.js deleted
-37
@@ -1,37 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule merge
17 - */
18 -
19 -"use strict";
20 -
21 -var mergeInto = require("./mergeInto");
22 -
23 -/**
24 - * Shallow merges two structures into a return value, without mutating either.
25 - *
26 - * @param {?object} one Optional object with properties to merge from.
27 - * @param {?object} two Optional object with properties to merge from.
28 - * @return {object} The shallow extension of one by two.
29 - */
30 -var merge = function(one, two) {
31 - var result = {};
32 - mergeInto(result, one);
33 - mergeInto(result, two);
34 - return result;
35 -};
36 -
37 -module.exports = merge;
React/mergeDeep.js deleted
-53
@@ -1,53 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mergeDeep
17 - */
18 -
19 -"use strict";
20 -
21 -var mergeHelpers = require("./mergeHelpers");
22 -var mergeDeepInto = require("./mergeDeepInto");
23 -
24 -var checkArrayStrategy = mergeHelpers.checkArrayStrategy;
25 -var checkMergeObjectArgs = mergeHelpers.checkMergeObjectArgs;
26 -var normalizeMergeArg = mergeHelpers.normalizeMergeArg;
27 -
28 -/**
29 - * @see mergeDeepImpl comments.
30 - *
31 - * @param {!Object} one returned will be an structural extension of this.
32 - * @param {!Object} two values from two take precedence over values in one.
33 - * @param {?Enum=} arrayStrategy One of `arrayStrategies`.
34 - * @return {!Object} the extension of one by two.
35 - */
36 -var mergeDeep = function(oneParam, twoParam, arrayStrategy) {
37 - var one = normalizeMergeArg(oneParam);
38 - var two = normalizeMergeArg(twoParam);
39 - checkMergeObjectArgs(one, two);
40 - checkArrayStrategy(arrayStrategy);
41 - var newObj = {};
42 - // TODO: This is horribly inefficient. Even when some deep object in `one`
43 - // will be clobbered by another entity in `two`, we perform a clone of that
44 - // entire structure. To make this code more efficient, we'll need to either
45 - // enhance `mergeDeepInto` to accept multiple arguments or mirror that code
46 - // here.
47 - mergeDeepInto(newObj, one, arrayStrategy);
48 - mergeDeepInto(newObj, two, arrayStrategy);
49 - return newObj;
50 -};
51 -
52 -
53 -module.exports = mergeDeep;
React/mergeDeepInto.js deleted
-238
@@ -1,238 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mergeDeepInto
17 - */
18 -
19 -"use strict";
20 -
21 -var keyMirror = require("./keyMirror");
22 -var mergeHelpers = require("./mergeHelpers");
23 -var throwIf = require("./throwIf");
24 -
25 -var ArrayStrategies = mergeHelpers.ArrayStrategies;
26 -var checkArrayStrategy = mergeHelpers.checkArrayStrategy;
27 -var checkMergeArrayArgs = mergeHelpers.checkMergeArrayArgs;
28 -var checkMergeLevel = mergeHelpers.checkMergeLevel;
29 -var checkMergeObjectArgs = mergeHelpers.checkMergeObjectArgs;
30 -var isTerminal = mergeHelpers.isTerminal;
31 -var normalizeMergeArg = mergeHelpers.normalizeMergeArg;
32 -
33 -var ERRORS = keyMirror({
34 - RUN_TIME_ARRAY_MERGE_FAIL: null
35 -});
36 -
37 -if (true) {
38 - ERRORS = {
39 - RUN_TIME_ARRAY_MERGE_FAIL:
40 - "The caller has not supplied an ArrayStrategy. This is supported as " +
41 - "long as the data structures being merged do not contain two Arrays " +
42 - "that must be merged together, which is exactly what has just " +
43 - "happened. Change the call site to supply an Array merge resolver."
44 - };
45 -}
46 -
47 -/**
48 - * Every deep merge function must handle merging in each of the following cases
49 - * at every level. We may refer to letters below in implementations. For each
50 - * case listed, the "Result" listed describes the *value* of the result, but
51 - * does not specify anything about the memory graph of the result. In other
52 - * words the Results listed below will be the same for `merge` and `mergeInto`
53 - * but `merge` may have different guarantees about mutation/cloning. In the
54 - * table, "Object" refers to a non- Array, non-terminal object. One result is
55 - * undefined and requires that the caller specify the resolution policy (only
56 - * when trying to merge two arrays).
57 - *
58 - * Scenario Result
59 - * --------------------------------------------------------------
60 - * [A]: (terminal, terminal) right terminal
61 - * [B]: (terminal, Array) right Array
62 - * [C]: (terminal, Object) right Object
63 - * [D]: (terminal, not present) left terminal
64 - * [E]: (Array, terminal) right terminal
65 - * [F]: (Array, Array) UNDEFINED - MUST SPECIFY POLICY
66 - * [G]: (Array, Object) right Object
67 - * [H]: (Array, not present) left Array
68 - * [I]: (Object, terminal) right terminal
69 - * [J]: (Object, Array) right Array
70 - * [K]: (Object, Object) merge of left and right Objects
71 - * [L]: (Object, not present) left Object
72 - * [M]: (not present, terminal) right terminal
73 - * [N]: (not present, Array) right Array
74 - * [O]: (not present, Object) right Object
75 - *
76 - * All merge functions are only expected to reason about "own" properties and,
77 - * any prototypical properties should have no effect on the result. At the first
78 - * level of recursion in deep merges, we may choose to normalize arguments
79 - * (convert undefined to empty objects etc.) The above chart does not describe
80 - * the result of those top level operations which behave specially due to the
81 - * normalization.
82 - */
83 -
84 -/**
85 - * Deep merge implementation for non-Array, non-terminal Objects.
86 - *
87 - * @param {!Object} one non-Array, non-terminal Object to be mutated deeply.
88 - * @param {!Object} two non-Array, non-terminal taking precedence over `one`.
89 - * @param {?Enum=} arrayStrategy one of `arrayStrategies`.
90 - * @param {!number} level The level of recursion.
91 - */
92 -var mergeDeepIntoObjects = function(one, two, arrayStrategy, level) {
93 - checkMergeObjectArgs(one, two);
94 - checkMergeLevel(level);
95 - var twoKeys = two ? Object.keys(two) : [];
96 - for (var i = 0; i < twoKeys.length; i++) {
97 - var twoKey = twoKeys[i];
98 - mergeSingleFieldDeep(one, two, twoKey, arrayStrategy, level);
99 - }
100 -};
101 -
102 -/**
103 - * Deep merge implementation for Arrays.
104 - *
105 - * @param {!Array} one Array to deep merge.
106 - * @param {!Array} two Array to deep merge "into" `one`.
107 - * @param {?Enum=} arrayStrategy one of `arrayStrategies`.
108 - * @param {!number} level Level of recursion.
109 - */
110 -var mergeDeepIntoArrays = function(one, two, arrayStrategy, level) {
111 - checkMergeArrayArgs(one, two);
112 - checkMergeLevel(level);
113 -
114 - var maxLen = Math.max(one.length, two.length);
115 - for (var i = 0; i < maxLen; i++) {
116 - mergeSingleFieldDeep(one, two, i, arrayStrategy, level);
117 - }
118 -};
119 -
120 -/**
121 - * Given two truthy containers `one` and `two`, and a `key`, performs a deep
122 - * merge on a logical field.
123 - *
124 - * @param {!Array|Object} one Container to merge into.
125 - * @param {!Array|Object} two Container to merge from.
126 - * @param {!string} key Key of field that should be merged.
127 - * @param {lEnum=} arrayStrategy One of `arrayStrategies`.
128 - * @param {!number} level Current level of recursion.
129 - */
130 -var mergeSingleFieldDeep = function(one, two, key, arrayStrategy, level) {
131 - var twoVal = two[key];
132 - var twoValIsPresent = two.hasOwnProperty(key);
133 - var twoValIsTerminal = twoValIsPresent && isTerminal(twoVal);
134 - var twoValIsArray = twoValIsPresent && Array.isArray(twoVal);
135 - var twoValIsProperObject =
136 - twoValIsPresent && !twoValIsArray && !twoValIsArray;
137 -
138 - var oneVal = one[key];
139 - var oneValIsPresent = one.hasOwnProperty(key);
140 - var oneValIsTerminal = oneValIsPresent && isTerminal(oneVal);
141 - var oneValIsArray = oneValIsPresent && Array.isArray(oneVal);
142 - var oneValIsProperObject =
143 - oneValIsPresent && !oneValIsArray && !oneValIsArray;
144 -
145 - if (oneValIsTerminal) {
146 - if (twoValIsTerminal) { // [A]
147 - one[key] = twoVal;
148 - } else if (twoValIsArray) { // [B]
149 - one[key] = [];
150 - mergeDeepIntoArrays(one[key], twoVal, arrayStrategy, level + 1);
151 - } else if (twoValIsProperObject) { // [C]
152 - one[key] = {};
153 - mergeDeepIntoObjects(one[key], twoVal, arrayStrategy, level + 1);
154 - } else if (!twoValIsPresent) { // [D]
155 - one[key] = oneVal;
156 - }
157 - } else if (oneValIsArray) {
158 - if (twoValIsTerminal) { // [E]
159 - one[key] = twoVal;
160 - } else if (twoValIsArray) { // [F]
161 - throwIf(
162 - !ArrayStrategies[arrayStrategy],
163 - ERRORS.RUN_TIME_ARRAY_MERGE_FAIL
164 - );
165 - // Else: At this point, the only other valid option is `IndexByIndex`
166 - if (arrayStrategy === ArrayStrategies.Clobber) {
167 - oneVal.length = 0;
168 - }
169 - mergeDeepIntoArrays(oneVal, twoVal, arrayStrategy, level + 1);
170 - } else if (twoValIsProperObject) { // [G]
171 - one[key] = {};
172 - mergeDeepIntoObjects(one[key], twoVal, arrayStrategy, level + 1);
173 - } else if (!twoValIsPresent) { // [H]
174 - // Leave the left Array alone
175 - }
176 - } else if (oneValIsProperObject) {
177 - if (twoValIsTerminal) { // [I]
178 - one[key] = twoVal;
179 - } else if (twoValIsArray) { // [J]
180 - one[key] = [];
181 - mergeDeepIntoArrays(one[key], twoVal, arrayStrategy, level + 1);
182 - } else if (twoValIsProperObject) { // [K]
183 - mergeDeepIntoObjects(oneVal, twoVal, arrayStrategy, level + 1);
184 - } else if (!twoValIsPresent) { // [L]
185 - // Leave the left Object alone
186 - }
187 - } else if (!oneValIsPresent) {
188 - if (twoValIsTerminal) { // [M]
189 - one[key] = twoVal;
190 - } else if (twoValIsArray) { // [N]
191 - one[key] = [];
192 - mergeDeepIntoArrays(one[key], twoVal, arrayStrategy, level + 1);
193 - } else if (twoValIsProperObject) { // [O]
194 - one[key] = {};
195 - mergeDeepIntoObjects(one[key], twoVal, arrayStrategy, level + 1);
196 - } else if (!twoValIsPresent) {
197 - // Could/should never happen
198 - }
199 - }
200 -};
201 -
202 -
203 -
204 -/**
205 - * Provides same functionality as mergeInto, but merges by mutating the first
206 - * argument. Will never mutate the second argument.
207 - *
208 - * mergeDeepInto provides two guarantees:
209 - * 1. In the process of mutating one, will not mutate two.
210 - * 2. Will not cause any nonTerminal memory to be shared between one and two.
211 - * This means that no further mutations to one will effect two (unless some
212 - * other part of your application forms shared memory between one and two).
213 - *
214 - * mergeDeepInto does not guarantee that it will *preserve* any shared memory
215 - * between two and one that existed before invocation. After calling
216 - * mergeDeepInto, there will be less (or equal) amount of shared memory between
217 - * one and two.
218 - *
219 - * Will tolerate a circular structure as the first parameter, but not the
220 - * second.
221 - *
222 - * Requires that first parameter be a non-Array, non-terminal `Object`, and the
223 - * second argument either be an `Object` or `null/undefined`. Arrays may exist
224 - * in the depths of either `Object` as long as an `arrayStrategy` is supplied.
225 - *
226 - * The third parameter indicates how merging two `Array`s should be performed.
227 - *
228 - * @param {!Object} one Object to be mutated deeply.
229 - * @param {?Object} two Values from two take precedence over values in one.
230 - * @param {?Enum=} arrayStrategy One of arrayStrategy
231 - */
232 -var mergeDeepInto = function(one, twoParam, arrayStrategy) {
233 - var two = normalizeMergeArg(twoParam);
234 - checkArrayStrategy(arrayStrategy); // Will be checked twice, for now
235 - mergeDeepIntoObjects(one, two, arrayStrategy, 0);
236 -};
237 -
238 -module.exports = mergeDeepInto;
React/mergeHelpers.js deleted
-162
@@ -1,162 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mergeHelpers
17 - *
18 - * requiresPolyfills: Array.isArray
19 - */
20 -
21 -"use strict";
22 -
23 -var keyMirror = require("./keyMirror");
24 -var throwIf = require("./throwIf");
25 -
26 -/*
27 - * Maximum number of levels to traverse. Will catch circular structures.
28 - * @const
29 - */
30 -var MAX_MERGE_DEPTH = 36;
31 -
32 -var ERRORS = keyMirror({
33 - MERGE_ARRAY_FAIL: null,
34 - MERGE_CORE_FAILURE: null,
35 - MERGE_TYPE_USAGE_FAILURE: null,
36 - MERGE_DEEP_MAX_LEVELS: null,
37 - MERGE_DEEP_NO_ARR_STRATEGY: null
38 -});
39 -
40 -if (true) {
41 - ERRORS = {
42 - MERGE_ARRAY_FAIL:
43 - 'Unsupported type passed to a merge function. You may have passed a ' +
44 - 'structure that contains an array and the merge function does not know ' +
45 - 'how to merge arrays. ',
46 -
47 - MERGE_CORE_FAILURE:
48 - 'Critical assumptions about the merge functions have been violated. ' +
49 - 'This is the fault of the merge functions themselves, not necessarily ' +
50 - 'the callers.',
51 -
52 - MERGE_TYPE_USAGE_FAILURE:
53 - 'Calling merge function with invalid types. You may call merge ' +
54 - 'functions (non-array non-terminal) OR (null/undefined) arguments. ' +
55 - 'mergeInto functions have the same requirements but with an added ' +
56 - 'restriction that the first parameter must not be null/undefined.',
57 -
58 - MERGE_DEEP_MAX_LEVELS:
59 - 'Maximum deep merge depth exceeded. You may attempting to merge ' +
60 - 'circular structures in an unsupported way.',
61 - MERGE_DEEP_NO_ARR_STRATEGY:
62 - 'You must provide an array strategy to deep merge functions to ' +
63 - 'instruct the deep merge how to resolve merging two arrays.'
64 - };
65 -}
66 -
67 -/**
68 - * We won't worry about edge cases like new String('x') or new Boolean(true).
69 - * Functions are considered terminals, and arrays are not.
70 - * @param {*} o The item/object/value to test.
71 - * @return {boolean} true iff the argument is a terminal.
72 - */
73 -var isTerminal = function(o) {
74 - return typeof o !== 'object' || o === null;
75 -};
76 -
77 -var mergeHelpers = {
78 -
79 - MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
80 -
81 - isTerminal: isTerminal,
82 -
83 - /**
84 - * Converts null/undefined values into empty object.
85 - *
86 - * @param {?Object=} arg Argument to be normalized (nullable optional)
87 - * @return {!Object}
88 - */
89 - normalizeMergeArg: function(arg) {
90 - return arg === undefined || arg === null ? {} : arg;
91 - },
92 -
93 - /**
94 - * If merging Arrays, a merge strategy *must* be supplied. If not, it is
95 - * likely the caller's fault. If this function is ever called with anything
96 - * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
97 - *
98 - * @param {*} one Array to merge into.
99 - * @param {*} two Array to merge from.
100 - */
101 - checkMergeArrayArgs: function(one, two) {
102 - throwIf(
103 - !Array.isArray(one) || !Array.isArray(two),
104 - ERRORS.MERGE_CORE_FAILURE
105 - );
106 - },
107 -
108 - /**
109 - * @param {*} one Object to merge into.
110 - * @param {*} two Object to merge from.
111 - */
112 - checkMergeObjectArgs: function(one, two) {
113 - mergeHelpers.checkMergeObjectArg(one);
114 - mergeHelpers.checkMergeObjectArg(two);
115 - },
116 -
117 - /**
118 - * @param {*} arg
119 - */
120 - checkMergeObjectArg: function(arg) {
121 - throwIf(isTerminal(arg) || Array.isArray(arg), ERRORS.MERGE_CORE_FAILURE);
122 - },
123 -
124 - /**
125 - * Checks that a merge was not given a circular object or an object that had
126 - * too great of depth.
127 - *
128 - * @param {number} Level of recursion to validate against maximum.
129 - */
130 - checkMergeLevel: function(level) {
131 - throwIf(level >= MAX_MERGE_DEPTH, ERRORS.MERGE_DEEP_MAX_LEVELS);
132 - },
133 -
134 - /**
135 - * Checks that a merge was not given a circular object or an object that had
136 - * too great of depth.
137 - *
138 - * @param {number} Level of recursion to validate against maximum.
139 - */
140 - checkArrayStrategy: function(strategy) {
141 - throwIf(
142 - strategy !== undefined && !(strategy in mergeHelpers.ArrayStrategies),
143 - ERRORS.MERGE_DEEP_NO_ARR_STRATEGY
144 - );
145 - },
146 -
147 - /**
148 - * Set of possible behaviors of merge algorithms when encountering two Arrays
149 - * that must be merged together.
150 - * - `clobber`: The left `Array` is ignored.
151 - * - `indexByIndex`: The result is achieved by recursively deep merging at
152 - * each index. (not yet supported.)
153 - */
154 - ArrayStrategies: keyMirror({
155 - Clobber: true,
156 - IndexByIndex: true
157 - }),
158 -
159 - ERRORS: ERRORS
160 -};
161 -
162 -module.exports = mergeHelpers;
React/mergeInto.js deleted
-45
@@ -1,45 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mergeInto
17 - * @typechecks
18 - */
19 -
20 -"use strict";
21 -
22 -var mergeHelpers = require("./mergeHelpers");
23 -
24 -var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
25 -
26 -/**
27 - * Shallow merges two structures by mutating the first parameter.
28 - *
29 - * @param {object} one Object to be merged into.
30 - * @param {?object} two Optional object with properties to merge from.
31 - */
32 -function mergeInto(one, two) {
33 - checkMergeObjectArg(one);
34 - if (two != null) {
35 - checkMergeObjectArg(two);
36 - for (var key in two) {
37 - if (!two.hasOwnProperty(key)) {
38 - continue;
39 - }
40 - one[key] = two[key];
41 - }
42 - }
43 -}
44 -
45 -module.exports = mergeInto;
React/mixInto.js deleted
-34
@@ -1,34 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mixInto
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Simply copies properties to the prototype.
23 - */
24 -var mixInto = function(constructor, methodBag) {
25 - var methodName;
26 - for (methodName in methodBag) {
27 - if (!methodBag.hasOwnProperty(methodName)) {
28 - continue;
29 - }
30 - constructor.prototype[methodName] = methodBag[methodName];
31 - }
32 -};
33 -
34 -module.exports = mixInto;
React/mock-modules.js deleted
-33
@@ -1,33 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mock-modules
17 - */
18 -
19 -var global = Function("return this")();
20 -require("./test/mock-timers").installMockTimers(global);
21 -
22 -exports.dumpCache = function() {
23 - require("./mocks").clear();
24 - return exports;
25 -};
26 -
27 -exports.dontMock = function() {
28 - return exports;
29 -};
30 -
31 -exports.mock = function() {
32 - return exports;
33 -};
React/mocks.js deleted
-431
@@ -1,431 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule mocks
17 - */
18 -
19 -function isA(typeName, value) {
20 - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
21 -}
22 -
23 -function getType(ref) {
24 - if (isA('RegExp', ref)) {
25 - return 'regexp';
26 - }
27 -
28 - if (isA('Array', ref)) {
29 - return 'array';
30 - }
31 -
32 - if (isA('Function', ref)) {
33 - return 'function';
34 - }
35 -
36 - if (isA('Object', ref)) {
37 - return 'object';
38 - }
39 -
40 - // consider number and string fields to be constants that we want to
41 - // pick up as they are
42 - if (isA('Number', ref) || isA('String', ref)) {
43 - return 'constant';
44 - }
45 -
46 - return null;
47 -}
48 -
49 -function makeComponent(metadata) {
50 - switch (metadata.type) {
51 - case 'object':
52 - return {};
53 -
54 - case 'array':
55 - return [];
56 -
57 - case 'regexp':
58 - return new RegExp();
59 -
60 - case 'constant':
61 - return metadata.value;
62 -
63 - case 'function':
64 - var defaultReturnValue;
65 - var specificReturnValues = [];
66 - var mockImpl;
67 - var isReturnValueLastSet = false;
68 - var calls = [];
69 - var instances = [];
70 - var prototype =
71 - (metadata.members && metadata.members.prototype &&
72 - metadata.members.prototype.members) || {};
73 -
74 - var f = function() {
75 - dirtyMocks.push(f);
76 -
77 - instances.push(this);
78 - calls.push(Array.prototype.slice.call(arguments));
79 - if (this instanceof arguments.callee) {
80 - // This is probably being called as a constructor
81 - for (var slot in prototype) {
82 - // Copy prototype methods to the instance to make
83 - // it easier to interact with mock instance call and
84 - // return values
85 - if (prototype[slot].type == 'function') {
86 - var protoImpl = this[slot];
87 - this[slot] = generateFromMetadata(prototype[slot]);
88 - this[slot]._protoImpl = protoImpl;
89 - }
90 - }
91 -
92 - // Run the mock constructor implementation
93 - mockImpl && mockImpl.apply(this, arguments);
94 - return;
95 - }
96 -
97 - var returnValue;
98 - // If return value is last set, either specific or default, i.e.
99 - // mockReturnValue()/mockDefaultReturnValue() is called and no
100 - // mockImplementation() is called after that.
101 - // use the set return value.
102 - if (isReturnValueLastSet) {
103 - returnValue = specificReturnValues.shift();
104 - if (returnValue === undefined) {
105 - returnValue = defaultReturnValue;
106 - }
107 - }
108 -
109 - // If mockImplementation() is last set, or specific return values
110 - // are used up, use the mock implementation.
111 - if (mockImpl && returnValue === undefined) {
112 - return mockImpl.apply(this, arguments);
113 - }
114 -
115 - // Otherwise use prototype implementation
116 - if (returnValue === undefined && arguments.callee._protoImpl) {
117 - return arguments.callee._protoImpl.apply(this, arguments);
118 - }
119 -
120 - return returnValue;
121 - };
122 -
123 - f._isMockFunction = true;
124 -
125 - f.mock = {
126 - calls : calls,
127 - instances : instances
128 - };
129 -
130 - f.mockClear = function() {
131 - calls.length = 0;
132 - instances.length = 0;
133 - };
134 -
135 - f.mockReturnValue = function(value) {
136 - // next function call will return this value or default return value
137 - isReturnValueLastSet = true;
138 - specificReturnValues.push(value);
139 - return f;
140 - };
141 -
142 - f.mockDefaultReturnValue = function(value) {
143 - // next function call will return specified return value or this one
144 - isReturnValueLastSet = true;
145 - defaultReturnValue = value;
146 - return f;
147 - };
148 -
149 - f.mockImplementation = function(fn) {
150 - // next function call will use mock implementation return value
151 - isReturnValueLastSet = false;
152 - mockImpl = fn;
153 - return f;
154 - };
155 -
156 - f.mockReturnThis = function() {
157 - return f.mockImplementation(function() {
158 - return this;
159 - });
160 - };
161 -
162 - f._getMockImplementation = function() {
163 - return mockImpl;
164 - };
165 -
166 - if (metadata.mockImpl) {
167 - f.mockImplementation(metadata.mockImpl);
168 - }
169 -
170 - return f;
171 - }
172 -
173 - throw new Error('Unrecognized type ' + metadata.type);
174 -}
175 -
176 -function generateFromMetadata(_metadata) {
177 - var callbacks = [];
178 - var refs = {};
179 -
180 - function generateMock(metadata) {
181 - var mock = makeComponent(metadata);
182 - if (metadata.ref_id != null) {
183 - refs[metadata.ref_id] = mock;
184 - }
185 -
186 - function getRefCallback(slot, ref) {
187 - return function() {
188 - mock[slot] = refs[ref];
189 - };
190 - }
191 -
192 - for (var slot in metadata.members) {
193 - var slotMetadata = metadata.members[slot];
194 - if (slotMetadata.ref != null) {
195 - callbacks.push(getRefCallback(slot, slotMetadata.ref));
196 - } else {
197 - mock[slot] = generateMock(slotMetadata);
198 - }
199 - }
200 -
201 - return mock;
202 - }
203 -
204 - var mock = generateMock(_metadata);
205 - callbacks.forEach(function(setter) {
206 - setter();
207 - });
208 -
209 - return mock;
210 -}
211 -
212 -
213 -function _getMetadata(component, _refs) {
214 - var refs = _refs || [];
215 -
216 - // This is a potential performance drain, since the whole list is scanned
217 - // for every component
218 - var ref = refs.indexOf(component);
219 - if (ref > -1) {
220 - return {ref: ref};
221 - }
222 -
223 - var type = getType(component);
224 - if (!type) {
225 - return null;
226 - }
227 -
228 - var metadata = {type : type};
229 - if (type == 'constant') {
230 - metadata.value = component;
231 - return metadata;
232 - } else if (type == 'function') {
233 - if (component._isMockFunction) {
234 - metadata.mockImpl = component._getMockImplementation();
235 - }
236 - }
237 -
238 - metadata.ref_id = refs.length;
239 - refs.push(component);
240 -
241 - var members = null;
242 -
243 - function addMember(slot, data) {
244 - if (!data) {
245 - return;
246 - }
247 - if (!members) {
248 - members = {};
249 - }
250 - members[slot] = data;
251 - }
252 -
253 - // Leave arrays alone
254 - if (type != 'array') {
255 - for (var slot in component) {
256 - if (slot.charAt(0) == '_' ||
257 - (type == 'function' && component._isMockFunction &&
258 - slot.match(/^mock/))) {
259 - continue;
260 - }
261 -
262 - if (component.hasOwnProperty(slot) ||
263 - (type == 'object' && component[slot] != Object.prototype[slot])) {
264 - addMember(slot, _getMetadata(component[slot], refs));
265 - }
266 - }
267 -
268 - // If component is native code function, prototype might be undefined
269 - if (type == 'function' && component.prototype) {
270 - var prototype = _getMetadata(component.prototype, refs);
271 - if (prototype && prototype.members) {
272 - addMember('prototype', prototype);
273 - }
274 - }
275 - }
276 -
277 - if (members) {
278 - metadata.members = members;
279 - }
280 -
281 - return metadata;
282 -}
283 -
284 -function removeUnusedRefs(metadata) {
285 - function visit(md, f) {
286 - f(md);
287 - if (md.members) {
288 - for (var slot in md.members) {
289 - visit(md.members[slot], f);
290 - }
291 - }
292 - }
293 -
294 - var usedRefs = {};
295 - visit(metadata, function(md) {
296 - if (md.ref != null) {
297 - usedRefs[md.ref] = true;
298 - }
299 - });
300 -
301 - visit(metadata, function(md) {
302 - if (!usedRefs[md.ref_id]) {
303 - delete md.ref_id;
304 - }
305 - });
306 -}
307 -
308 -var dirtyMocks = [];
309 -
310 -module.exports = {
311 - /**
312 - * Invokes the .mockClear method of all function mocks that have been
313 - * called since the last time clear was called.
314 - */
315 - clear: function() {
316 - var old = dirtyMocks;
317 - dirtyMocks = [];
318 - old.forEach(function(mock) {
319 - mock.mockClear();
320 - });
321 - },
322 -
323 - /**
324 - * Generates a mock based on the given metadata. Mocks treat functions
325 - * specially, and all mock functions have additional members, described in the
326 - * documentation for getMockFunction in this module.
327 - *
328 - * One important note: function prototoypes are handled specially by this
329 - * mocking framework. For functions with prototypes, when called as a
330 - * constructor, the mock will install mocked function members on the instance.
331 - * This allows different instances of the same constructor to have different
332 - * values for its mocks member and its return values.
333 - *
334 - * @param metadata Metadata for the mock in the schema returned by the
335 - * getMetadata method of this module.
336 - *
337 - */
338 - generateFromMetadata: generateFromMetadata,
339 -
340 - /**
341 - * Inspects the argument and returns its schema in the following recursive
342 - * format:
343 - * {
344 - * type: ...
345 - * members : {}
346 - * }
347 - *
348 - * Where type is one of 'array', 'object', 'function', or 'ref', and members
349 - * is an optional dictionary where the keys are member names and the values
350 - * are metadata objects. Function prototypes are defined simply by defining
351 - * metadata for the member.prototype of the function. The type of a function
352 - * prototype should always be "object". For instance, a simple class might be
353 - * defined like this:
354 - *
355 - * {
356 - * type: 'function',
357 - * members: {
358 - * staticMethod: {type: 'function'},
359 - * prototype: {
360 - * type: 'object',
361 - * members: {
362 - * instanceMethod: {type: 'function'}
363 - * }
364 - * }
365 - * }
366 - * }
367 - *
368 - * Metadata may also contain references to other objects defined within the
369 - * same metadata object. The metadata for the referent must be marked with
370 - * 'ref_id' key and an arbitrary value. The referer must be marked with a
371 - * 'ref' key that has the same value as object with ref_id that it refers to.
372 - * For instance, this metadata blob:
373 - * {
374 - * type: 'object',
375 - * ref_id: 1,
376 - * members: {
377 - * self: {ref: 1}
378 - * }
379 - * }
380 - *
381 - * defines an object with a slot named 'self' that refers back to the object.
382 - *
383 - * @param component The component for which to retrieve metadata.
384 - */
385 - getMetadata: function(component) {
386 - var metadata = _getMetadata(component);
387 - // to make it easier to work with mock metadata, only preserve references
388 - // that are actually used
389 - removeUnusedRefs(metadata);
390 - return metadata;
391 - },
392 -
393 - /**
394 - * Generates a stand-alone function with members that help drive unit tests or
395 - * confirm expectations. Specifically, functions returned by this method have
396 - * the following members:
397 - *
398 - * .mock:
399 - * An object with two members, "calls", and "instances", which are both
400 - * lists. The items in the "calls" list are the arguments with which the
401 - * function was called. The "instances" list stores the value of 'this' for
402 - * each call to the function. This is useful for retrieving instances from a
403 - * constructor.
404 - *
405 - * .mockReturnValue(value)
406 - * Pushes the given value onto a FIFO queue of return values for the
407 - * function.
408 - *
409 - * .mockDefaultReturnValue(value)
410 - * Sets the default return value for the function.
411 - *
412 - * .mockImplementation(function)
413 - * Sets a mock implementation for the function.
414 - *
415 - * .mockReturnThis()
416 - * Syntactic sugar for .mockImplementation(function() {return this;})
417 - *
418 - * In case both mockImplementation() and
419 - * mockReturnValue()/mockDefaultReturnValue() are called. The priority of
420 - * which to use is based on what is the last call:
421 - * - if the last call is mockRetrunValue() or mockDefaultReturnValue(),
422 - * use the specific return specific return value or default return value.
423 - * If specific return values are used up or no default return value is set,
424 - * fall back to try mockImplementation();
425 - * - if the last call is mockImplementation(), run the given implementation
426 - * and return the result.
427 - */
428 - getMockFunction: function() {
429 - return makeComponent({type: 'function'});
430 - }
431 -};
React/objFilter.js deleted
-48
@@ -1,48 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule objFilter
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * For each key/value pair, invokes callback func and constructs a resulting
23 - * object which contains each key/value pair which produces a truthy result
24 - * from invoking the function:
25 - *
26 - * func(value, key, iteration)
27 - *
28 - * @param {?object} obj Object to map keys over
29 - * @param {function} func Invoked for each key/val pair.
30 - * @param {?*} context
31 - * @return {?object} Result of filtering or null if obj is falsey
32 - */
33 -function objFilter(obj, func, context) {
34 - if (!obj) {
35 - return null;
36 - }
37 - var i = 0;
38 - var ret = {};
39 - for (var key in obj) {
40 - if (obj.hasOwnProperty(key) &&
41 - func.call(context, obj[key], key, i++)) {
42 - ret[key] = obj[key];
43 - }
44 - }
45 - return ret;
46 -}
47 -
48 -module.exports = objFilter;
React/objMap.js deleted
-47
@@ -1,47 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule objMap
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * For each key/value pair, invokes callback func and constructs a resulting
23 - * object which contains, for every key in obj, values that are the result of
24 - * of invoking the function:
25 - *
26 - * func(value, key, iteration)
27 - *
28 - * @param {?object} obj Object to map keys over
29 - * @param {function} func Invoked for each key/val pair.
30 - * @param {?*} context
31 - * @return {?object} Result of mapping or null if obj is falsey
32 - */
33 -function objMap(obj, func, context) {
34 - if (!obj) {
35 - return null;
36 - }
37 - var i = 0;
38 - var ret = {};
39 - for (var key in obj) {
40 - if (obj.hasOwnProperty(key)) {
41 - ret[key] = func.call(context, obj[key], key, i++);
42 - }
43 - }
44 - return ret;
45 -}
46 -
47 -module.exports = objMap;
React/objMapKeyVal.js deleted
-47
@@ -1,47 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule objMapKeyVal
17 - */
18 -
19 -"use strict";
20 -
21 -/**
22 - * Behaves the same as `objMap` but invokes func with the key first, and value
23 - * second. Use `objMap` unless you need this special case.
24 - * Invokes func as:
25 - *
26 - * func(key, value, iteration)
27 - *
28 - * @param {?object} obj Object to map keys over
29 - * @param {!function} func Invoked for each key/val pair.
30 - * @param {?*} context
31 - * @return {?object} Result of mapping or null if obj is falsey
32 - */
33 -function objMapKeyVal(obj, func, context) {
34 - if (!obj) {
35 - return null;
36 - }
37 - var i = 0;
38 - var ret = {};
39 - for (var key in obj) {
40 - if (obj.hasOwnProperty(key)) {
41 - ret[key] = func.call(context, key, obj[key], i++);
42 - }
43 - }
44 - return ret;
45 -}
46 -
47 -module.exports = objMapKeyVal;
React/reactComponentExpect.js deleted
-190
@@ -1,190 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule reactComponentExpect
17 - * @nolint
18 - */
19 -
20 -var ReactComponent = require("./ReactComponent");
21 -var ReactTestUtils = require("./ReactTestUtils");
22 -
23 -var copyProperties = require("./copyProperties");
24 -
25 -function reactComponentExpect(instance) {
26 - if (instance instanceof reactComponentExpect) {
27 - return instance;
28 - }
29 -
30 - if (!(this instanceof reactComponentExpect)) {
31 - return new reactComponentExpect(instance);
32 - }
33 -
34 - this._instance = instance;
35 - this.toBeValidReactComponent();
36 -}
37 -
38 -copyProperties(reactComponentExpect.prototype, {
39 - // Getters -------------------------------------------------------------------
40 -
41 - /**
42 - * @instance: Retrieves the backing instance.
43 - */
44 - instance: function() {
45 - return this._instance;
46 - },
47 -
48 - /**
49 - * There are two types of components in the world.
50 - * - A component created via React.createClass() - Has a single child
51 - * subComponent - the return value from the .render() function. This
52 - * function @subComponent expects that this._instance is component created
53 - * with React.createClass().
54 - * - A primitive DOM component - which has many renderedChildren, each of
55 - * which may have a name that is unique with respect to its siblings. This
56 - * method will fail if this._instance is a primitive component.
57 - *
58 - * TL;DR: An instance may have a subComponent (this._renderedComponent) or
59 - * renderedChildren, but never both. Neither will actually show up until you
60 - * render the component (simply instantiating is not enough).
61 - */
62 - expectRenderedChild: function() {
63 - this.toBeCompositeComponent();
64 - return new reactComponentExpect(this.instance()._renderedComponent);
65 - },
66 -
67 - /**
68 - * The nth child of a DOMish component instance that is not falsy.
69 - */
70 - expectRenderedChildAt: function(childIndex) {
71 - // Currently only dom components have arrays of children, but that will
72 - // change soon.
73 - this.toBeDOMComponent();
74 - var renderedChildren = this.instance()._renderedChildren || {};
75 - var nonEmptyCount = 0;
76 - var name;
77 - for (name in renderedChildren) {
78 - if (!renderedChildren.hasOwnProperty(name)) {
79 - continue;
80 - }
81 - if (renderedChildren[name]) {
82 - if (nonEmptyCount === childIndex) {
83 - return new reactComponentExpect(renderedChildren[name]);
84 - }
85 - nonEmptyCount++;
86 - }
87 - }
88 - throw new Error('Child:' + childIndex + ' is not found');
89 - },
90 -
91 - toBeDOMComponentWithChildCount: function(n) {
92 - this.toBeDOMComponent();
93 - expect(this.instance()._renderedChildren).toBeTruthy();
94 - var len = Object.keys(this.instance()._renderedChildren).length;
95 - expect(len).toBe(n);
96 - return this;
97 - },
98 -
99 - toBeDOMComponentWithNoChildren: function() {
100 - this.toBeDOMComponent();
101 - expect(this.instance()._renderedChildren).toBeFalsy();
102 - return this;
103 - },
104 -
105 - // Matchers ------------------------------------------------------------------
106 -
107 - /**
108 - * A component that is created with React.createClass. Just duck typing
109 - * here.
110 - */
111 - toBeCompositeComponent: function() {
112 - this.toBeValidReactComponent();
113 - expect(ReactTestUtils.isCompositeComponent(this.instance())).toBe(true);
114 - return this;
115 - },
116 -
117 - toBeCompositeComponentWithType: function(convenienceConstructor) {
118 - expect(ReactTestUtils.isCompositeComponentWithType(
119 - this.instance(),
120 - convenienceConstructor
121 - )).toBe(true);
122 - return this;
123 - },
124 -
125 - toBeTextComponent: function() {
126 - expect(ReactTestUtils.isTextComponent(this.instance())).toBe(true);
127 - return this;
128 - },
129 -
130 - /**
131 - * Falsy values are valid components - the vanished component that is.
132 - */
133 - toBeValidReactComponent: function() {
134 - expect(ReactComponent.isValidComponent(this.instance())).toBe(true);
135 - return this;
136 - },
137 -
138 - toBePresent: function() {
139 - expect(this.instance()).toBeTruthy();
140 - return this;
141 - },
142 -
143 - /**
144 - * A terminal type of component representing some virtual dom node. Just duck
145 - * typing here.
146 - */
147 - toBeDOMComponent: function() {
148 - expect(ReactTestUtils.isDOMComponent(this.instance())).toBe(true);
149 - return this;
150 - },
151 -
152 - toBeDOMComponentWithTag: function(tag) {
153 - this.toBeDOMComponent();
154 - expect(this.instance().tagName).toBe(tag.toUpperCase());
155 - return this;
156 - },
157 -
158 - /**
159 - * Check that internal state values are equal to a state of expected values.
160 - */
161 - scalarStateEqual: function(stateNameToExpectedValue) {
162 - expect(this.instance()).toBeTruthy();
163 - for (var stateName in stateNameToExpectedValue) {
164 - if (!stateNameToExpectedValue.hasOwnProperty(stateName)) {
165 - continue;
166 - }
167 - expect(this.instance().state[stateName])
168 - .toEqual(stateNameToExpectedValue[stateName]);
169 - }
170 - return this;
171 - },
172 -
173 - /**
174 - * Check a set of props are equal to a set of expected values - only works
175 - * with scalars.
176 - */
177 - scalarPropsEqual: function(propNameToExpectedValue) {
178 - expect(this.instance()).toBeTruthy();
179 - for (var propName in propNameToExpectedValue) {
180 - if (!propNameToExpectedValue.hasOwnProperty(propName)) {
181 - continue;
182 - }
183 - expect(this.instance().props[propName])
184 - .toEqual(propNameToExpectedValue[propName]);
185 - }
186 - return this;
187 - }
188 -});
189 -
190 -module.exports = reactComponentExpect;
React/test/all.js deleted
-57
@@ -1,57 +0,0 @@
1 -// This file exists both to give a single entry point for all the utility
2 -// modules in src/test and to specify an ordering on those modules, since
3 -// some still have implicit dependencies on others.
4 -
5 -var Ap = Array.prototype;
6 -var slice = Ap.slice;
7 -var Fp = Function.prototype;
8 -
9 -if (!Fp.bind) {
10 - // PhantomJS doesn't support Function.prototype.bind natively, so
11 - // polyfill it whenever this module is required.
12 - Fp.bind = function(context) {
13 - var func = this;
14 - var args = slice.call(arguments, 1);
15 - var bound;
16 -
17 - if (func.prototype) {
18 - if (args.length > 0) {
19 - bound = function() {
20 - return func.apply(
21 - !(this instanceof func) && context || this,
22 - args.concat(slice.call(arguments))
23 - );
24 - };
25 - } else {
26 - bound = function() {
27 - return func.apply(
28 - !(this instanceof func) && context || this,
29 - arguments
30 - );
31 - };
32 - }
33 -
34 - bound.prototype = Object.create(func.prototype);
35 -
36 - } else if (args.length > 0) {
37 - bound = function() {
38 - return func.apply(
39 - context || this,
40 - args.concat(slice.call(arguments))
41 - );
42 - };
43 - } else {
44 - bound = function() {
45 - return func.apply(context || this, arguments);
46 - };
47 - }
48 -
49 - return bound;
50 - };
51 -}
52 -
53 -require("../ReactTestUtils");
54 -require("../reactComponentExpect");
55 -require("../mocks");
56 -require("../mock-modules");
57 -require("./mock-timers");
React/test/mock-timers.js deleted
-226
@@ -1,226 +0,0 @@
1 -var mocks = require("../mocks");
2 -
3 -var timers = {};
4 -// Keep a fake timestamp
5 -// move on the time when runTimersToTime() is called
6 -var now = 0;
7 -
8 -// add a timer of type either 'timeout' or 'interval'
9 -function _setTimer(type, callback, delay) {
10 - var token = null;
11 - do {
12 - token = Math.floor(Math.random() * 4294967296) + 1;
13 - } while (timers[token]);
14 - timers[token] = {
15 - type: type,
16 - callback: callback,
17 - // Add some random msecs to the delay to mimic code execution time.
18 - time: now + delay + Math.floor(Math.random() * 5),
19 - interval: (type == 'interval' ? delay : 0)
20 - };
21 - return token;
22 -}
23 -
24 -// clear a timer of type either 'timeout' or 'interval'
25 -function _clearTimer(type, token) {
26 - if (timers[token] && timers[token].type == type) {
27 - delete timers[token];
28 - }
29 -}
30 -
31 -function _setTimeout(callback, delay) {
32 - return _setTimer('timeout', callback, delay);
33 -}
34 -
35 -function _setInterval(callback, delay) {
36 - return _setTimer('interval', callback, delay);
37 -}
38 -
39 -function _clearTimeout(token) {
40 - _clearTimer('timeout', token);
41 -}
42 -
43 -function _clearInterval(token) {
44 - _clearTimer('interval', token);
45 -}
46 -
47 -// Run timer of given token
48 -function _runTimer(token) {
49 - // Skip non-existing token
50 - if (timers[token]) {
51 - if (timers[token].type == 'timeout') {
52 - // for 'timeout', run callback and delete the timer
53 - var callback = timers[token].callback;
54 - delete timers[token];
55 - callback();
56 - } else if (timers[token].type == 'interval') {
57 - // for 'interval', run callback and set the next invoke time
58 - // Add some random msecs to the delay to mimic code execution time.
59 - timers[token].time =
60 - now + timers[token].interval + Math.floor(Math.random() * 5);
61 - timers[token].callback();
62 - }
63 - }
64 -}
65 -
66 -function _runTimersOnce() {
67 - // Invoke all timers once regardsless of the delay
68 - for (var token in timers) {
69 - _runTimer(token);
70 - }
71 -}
72 -
73 -function _runTimersToTime(delay) {
74 - var toRunToken = _getNextTimerToken();
75 - if (!toRunToken) {
76 - return;
77 - }
78 -
79 - var minTime = timers[toRunToken].time;
80 - if (now + delay < minTime) {
81 - // Termination when there's no more timers to invoke
82 - now += delay;
83 - } else {
84 - // Recursively invoke the next to-run timer
85 - delay -= (minTime - now);
86 - now = minTime;
87 - _runTimer(toRunToken);
88 - _runTimersToTime(delay);
89 - }
90 -}
91 -
92 -function _runTimersRepeatedly() {
93 - // Only run a generous 1000 timers and then bail, since we may have entered
94 - // a loop if we have more than that.
95 - var max_timers = 1000;
96 -
97 - var token;
98 - for (var ii = 0; ii < max_timers; ii++) {
99 - token = _getNextTimerToken();
100 -
101 - if (!token) {
102 - break;
103 - }
104 -
105 - _runTimer(token);
106 - }
107 -
108 - if (ii === max_timers) {
109 - throw new Error("More timers still exist after " + max_timers + " timers!");
110 - }
111 -}
112 -
113 -function _clearTimers() {
114 - for (var token in timers) {
115 - delete timers[token];
116 - }
117 -}
118 -
119 -function _getNextTimerToken() {
120 - var nextTimerToken = null;
121 - var minTime = 31536000000; // One year
122 - // Find the next to invoke timer
123 - for (var token in timers) {
124 - if (timers[token].time < minTime) {
125 - nextTimerToken = token;
126 - minTime = timers[token].time;
127 - }
128 - }
129 - return nextTimerToken;
130 -}
131 -
132 -var mockTimers = {
133 - setTimeout: _setTimeout,
134 - clearTimeout: _clearTimeout,
135 - setInterval: _setInterval,
136 - clearInterval: _clearInterval,
137 -
138 - /**
139 - * Copyright 2013 Facebook, Inc.
140 - *
141 - * Licensed under the Apache License, Version 2.0 (the "License");
142 - * you may not use this file except in compliance with the License.
143 - * You may obtain a copy of the License at
144 - *
145 - * http://www.apache.org/licenses/LICENSE-2.0
146 - *
147 - * Unless required by applicable law or agreed to in writing, software
148 - * distributed under the License is distributed on an "AS IS" BASIS,
149 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150 - * See the License for the specific language governing permissions and
151 - * limitations under the License.
152 - *
153 - * Iteratively run callbacks in time order during the time from now to
154 - * now + delay.
155 - * If one callback register another timer which should be run during now to
156 - * now + delay, the new timer will also be run in the right order.
157 - *
158 - * @param delay
159 - */
160 - runTimersToTime: _runTimersToTime,
161 -
162 - /**
163 - * Run all registered timer once. Newly registered timers will not be run.
164 - */
165 - runTimersOnce: _runTimersOnce,
166 -
167 - /**
168 - * Iteratively run callbacks until there are no timers left to call. Will
169 - * stop after a maximum number of iterations to avoid infinite loop.
170 - *
171 - * @param maximum iterations (optional)
172 - */
173 - runTimersRepeatedly: _runTimersRepeatedly,
174 -
175 - /**
176 - * Clear all timers
177 - */
178 - clearTimers: _clearTimers,
179 -
180 - /**
181 - * Get the number of remaining timers
182 - */
183 - getTimersCount: function() {
184 - return Object.keys(timers).length;
185 - }
186 -};
187 -
188 -module.exports.installMockTimers = function(window) {
189 - window._originalTimeouts = {
190 - setTimeout: window.setTimeout,
191 - clearTimeout: window.clearTimeout,
192 - setInterval: window.setInterval,
193 - clearInterval: window.clearInterval
194 - };
195 - window.setTimeout =
196 - mocks.getMockFunction().mockImplementation(mockTimers.setTimeout);
197 - window.clearTimeout =
198 - mocks.getMockFunction().mockImplementation(mockTimers.clearTimeout);
199 - window.setInterval =
200 - mocks.getMockFunction().mockImplementation(mockTimers.setInterval);
201 - window.clearInterval =
202 - mocks.getMockFunction().mockImplementation(mockTimers.clearInterval);
203 - window.mockRunTimersOnce =
204 - mocks.getMockFunction().mockImplementation(mockTimers.runTimersOnce);
205 - window.mockRunTimersToTime =
206 - mocks.getMockFunction().mockImplementation(mockTimers.runTimersToTime);
207 - window.mockRunTimersRepeatedly =
208 - mocks.getMockFunction().mockImplementation(mockTimers.runTimersRepeatedly);
209 - window.mockClearTimers =
210 - mocks.getMockFunction().mockImplementation(mockTimers.clearTimers);
211 - window.mockGetTimersCount =
212 - mocks.getMockFunction().mockImplementation(mockTimers.getTimersCount);
213 -};
214 -
215 -module.exports.uninstallMockTimers = function(window) {
216 - window.setTimeout = window._originalTimeouts.setTimeout;
217 - window.clearTimeout = window._originalTimeouts.clearTimeout;
218 - window.setInterval = window._originalTimeouts.setInterval;
219 - window.clearInterval = window._originalTimeouts.clearInterval;
220 - window._originalTimeouts = undefined;
221 - window.mockRunTimersOnce = undefined;
222 - window.mockRunTimersToTime = undefined;
223 - window.mockRunTimersRepeatedly = undefined;
224 - window.mockClearTimers = undefined;
225 - window.mockGetTimersCount = undefined;
226 -};
React/throwIf.js deleted
-27
@@ -1,27 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @providesModule throwIf
17 - */
18 -
19 -"use strict";
20 -
21 -var throwIf = function(condition, err) {
22 - if (condition) {
23 - throw new Error(err);
24 - }
25 -};
26 -
27 -module.exports = throwIf;
React/utils/__tests__/ImmutableObject-test.js deleted
-293
@@ -1,293 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -require("../../mock-modules")
22 - .dontMock('ImmutableObject');
23 -
24 -var ImmutableObject;
25 -
26 -var expectSeriallyEqual = function(one, two) {
27 -};
28 -
29 -/**
30 - * To perform performance testing of using `ImmutableObject` vs. not using
31 - * `ImmutableObject`, such testing must be done with __DEV__ set to false.
32 - */
33 -describe('ImmutableObject', function() {
34 - var message;
35 - beforeEach(function() {
36 - require("../../mock-modules").dumpCache();
37 - ImmutableObject = require("../../ImmutableObject");
38 - this.addMatchers({
39 - /**
40 - * Equivalent with respect to serialization. Must stringify because
41 - * constructors are different and other comparison methods will not
42 - * consider them structurally equal. Probably not useful for use outside
43 - * of this test module.
44 - */
45 - toBeSeriallyEqualTo: function(expected) {
46 - var actual = this.actual;
47 - var notText = this.isNot ? " not" : "";
48 - this.message = function () {
49 - return "Expected " + JSON.stringify(actual) + notText +
50 - " to be serially equal to " + JSON.stringify(expected);
51 - };
52 -
53 - return JSON.stringify(actual) === JSON.stringify(expected);
54 - }
55 - });
56 - });
57 -
58 - /**
59 - * We are in __DEV__ by default.
60 - */
61 - var testDev = function(message, testFunc) {
62 - it(message, testFunc);
63 - };
64 -
65 - var testProd = function(message, testFunc) {
66 - // Temporarily enter production mode
67 - window.true = false;
68 - it(message, testFunc);
69 - window.true = true;
70 - };
71 -
72 - var testDevAndProd = function(message, testFunc) {
73 - testDev(message + ':DEV', testFunc);
74 - testProd(message + ':PROD', testFunc);
75 - };
76 -
77 - testDev('should be running in DEV', function() {
78 - expect(window.true).toBe(true);
79 - });
80 -
81 - testDev('should require initial map to be an object', function() {
82 - expect(function() {
83 - new ImmutableObject([1,2,3]);
84 - }).toThrow();
85 -
86 - expect(function() {
87 - new ImmutableObject('asdf');
88 - }).toThrow();
89 -
90 - expect(function() {
91 - new ImmutableObject({oldField: 'asdf', fieldTwo: null});
92 - }).not.toThrow();
93 - });
94 -
95 - testDevAndProd('should not throw when not mutating directly', function() {
96 - var io = new ImmutableObject({oldField: 'asdf'});
97 - expect(function() {
98 - ImmutableObject.set(io, {newField: null}); // not a mutation!
99 - }).not.toThrow();
100 - });
101 -
102 - testDev('should prevent shallow field addition when strict', function() {
103 - if (window.callPhantom) return;
104 - expect(function() {
105 - var io = new ImmutableObject({oldField: 'asdf'});
106 - io.newField = 'this will not work';
107 - }).toThrow();
108 - });
109 -
110 - testDev('should prevent shallow field mutation when strict', function() {
111 - if (window.callPhantom) return;
112 - expect(function() {
113 - var io = new ImmutableObject({oldField: 'asdf'});
114 - io.oldField = 'this will not work!';
115 - }).toThrow();
116 - });
117 -
118 - testDev('should prevent deep field addition when strict', function() {
119 - if (window.callPhantom) return;
120 - expect(function() {
121 - var io =
122 - new ImmutableObject({shallowField: {deepField: {oldField: null}}});
123 - io.shallowField.deepField.oldField = 'this will not work!';
124 - }).toThrow();
125 - });
126 -
127 - testDev('should prevent deep field mutation when strict', function() {
128 - if (window.callPhantom) return;
129 - expect(function() {
130 - var io =
131 - new ImmutableObject({shallowField: {deepField: {oldField: null}}});
132 - io.shallowField.deepField.newField = 'this will not work!';
133 - }).toThrow();
134 - });
135 -
136 - testDevAndProd(
137 - 'should create object with same structure when set with {}',
138 - function() {
139 - var beforeIO =
140 - new ImmutableObject({shallowField: {deepField: {oldField: null}}});
141 - var afterIO = ImmutableObject.set(beforeIO, {});
142 - expect(afterIO).toBeSeriallyEqualTo(beforeIO);
143 - expect(afterIO).not.toBe(beforeIO);
144 - }
145 - );
146 -
147 - testDevAndProd(
148 - 'should create distinct object with shallow field insertion',
149 - function() {
150 - var beforeStructure = {
151 - oldShallowField: {
152 - deepField: {
153 - oldField: null
154 - }
155 - }
156 - };
157 -
158 - var delta = {
159 - newShallowField: 'newShallowFieldHere'
160 - };
161 -
162 - var expectedAfterStructure = {
163 - oldShallowField: {
164 - deepField: {
165 - oldField: null
166 - }
167 - },
168 - newShallowField: 'newShallowFieldHere'
169 - };
170 -
171 - var beforeIO = new ImmutableObject(beforeStructure);
172 - var afterIO = ImmutableObject.set(beforeIO, delta);
173 - expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);
174 - expect(afterIO).not.toBe(beforeIO);
175 - }
176 - );
177 -
178 - testDevAndProd(
179 - 'should create distinct object with shallow field mutation',
180 - function() {
181 - var beforeStructure = {
182 - oldShallowField: {
183 - deepField: {
184 - oldField: null
185 - }
186 - }
187 - };
188 -
189 - var delta = {
190 - oldShallowField: 'this will clobber the old field'
191 - };
192 -
193 - var expectedAfterStructure = {
194 - oldShallowField: 'this will clobber the old field'
195 - };
196 -
197 - var beforeIO = new ImmutableObject(beforeStructure);
198 - var afterIO = ImmutableObject.set(beforeIO, delta);
199 - expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);
200 - expect(afterIO).not.toBe(beforeIO);
201 - }
202 - );
203 -
204 - message = 'should create distinct object with deep field insertion';
205 - testDevAndProd(message, function() {
206 - var beforeStructure = {
207 - oldShallowField: {
208 - deepField: {
209 - oldField: null
210 - }
211 - }
212 - };
213 -
214 - var delta = {
215 - oldShallowField: {newDeepField: 'hello'}
216 - };
217 -
218 - // ImmutableObject does not yet support deep merging with
219 - // ImmutableObject.set().
220 - var expectedAfterStructure = {
221 - oldShallowField: {newDeepField: 'hello'}
222 - };
223 -
224 - var beforeIO = new ImmutableObject(beforeStructure);
225 - var afterIO = ImmutableObject.set(beforeIO, delta);
226 - expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);
227 - expect(afterIO).not.toBe(beforeIO);
228 - });
229 -
230 - message =
231 - 'should tolerate arrays at deeper levels and prevent mutation on them';
232 - testDevAndProd(message, function() {
233 - if (window.callPhantom) {
234 - // PhantomJS has a bug with Object.freeze and Arrays.
235 - // https://github.com/ariya/phantomjs/issues/10817
236 - return;
237 - }
238 - var beforeStructure = {
239 - shallowField: [1,'second field',3]
240 - };
241 - var io = new ImmutableObject(beforeStructure);
242 - expect(function() {
243 - io.newField = 'nope!';
244 - }).toThrow();
245 - expect(function() {
246 - io.shallowField[0] = 'nope!';
247 - }).toThrow();
248 - expect(io.shallowField[1]).toEqual('second field');
249 - });
250 -
251 - message = 'should provide a setField interface as sugar for set()';
252 - testDevAndProd(message, function() {
253 - var beforeIO = new ImmutableObject({initialField: null});
254 - var afterIO =
255 - ImmutableObject.setField(beforeIO, 'anotherField', 'anotherValue');
256 - expect(afterIO).toBeSeriallyEqualTo({
257 - initialField: null,
258 - anotherField: 'anotherValue'
259 - });
260 - expect(afterIO).not.toBe(beforeIO);
261 - });
262 -
263 - message = 'should recursively create distinct objects when deep copying';
264 - testDevAndProd(message, function() {
265 - var beforeIO = new ImmutableObject({
266 - a: {b: 'b', c: {}, d: 'd', e: new ImmutableObject({f: 'f'}) }
267 - });
268 - var afterIO = ImmutableObject.setDeep(beforeIO, {
269 - a: {b: {}, c: 'C', e: {f: 'F', g: 'G'}, h: 'H'}
270 - });
271 - expect(afterIO).toBeSeriallyEqualTo({
272 - a: {b: {}, c: 'C', d: 'd', e: {f: 'F', g: 'G'}, h: 'H'}
273 - })
274 - expect(afterIO).not.toBe(beforeIO);
275 - expect(afterIO.a).not.toBe(beforeIO.a);
276 - expect(afterIO.a.e).not.toBe(beforeIO.a.e);
277 - });
278 -
279 - testDevAndProd('should deep copy member immutability', function() {
280 - var beforeIO = new ImmutableObject({
281 - a: {b: new ImmutableObject({c: 'c'}), e: {f: 'f'}}
282 - });
283 - var afterIO = ImmutableObject.setDeep(beforeIO, {
284 - a: {b: {d: 'D'}, e: new ImmutableObject({g: 'G'})}
285 - });
286 - expect(afterIO).toBeSeriallyEqualTo({
287 - a: {b: {c: 'c', d: 'D'}, e: {f: 'f', g: 'G'}}
288 - });
289 - expect(afterIO instanceof ImmutableObject).toBe(true);
290 - expect(afterIO.a.b instanceof ImmutableObject).toBe(true);
291 - expect(afterIO.a.e instanceof ImmutableObject).toBe(true);
292 - });
293 -});
React/utils/__tests__/OrderedMap-test.js deleted
-944
@@ -1,944 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -var OrderedMap;
22 -
23 -/**
24 - * Shared, reusable objects.
25 - */
26 -var hasEmptyStringKey = {
27 - 'thisKeyIsFine': {data: []},
28 - '': {thisShouldCauseAFailure: []},
29 - 'thisKeyIsAlsoFine': {data: []}
30 -};
31 -
32 -/**
33 - * Used as map/forEach callback.
34 - */
35 -var duplicate = function(itm, key, count) {
36 - return {
37 - uniqueID: itm.uniqueID,
38 - val: itm.val + key + count + this.justToTestScope
39 - };
40 -};
41 -
42 -// Should not be allowed - because then null/'null' become impossible to
43 -// distinguish. Every key MUST be a string period!
44 -var hasNullAndUndefStringKey = [
45 - {uniqueID: 'undefined', val: 'thisIsUndefined'},
46 - {uniqueID: 'null', val: 'thisIsNull'}
47 -];
48 -var hasNullKey = [
49 - {uniqueID: 'thisKeyIsFine', data: []},
50 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
51 - {uniqueID: null, data: []}
52 -];
53 -
54 -var hasObjectKey = [
55 - {uniqueID: 'thisKeyIsFine', data: []},
56 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
57 - {uniqueID: {}, data: []}
58 -];
59 -
60 -var hasArrayKey = [
61 - {uniqueID: 'thisKeyIsFine', data: []},
62 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
63 - {uniqueID: [], data: []}
64 -];
65 -
66 -// This should be allowed
67 -var hasNullStringKey = [
68 - {uniqueID: 'thisKeyIsFine', data: []},
69 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
70 - {uniqueID: 'null', data: []}
71 -];
72 -
73 -var hasUndefinedKey = [
74 - {uniqueID: 'thisKeyIsFine', data: []},
75 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
76 - {uniqueID: undefined, data: []}
77 -];
78 -
79 -var hasUndefinedStringKey = [
80 - {uniqueID: 'thisKeyIsFine', data: []},
81 - {uniqueID: 'thisKeyIsAlsoFine', data: []},
82 - {uniqueID: 'undefined', data: []}
83 -];
84 -
85 -var hasPositiveNumericKey = [
86 - {uniqueID: 'notANumber', data: []},
87 - {uniqueID: '5', data: []},
88 - {uniqueID: 'notAnotherNumber',data: []}
89 -];
90 -
91 -var hasZeroStringKey = [
92 - {uniqueID: 'greg', data: 'grego'},
93 - {uniqueID: '0', data: '0o'},
94 - {uniqueID: 'tom', data: 'tomo'}
95 -];
96 -
97 -var hasZeroNumberKey = [
98 - {uniqueID: 'greg', data: 'grego'},
99 - {uniqueID: 0, data: '0o'},
100 - {uniqueID: 'tom', data: 'tomo'}
101 -];
102 -
103 -var hasAllNumericStringKeys = [
104 - {uniqueID: '0', name: 'Gregory'},
105 - {uniqueID: '2', name: 'James'},
106 - {uniqueID: '1', name: 'Tom'}
107 -];
108 -
109 -var hasAllNumericKeys = [
110 - {uniqueID: 0, name: 'Gregory'},
111 - {uniqueID: 2, name: 'James'},
112 - {uniqueID: 1, name: 'Tom'}
113 -];
114 -
115 -var hasAllValidKeys = [
116 - {uniqueID: 'keyOne', value: 'valueOne'},
117 - {uniqueID: 'keyTwo', value: 'valueTwo'}
118 -];
119 -
120 -var hasDuplicateKeys = [
121 - {uniqueID: 'keyOne', value: 'valueOne'},
122 - {uniqueID: 'keyTwo', value: 'valueTwo'},
123 - {uniqueID: 'keyOne', value: 'valueThree'}
124 -];
125 -
126 -var idEntities = [
127 - {uniqueID: 'greg', name: 'Gregory'},
128 - {uniqueID: 'james', name: 'James'},
129 - {uniqueID: 'tom', name: 'Tom'}
130 -];
131 -
132 -var hasEmptyKey = [
133 - {uniqueID: 'greg', name: 'Gregory'},
134 - {uniqueID: '', name: 'James'},
135 - {uniqueID: 'tom', name: 'Tom'}
136 -];
137 -
138 -var extractUniqueID = function(entity) {
139 - return entity.uniqueID;
140 -};
141 -
142 -describe('OrderedMap', function() {
143 - beforeEach(function() {
144 - require("../../mock-modules").dumpCache();
145 - OrderedMap = require("../../OrderedMap");
146 - });
147 -
148 - it('should create according to simple object with keys', function() {
149 - OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
150 - // Iterate over and ensure key order.
151 - });
152 -
153 - it('should create from array when providing an identity CB', function() {
154 - expect(function() {
155 - OrderedMap.fromArray(idEntities, extractUniqueID);
156 - }).not.toThrow();
157 - });
158 -
159 - it('should throw if constructing from Array without identity CB', function() {
160 - OrderedMap.fromArray(idEntities, extractUniqueID);
161 - // Iterate and ensure key order
162 - });
163 -
164 - it('should not throw when fromArray extracts a numeric key', function() {
165 - expect(function() {
166 - OrderedMap.fromArray(hasPositiveNumericKey, extractUniqueID);
167 - }).not.toThrow();
168 -
169 - });
170 -
171 - it('should throw when any key is the empty string', function() {
172 - expect(function() {
173 - OrderedMap.fromArray(hasEmptyKey, extractUniqueID);
174 - }).toThrow();
175 - });
176 -
177 - it('should not throw when a key is the string "undefined" or "null"',
178 - function() {
179 - var om = OrderedMap.fromArray(hasNullAndUndefStringKey, extractUniqueID);
180 - expect(om.length).toBe(2);
181 - expect(om.indexOfKey('undefined')).toBe(0);
182 - expect(om.indexOfKey('null')).toBe(1);
183 - expect(om.keyAfter('undefined')).toBe('null');
184 - expect(om.keyAfter('null')).toBe(undefined);
185 - expect(om.keyBefore('undefined')).toBe(undefined);
186 - expect(om.has('undefined')).toBe(true);
187 - expect(om.has('null')).toBe(true);
188 - expect(om.get('undefined').val).toBe('thisIsUndefined');
189 - expect(om.get('null').val).toBe('thisIsNull');
190 - });
191 -
192 -
193 - /**
194 - * Numeric keys are cast to strings.
195 - */
196 - it('should not throw when a key is the number zero', function() {
197 - var om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);
198 - expect(om.length).toBe(3);
199 - expect(om.indexOfKey('0')).toBe(1);
200 - expect(om.indexOfKey(0)).toBe(1);
201 - });
202 -
203 - it('should throw when any key is falsey', function() {
204 - expect(function() {
205 - OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);
206 - }).toThrow();
207 -
208 - expect(function() {
209 - OrderedMap.fromArray(hasNullKey, extractUniqueID);
210 - }).toThrow();
211 -
212 - expect(function() {
213 - OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);
214 - }).toThrow();
215 - });
216 -
217 - it('should not throw on string keys "undefined/null"', function() {
218 - expect(function() {
219 - OrderedMap.fromArray(hasNullStringKey, extractUniqueID);
220 - }).not.toThrow();
221 -
222 - expect(function() {
223 - OrderedMap.fromArray(hasUndefinedStringKey, extractUniqueID);
224 - }).not.toThrow();
225 - });
226 -
227 - it('should throw on extracting keys that are not strings/nums', function() {
228 - expect(function() {
229 - OrderedMap.fromArray(hasObjectKey, extractUniqueID);
230 - }).toThrow();
231 -
232 - expect(function() {
233 - OrderedMap.fromArray(hasArrayKey, extractUniqueID);
234 - }).toThrow();
235 - });
236 -
237 - it('should throw if instantiating with duplicate key', function() {
238 - expect(function() {
239 - OrderedMap.fromArray(hasDuplicateKeys, extractUniqueID);
240 - }).toThrow();
241 - });
242 -
243 - it('should not throw when a key is the string "0"', function() {
244 - var verifyOM = function(om) {
245 - expect(om.length).toBe(3);
246 - expect(om.indexOfKey('greg')).toBe(0);
247 - expect(om.indexOfKey('0')).toBe(1);
248 - expect(om.indexOfKey(0)).toBe(1); // Casts on writes and reads.
249 - expect(om.indexOfKey('tom')).toBe(2);
250 - expect(om.keyAfter('greg')).toBe('0');
251 - expect(om.keyAfter('0')).toBe('tom');
252 - expect(om.keyAfter(0)).toBe('tom');
253 - expect(om.keyAfter('tom')).toBe(undefined);
254 - expect(om.keyBefore('greg')).toBe(undefined);
255 - expect(om.keyBefore(0)).toBe('greg');
256 - expect(om.keyBefore('0')).toBe('greg');
257 - expect(om.keyBefore('tom')).toBe('0');
258 - expect(om.has('undefined')).toBe(false);
259 - expect(om.has(0)).toBe(true);
260 - expect(om.has('0')).toBe(true);
261 - };
262 - var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);
263 - verifyOM(om);
264 - om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);
265 - verifyOM(om);
266 - });
267 -
268 - it('should throw when getting invalid public key', function() {
269 - var om = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
270 - expect(function() {
271 - om.has(undefined);
272 - }).toThrow();
273 - expect(function() {
274 - om.get(undefined);
275 - }).toThrow();
276 - expect(function() {
277 - om.has(null);
278 - }).toThrow();
279 - expect(function() {
280 - om.get(null);
281 - }).toThrow();
282 - expect(function() {
283 - om.has('');
284 - }).toThrow();
285 - expect(function() {
286 - om.get('');
287 - }).toThrow();
288 - });
289 -
290 - it('should throw when any key is falsey', function() {
291 - expect(function() {
292 - OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);
293 - }).toThrow();
294 -
295 - expect(function() {
296 - OrderedMap.fromArray(hasNullKey, extractUniqueID);
297 - }).toThrow();
298 -
299 - expect(function() {
300 - OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);
301 - }).toThrow();
302 - });
303 -
304 -
305 - it('should throw when fromArray is passed crazy args', function() {
306 - // Test passing another OrderedMap (when it expects a plain object.)
307 - // This is probably not what you meant to do! We should error.
308 - var validOM = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);
309 - expect(function() {
310 - OrderedMap.fromArray({uniqueID: 'asdf'}, extractUniqueID);
311 - }).toThrow();
312 - expect(function() {
313 - OrderedMap.fromArray(validOM, extractUniqueID);
314 - }).toThrow();
315 - });
316 -
317 - it('should throw when fromArray is passed crazy things', function() {
318 - expect(function() {
319 - OrderedMap.fromArray(null, extractUniqueID);
320 - }).toThrow();
321 - expect(function() {
322 - OrderedMap.fromArray('stringgg', extractUniqueID);
323 - }).toThrow();
324 - expect(function() {
325 - OrderedMap.fromArray(undefined, extractUniqueID);
326 - }).toThrow();
327 - expect(function() {
328 - OrderedMap.fromArray(new Date(), extractUniqueID);
329 - }).toThrow();
330 - expect(function() {
331 - OrderedMap.fromArray({}, extractUniqueID);
332 - }).toThrow();
333 -
334 - // Test failure without extractor
335 - expect(function() {
336 - OrderedMap.fromArray(idEntities);
337 - }).toThrow();
338 - expect(function() {
339 - OrderedMap.fromArray(idEntities, extractUniqueID);
340 - }).not.toThrow();
341 - });
342 -
343 - // Testing methods that accept other `OrderedMap`s.
344 - it('should throw when from/merge is passed an non-OrderedMap.', function() {
345 - // Test passing an array to construction.
346 - expect(function() {
347 - OrderedMap.from(idEntities, extractUniqueID);
348 - }).toThrow();
349 -
350 - // Test passing an array to merge.
351 - expect(function() {
352 - OrderedMap.fromArray(idEntities, extractUniqueID)
353 - .merge(idEntities, extractUniqueID);
354 - }).toThrow();
355 -
356 -
357 - // Test passing a plain object to merge.
358 - expect(function() {
359 - OrderedMap.fromArray(
360 - idEntities,
361 - extractUniqueID
362 - ).merge({blah: 'willFail'});
363 - }).toThrow();
364 - });
365 -
366 - it('should throw when accessing key before/after of non-key', function() {
367 - var om = OrderedMap.fromArray([
368 - {uniqueID: 'first'},
369 - {uniqueID: 'two'}], extractUniqueID
370 - );
371 - expect(function() {
372 - om.keyBefore('dog');
373 - }).toThrow();
374 - expect(function() {
375 - om.keyAfter('cat');
376 - }).toThrow();
377 - expect(function() {
378 - om.keyAfter(null);
379 - }).toThrow();
380 - expect(function() {
381 - om.keyAfter(undefined);
382 - }).toThrow();
383 - });
384 -
385 - it('should throw passing invalid/not-present-keys to before/after',
386 - function() {
387 - var om = OrderedMap.fromArray([
388 - {uniqueID: 'one', val: 'first'},
389 - {uniqueID: 'two', val: 'second'},
390 - {uniqueID: 'three', val: 'third'},
391 - {uniqueID: 'four', val: 'fourth'}
392 - ], extractUniqueID);
393 -
394 - expect(function() {
395 - om.keyBefore('');
396 - }).toThrow();
397 - expect(function() {
398 - om.keyBefore(null);
399 - }).toThrow();
400 - expect(function() {
401 - om.keyBefore(undefined);
402 - }).toThrow();
403 - expect(function() {
404 - om.keyBefore('notInTheOrderedMap!');
405 - }).toThrow();
406 -
407 - expect(function() {
408 - om.keyAfter('');
409 - }).toThrow();
410 - expect(function() {
411 - om.keyAfter(null);
412 - }).toThrow();
413 - expect(function() {
414 - om.keyAfter(undefined);
415 - }).toThrow();
416 - expect(function() {
417 - om.keyAfter('notInTheOrderedMap!');
418 - }).toThrow();
419 -
420 - expect(function() {
421 - om.nthKeyAfter('', 1);
422 - }).toThrow();
423 - expect(function() {
424 - om.nthKeyAfter(null, 1);
425 - }).toThrow();
426 - expect(function() {
427 - om.nthKeyAfter(undefined, 1);
428 - }).toThrow();
429 - expect(function() {
430 - om.nthKeyAfter('notInTheOrderedMap!', 1);
431 - }).toThrow();
432 -
433 - expect(function() {
434 - om.nthKeyBefore('', 1);
435 - }).toThrow();
436 - expect(function() {
437 - om.nthKeyBefore(null, 1);
438 - }).toThrow();
439 - expect(function() {
440 - om.nthKeyBefore(undefined, 1);
441 - }).toThrow();
442 - expect(function() {
443 - om.nthKeyBefore('notInTheOrderedMap!', 1);
444 - }).toThrow();
445 - });
446 -
447 - it('should correctly determine the nth key after before', function() {
448 - var om = OrderedMap.fromArray([
449 - {uniqueID: 'one', val: 'first'},
450 - {uniqueID: 'two', val: 'second'},
451 - {uniqueID: 'three', val: 'third'},
452 - {uniqueID: 'four', val: 'fourth'}
453 - ], extractUniqueID);
454 - expect(om.keyBefore('one')).toBe(undefined); // first key
455 - expect(om.keyBefore('two')).toBe('one');
456 - expect(om.keyBefore('three')).toBe('two');
457 - expect(om.keyBefore('four')).toBe('three');
458 -
459 - expect(om.keyAfter('one')).toBe('two'); // first key
460 - expect(om.keyAfter('two')).toBe('three');
461 - expect(om.keyAfter('three')).toBe('four');
462 - expect(om.keyAfter('four')).toBe(undefined);
463 -
464 - expect(om.nthKeyBefore('one', 0)).toBe('one'); // first key
465 - expect(om.nthKeyBefore('one', 1)).toBe(undefined);
466 - expect(om.nthKeyBefore('one', 2)).toBe(undefined);
467 - expect(om.nthKeyBefore('two', 0)).toBe('two');
468 - expect(om.nthKeyBefore('two', 1)).toBe('one');
469 - expect(om.nthKeyBefore('four', 0)).toBe('four');
470 - expect(om.nthKeyBefore('four', 1)).toBe('three');
471 -
472 - expect(om.nthKeyAfter('one', 0)).toBe('one');
473 - expect(om.nthKeyAfter('one', 1)).toBe('two');
474 - expect(om.nthKeyAfter('one', 2)).toBe('three');
475 - expect(om.nthKeyAfter('two', 0)).toBe('two');
476 - expect(om.nthKeyAfter('two', 1)).toBe('three');
477 - expect(om.nthKeyAfter('four', 0)).toBe('four');
478 - expect(om.nthKeyAfter('four', 1)).toBe(undefined);
479 - });
480 -
481 - it('should compute key indices correctly', function() {
482 - var om = OrderedMap.fromArray([
483 - {uniqueID: 'one', val: 'first'},
484 - {uniqueID: 'two', val: 'second'}
485 - ], extractUniqueID);
486 - expect(om.keyAtIndex(0)).toBe('one');
487 - expect(om.keyAtIndex(1)).toBe('two');
488 - expect(om.keyAtIndex(2)).toBe(undefined);
489 - expect(om.indexOfKey('one')).toBe(0);
490 - expect(om.indexOfKey('two')).toBe(1);
491 - expect(om.indexOfKey('nope')).toBe(undefined);
492 - expect(function() {
493 - om.indexOfKey(null);
494 - }).toThrow();
495 - expect(function() {
496 - om.indexOfKey(undefined);
497 - }).toThrow();
498 - expect(function() {
499 - om.indexOfKey(''); // Empty key is not allowed
500 - }).toThrow();
501 - });
502 -
503 - it('should compute indices on array that extracted numeric ids', function() {
504 - var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);
505 - expect(om.keyAtIndex(0)).toBe('greg');
506 - expect(om.keyAtIndex(1)).toBe('0');
507 - expect(om.keyAtIndex(2)).toBe('tom');
508 - expect(om.indexOfKey('greg')).toBe(0);
509 - expect(om.indexOfKey('0')).toBe(1);
510 - expect(om.indexOfKey('tom')).toBe(2);
511 -
512 -
513 - var verifyNumericKeys = function(om) {
514 - expect(om.keyAtIndex(0)).toBe('0');
515 - expect(om.keyAtIndex(1)).toBe('2');
516 - expect(om.keyAtIndex(2)).toBe('1');
517 - expect(om.indexOfKey('0')).toBe(0);
518 - expect(om.indexOfKey('2')).toBe(1); // Proove these are not ordered by
519 - expect(om.indexOfKey('1')).toBe(2); // their keys
520 - };
521 - var omStringNumberKeys =
522 - OrderedMap.fromArray(hasAllNumericStringKeys, extractUniqueID);
523 - verifyNumericKeys(omStringNumberKeys);
524 - var omNumericKeys =
525 - OrderedMap.fromArray(hasAllNumericKeys, extractUniqueID);
526 - verifyNumericKeys(omNumericKeys);
527 - });
528 -
529 - it('should compute indices on mutually exclusive merge', function() {
530 - var om = OrderedMap.fromArray([
531 - {uniqueID: 'one', val: 'first'},
532 - {uniqueID: 'two', val: 'second'}
533 - ], extractUniqueID);
534 - var om2 = OrderedMap.fromArray([
535 - {uniqueID: 'three', val: 'third'}
536 - ], extractUniqueID);
537 - var res = om.merge(om2);
538 -
539 - expect(res.length).toBe(3);
540 -
541 - expect(res.keyAtIndex(0)).toBe('one');
542 - expect(res.keyAtIndex(1)).toBe('two');
543 - expect(res.keyAtIndex(2)).toBe('three');
544 - expect(res.keyAtIndex(3)).toBe(undefined);
545 -
546 - expect(res.indexOfKey('one')).toBe(0);
547 - expect(res.indexOfKey('two')).toBe(1);
548 - expect(res.indexOfKey('three')).toBe(2);
549 - expect(res.indexOfKey('dog')).toBe(undefined);
550 -
551 - expect(res.has('one')).toBe(true);
552 - expect(res.has('two')).toBe(true);
553 - expect(res.has('three')).toBe(true);
554 - expect(res.has('dog')).toBe(false);
555 -
556 - expect(res.get('one').val).toBe('first');
557 - expect(res.get('two').val).toBe('second');
558 - expect(res.get('three').val).toBe('third');
559 - expect(res.get('dog')).toBe(undefined);
560 - });
561 -
562 - it('should compute indices on intersected merge', function() {
563 - var oneTwo = OrderedMap.fromArray([
564 - {uniqueID: 'one', val: 'first'},
565 - {uniqueID: 'two', val: 'secondOM1'}
566 - ], extractUniqueID);
567 -
568 - var testOneTwoMergedWithTwoThree = function(res) {
569 - expect(res.length).toBe(3);
570 - expect(res.keyAtIndex(0)).toBe('one');
571 - expect(res.keyAtIndex(1)).toBe('two');
572 - expect(res.keyAtIndex(2)).toBe('three');
573 - expect(res.keyAtIndex(3)).toBe(undefined);
574 - expect(res.indexOfKey('one')).toBe(0);
575 - expect(res.indexOfKey('two')).toBe(1);
576 - expect(res.indexOfKey('three')).toBe(2);
577 - expect(res.indexOfKey('dog')).toBe(undefined);
578 - expect(res.has('one')).toBe(true);
579 - expect(res.has('two')).toBe(true);
580 - expect(res.has('three')).toBe(true);
581 - expect(res.has('dog')).toBe(false);
582 - expect(res.get('one').val).toBe('first');
583 - expect(res.get('two').val).toBe('secondOM2');
584 - expect(res.get('three').val).toBe('third');
585 - expect(res.get('dog')).toBe(undefined);
586 - };
587 -
588 - var result =
589 - oneTwo.merge(OrderedMap.fromArray([
590 - {uniqueID: 'two', val: 'secondOM2'},
591 - {uniqueID: 'three', val: 'third'}
592 - ], extractUniqueID));
593 - testOneTwoMergedWithTwoThree(result);
594 -
595 - // Everything should be exactly as before, since the ordering of `two` was
596 - // already determined by `om`.
597 - result = oneTwo.merge(
598 - OrderedMap.fromArray([
599 - {uniqueID: 'three', val: 'third'},
600 - {uniqueID: 'two', val:'secondOM2'}
601 - ], extractUniqueID)
602 - );
603 - testOneTwoMergedWithTwoThree(result);
604 -
605 -
606 - var testTwoThreeMergedWithOneTwo = function(res) {
607 - expect(res.length).toBe(3);
608 - expect(res.keyAtIndex(0)).toBe('two');
609 - expect(res.keyAtIndex(1)).toBe('three');
610 - expect(res.keyAtIndex(2)).toBe('one');
611 - expect(res.keyAtIndex(3)).toBe(undefined);
612 - expect(res.indexOfKey('two')).toBe(0);
613 - expect(res.indexOfKey('three')).toBe(1);
614 - expect(res.indexOfKey('one')).toBe(2);
615 - expect(res.indexOfKey('cat')).toBe(undefined);
616 - expect(res.has('two')).toBe(true);
617 - expect(res.has('three')).toBe(true);
618 - expect(res.has('one')).toBe(true);
619 - expect(res.has('dog')).toBe(false);
620 - expect(res.get('one').val).toBe('first');
621 - expect(res.get('two').val).toBe('secondOM1');
622 - expect(res.get('three').val).toBe('third');
623 - expect(res.get('dog')).toBe(undefined);
624 - };
625 - result = OrderedMap.fromArray([
626 - {uniqueID: 'two', val: 'secondOM2'},
627 - {uniqueID: 'three', val: 'third'}
628 - ], extractUniqueID).merge(oneTwo);
629 - testTwoThreeMergedWithOneTwo(result);
630 -
631 - });
632 -
633 - it('should merge mutually exclusive keys to the end.', function() {
634 - var om = OrderedMap.fromArray([
635 - {uniqueID: 'one', val: 'first'},
636 - {uniqueID: 'two', val: 'second'}
637 - ], extractUniqueID);
638 - var om2 = OrderedMap.fromArray([
639 - {uniqueID: 'three', val: 'first'},
640 - {uniqueID: 'four', val: 'second'}
641 - ], extractUniqueID);
642 - var res = om.merge(om2);
643 - expect(res.length).toBe(4);
644 -
645 - });
646 -
647 - it('should map correctly', function() {
648 - var om = OrderedMap.fromArray([
649 - {uniqueID: 'x', val: 'xx'},
650 - {uniqueID: 'y', val: 'yy'},
651 - {uniqueID: 'z', val: 'zz'}
652 - ], extractUniqueID);
653 - var scope = {justToTestScope: 'justTestingScope'};
654 - var verifyResult = function(omResult) {
655 - expect(omResult.length).toBe(3);
656 - expect(omResult.keyAtIndex(0)).toBe('x');
657 - expect(omResult.keyAtIndex(1)).toBe('y');
658 - expect(omResult.keyAtIndex(2)).toBe('z');
659 - expect(omResult.get('x').val).toBe('xxx0justTestingScope');
660 - expect(omResult.get('y').val).toBe('yyy1justTestingScope');
661 - expect(omResult.get('z').val).toBe('zzz2justTestingScope');
662 - };
663 - var resultOM = om.map(function(itm, key, count) {
664 - return {
665 - uniqueID: itm.uniqueID,
666 - val: itm.val + key + count + this.justToTestScope
667 - };
668 - }, scope);
669 - verifyResult(resultOM);
670 -
671 - var resArray = [];
672 - om.forEach(function(itm, key, count) {
673 - resArray.push({
674 - uniqueID: itm.uniqueID,
675 - val: itm.val + key + count + this.justToTestScope
676 - });
677 - }, scope);
678 - resultOM = OrderedMap.fromArray(resArray, extractUniqueID);
679 - verifyResult(resultOM);
680 - });
681 -
682 - it('should filter correctly', function() {
683 - var om = OrderedMap.fromArray([
684 - {uniqueID: 'x', val: 'xx'},
685 - {uniqueID: 'y', val: 'yy'},
686 - {uniqueID: 'z', val: 'zz'}
687 - ], extractUniqueID);
688 - var scope = {justToTestScope: 'justTestingScope'};
689 -
690 - var filteringCallback = function(item, key, indexInOriginal) {
691 - expect(this).toBe(scope);
692 - expect(key === 'x' || key === 'y' || key === 'z').toBe(true);
693 - if (key === 'x') {
694 - expect(item.val).toBe('xx');
695 - expect(indexInOriginal).toBe(0);
696 - return false;
697 - } else if (key === 'y') {
698 - expect(item.val).toBe('yy');
699 - expect(indexInOriginal).toBe(1);
700 - return true;
701 - } else {
702 - expect(item.val).toBe('zz');
703 - expect(indexInOriginal).toBe(2);
704 - return true;
705 - }
706 - };
707 -
708 - var verifyResult = function(omResult) {
709 - expect(omResult.length).toBe(2);
710 - expect(omResult.keyAtIndex(0)).toBe('y');
711 - expect(omResult.keyAtIndex(1)).toBe('z');
712 - expect(omResult.has('x')).toBe(false);
713 - expect(omResult.has('z')).toBe(true);
714 - expect(omResult.get('z').val).toBe('zz');
715 - expect(omResult.has('y')).toBe(true);
716 - expect(omResult.get('y').val).toBe('yy');
717 - };
718 -
719 - var resultOM = om.filter(filteringCallback, scope);
720 - verifyResult(resultOM);
721 - });
722 -
723 - it('should throw when providing invalid ranges to ranging', function() {
724 - var om = OrderedMap.fromArray([
725 - {uniqueID: 'x', val: 'xx'},
726 - {uniqueID: 'y', val: 'yy'},
727 - {uniqueID: 'z', val: 'zz'}
728 - ], extractUniqueID);
729 - var scope = {justToTestScope: 'justTestingScope'};
730 -
731 - expect(function() {
732 - om.mapRange(duplicate, 0, 3, scope);
733 - }).not.toThrow();
734 - expect(function() {
735 - om.filterRange(duplicate, 0, 3, scope);
736 - }).not.toThrow();
737 - expect(function() {
738 - om.forEachRange(duplicate, 0, 3, scope);
739 - }).not.toThrow();
740 - expect(function() {
741 - om.mapKeyRange(duplicate, 'x' , 3, scope);
742 - }).not.toThrow();
743 - expect(function() {
744 - om.forEachKeyRange(duplicate, 'x', 3, scope);
745 - }).not.toThrow();
746 -
747 - expect(function() {
748 - om.mapRange(duplicate, 0, 4, scope);
749 - }).toThrow();
750 - expect(function() {
751 - om.filterRange(duplicate, 0, 4, scope);
752 - }).toThrow();
753 - expect(function() {
754 - om.forEachRange(duplicate, 0, 4, scope);
755 - }).toThrow();
756 - expect(function() {
757 - om.mapKeyRange(duplicate, 'x', null, scope);
758 - }).toThrow();
759 - expect(function() {
760 - om.forEachKeyRange(duplicate, 'x', null, scope);
761 - }).toThrow();
762 -
763 - expect(function() {
764 - om.mapRange(duplicate, -1, 1, scope);
765 - }).toThrow();
766 - expect(function() {
767 - om.filterRange(duplicate, -1, 1, scope);
768 - }).toThrow();
769 - expect(function() {
770 - om.forEachRange(duplicate, -1, 1, scope);
771 - }).toThrow();
772 - expect(function() {
773 - om.mapKeyRange(duplicate, null, 'y', scope);
774 - }).toThrow();
775 - expect(function() {
776 - om.forEachKeyRange(duplicate, null, 'y', scope);
777 - }).toThrow();
778 -
779 - expect(function() {
780 - om.mapRange(duplicate, 0, 0, scope);
781 - }).not.toThrow();
782 - expect(function() {
783 - om.filterRange(duplicate, 0, 0, scope);
784 - }).not.toThrow();
785 - expect(function() {
786 - om.forEachRange(duplicate, 0, 0, scope);
787 - }).not.toThrow();
788 - expect(function() {
789 - om.mapKeyRange(duplicate, 'x', 'x', scope);
790 - }).not.toThrow();
791 - expect(function() {
792 - om.forEachKeyRange(duplicate, 'x', 'x', scope);
793 - }).not.toThrow();
794 -
795 - expect(function() {
796 - om.mapRange(duplicate, 0, -1, scope);
797 - }).toThrow();
798 - expect(function() {
799 - om.filterRange(duplicate, 0, -1, scope);
800 - }).toThrow();
801 - expect(function() {
802 - om.forEachRange(duplicate, 0, -1, scope);
803 - }).toThrow();
804 - expect(function() {
805 - om.mapKeyRange(duplicate, 'x', null, scope);
806 - }).toThrow();
807 - expect(function() {
808 - om.forEachKeyRange(duplicate, 'x', null, scope);
809 - }).toThrow();
810 -
811 - expect(function() {
812 - om.mapRange(duplicate, 2, 1, scope);
813 - }).not.toThrow();
814 - expect(function() {
815 - om.filterRange(duplicate, 2, 1, scope);
816 - }).not.toThrow();
817 - expect(function() {
818 - om.forEachRange(duplicate, 2, 1, scope);
819 - }).not.toThrow();
820 - expect(function() {
821 - om.mapKeyRange(duplicate, 'z', 'z', scope);
822 - }).not.toThrow();
823 - expect(function() {
824 - om.forEachKeyRange(duplicate, 'z', 'z', scope);
825 - }).not.toThrow();
826 -
827 - expect(function() {
828 - om.mapRange(duplicate, 2, 2, scope);
829 - }).toThrow();
830 - expect(function() {
831 - om.filterRange(duplicate, 2, 2, scope);
832 - }).toThrow();
833 - expect(function() {
834 - om.forEachRange(duplicate, 2, 2, scope);
835 - }).toThrow();
836 - expect(function() {
837 - om.mapKeyRange(duplicate, 'z', null, scope);
838 - }).toThrow();
839 - expect(function() {
840 - om.forEachKeyRange(duplicate, 'z', null, scope);
841 - }).toThrow();
842 -
843 - // Provide keys in reverse order - should throw.
844 - expect(function() {
845 - om.mapKeyRange(duplicate, 'y', 'x', scope);
846 - }).toThrow();
847 - expect(function() {
848 - om.forEachKeyRange(duplicate, 'y', 'x', scope);
849 - }).toThrow();
850 - });
851 -
852 - // TEST length zero map, or keyrange start===end
853 -
854 - it('should map range correctly', function() {
855 - var om = OrderedMap.fromArray([
856 - {uniqueID: 'x', val: 'xx'},
857 - {uniqueID: 'y', val: 'yy'},
858 - {uniqueID: 'z', val: 'zz'}
859 - ], extractUniqueID);
860 - var scope = {justToTestScope: 'justTestingScope'};
861 - var verifyThreeItems = function(omResult) {
862 - expect(omResult.length).toBe(3);
863 - expect(omResult.keyAtIndex(0)).toBe('x');
864 - expect(omResult.keyAtIndex(1)).toBe('y');
865 - expect(omResult.keyAtIndex(2)).toBe('z');
866 - expect(omResult.get('x').val).toBe('xxx0justTestingScope');
867 - expect(omResult.get('y').val).toBe('yyy1justTestingScope');
868 - expect(omResult.get('z').val).toBe('zzz2justTestingScope');
869 - };
870 - var verifyFirstTwoItems = function(omResult) {
871 - expect(omResult.length).toBe(2);
872 - expect(omResult.keyAtIndex(0)).toBe('x');
873 - expect(omResult.keyAtIndex(1)).toBe('y');
874 - expect(omResult.get('x').val).toBe('xxx0justTestingScope');
875 - expect(omResult.get('y').val).toBe('yyy1justTestingScope');
876 - };
877 -
878 - var verifyLastTwoItems = function(omResult) {
879 - expect(omResult.length).toBe(2);
880 - expect(omResult.keyAtIndex(0)).toBe('y');
881 - expect(omResult.keyAtIndex(1)).toBe('z');
882 - expect(omResult.get('y').val).toBe('yyy1justTestingScope');
883 - expect(omResult.get('z').val).toBe('zzz2justTestingScope');
884 - };
885 -
886 - var verifyMiddleItem = function(omResult) {
887 - expect(omResult.length).toBe(1);
888 - expect(omResult.keyAtIndex(0)).toBe('y');
889 - expect(omResult.get('y').val).toBe('yyy1justTestingScope');
890 - };
891 -
892 - var verifyEmpty = function(omResult) {
893 - expect(omResult.length).toBe(0);
894 - };
895 -
896 - var omResultThree = om.mapRange(duplicate, 0, 3, scope);
897 - verifyThreeItems(omResultThree);
898 - var resArray = [];
899 - var pushToResArray = function(itm, key, count) {
900 - resArray.push({
901 - uniqueID: itm.uniqueID,
902 - val: itm.val + key + count + this.justToTestScope
903 - });
904 - };
905 -
906 - om.forEachRange(pushToResArray, 0, 3, scope);
907 - omResultThree = OrderedMap.fromArray(resArray, extractUniqueID);
908 - verifyThreeItems(omResultThree);
909 -
910 - var omResultFirstTwo = om.mapRange(duplicate, 0, 2, scope);
911 - verifyFirstTwoItems(omResultFirstTwo);
912 - resArray = [];
913 - om.forEachRange(pushToResArray, 0, 2, scope);
914 - omResultFirstTwo = OrderedMap.fromArray(resArray, extractUniqueID);
915 - verifyFirstTwoItems(omResultFirstTwo);
916 -
917 - var omResultLastTwo = om.mapRange(duplicate, 1, 2, scope);
918 - verifyLastTwoItems(omResultLastTwo);
919 - resArray = [];
920 - om.forEachRange(pushToResArray, 1, 2, scope);
921 - omResultLastTwo = OrderedMap.fromArray(resArray, extractUniqueID);
922 - verifyLastTwoItems(omResultLastTwo);
923 -
924 - var omResultMiddle = om.mapRange(duplicate, 1, 1, scope);
925 - verifyMiddleItem(omResultMiddle);
926 - resArray = [];
927 - om.forEachRange(pushToResArray, 1, 1, scope);
928 - omResultMiddle = OrderedMap.fromArray(resArray, extractUniqueID);
929 - verifyMiddleItem(omResultMiddle);
930 -
931 - var omResultNone = om.mapRange(duplicate, 1, 0, scope);
932 - verifyEmpty(omResultNone);
933 - });
934 -
935 - it('should extract the original array correctly', function() {
936 - var sourceArray = [
937 - {uniqueID: 'x', val: 'xx'},
938 - {uniqueID: 'y', val: 'yy'},
939 - {uniqueID: 'z', val: 'zz'}
940 - ];
941 - var om = OrderedMap.fromArray(sourceArray, extractUniqueID);
942 - expect(om.toArray()).toEqual(sourceArray);
943 - });
944 -});
React/utils/__tests__/Transaction-test.js deleted
-314
@@ -1,314 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -var Transaction;
22 -var mixInto;
23 -
24 -var INIT_ERRORED = 'initErrored'; // Just a dummy value to check for.
25 -describe('Transaction', function() {
26 - beforeEach(function() {
27 - require("../../mock-modules").dumpCache();
28 - Transaction = require("../../Transaction");
29 - mixInto = require("../../mixInto");
30 - });
31 -
32 - /**
33 - * We should not invoke closers for inits that failed. We should pass init
34 - * return values to closers when those inits are successful. We should not
35 - * invoke the actual method when any of the initializers fail.
36 - */
37 - it('should invoke closers with/only-with init returns', function() {
38 - var throwInInit = function() {
39 - throw new Error('close[0] should receive Transaction.OBSERVED_ERROR');
40 - };
41 -
42 - var performSideEffect;
43 - var dontPerformThis = function() {
44 - performSideEffect = 'This should never be set to this';
45 - };
46 -
47 - /**
48 - * New test Transaction subclass.
49 - */
50 - var TestTransaction = function() {
51 - this.reinitializeTransaction();
52 - this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else
53 - this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
54 - this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else
55 - };
56 - mixInto(TestTransaction, Transaction.Mixin);
57 - TestTransaction.prototype.getTransactionWrappers = function() {
58 - return [
59 - {
60 - initialize: throwInInit,
61 - close: function(initResult) {
62 - this.firstCloseParam = initResult;
63 - }
64 - },
65 - {
66 - initialize: function() { return 'asdf'; },
67 - close: function(initResult) {
68 - this.secondCloseParam = initResult;
69 - }
70 - },
71 - {
72 - initialize: throwInInit,
73 - close: function(initResult) {
74 - this.lastCloseParam = initResult;
75 - }
76 - }
77 - ];
78 - };
79 -
80 - var transaction = new TestTransaction();
81 -
82 - expect(function() {
83 - transaction.perform(dontPerformThis);
84 - }).toThrow();
85 -
86 - expect(performSideEffect).toBe(undefined);
87 - expect(transaction.firstCloseParam).toBe(INIT_ERRORED);
88 - expect(transaction.secondCloseParam).toBe('asdf');
89 - expect(transaction.lastCloseParam).toBe(INIT_ERRORED);
90 - expect(transaction.isInTransaction()).toBe(false);
91 - });
92 -
93 - it('should invoke closers and wrapped method when inits success', function() {
94 -
95 - var performSideEffect;
96 - /**
97 - * New test Transaction subclass.
98 - */
99 - var TestTransaction = function() {
100 - this.reinitializeTransaction();
101 - this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else
102 - this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
103 - this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else
104 - };
105 - mixInto(TestTransaction, Transaction.Mixin);
106 - TestTransaction.prototype.getTransactionWrappers = function() {
107 - return [
108 - {
109 - initialize: function() {
110 - return 'firstResult';
111 - },
112 - close: function(initResult) {
113 - this.firstCloseParam = initResult;
114 - }
115 - },
116 - {
117 - initialize: function() {
118 - return 'secondResult';
119 - },
120 - close: function(initResult) {
121 - this.secondCloseParam = initResult;
122 - }
123 - },
124 - {
125 - initialize: function() {
126 - return 'thirdResult';
127 - },
128 - close: function(initResult) {
129 - this.lastCloseParam = initResult;
130 - }
131 - }
132 - ];
133 - };
134 -
135 - var transaction = new TestTransaction();
136 -
137 - transaction.perform(function() {
138 - performSideEffect = 'SIDE_EFFECT';
139 - });
140 -
141 - expect(performSideEffect).toBe('SIDE_EFFECT');
142 - expect(transaction.firstCloseParam).toBe('firstResult');
143 - expect(transaction.secondCloseParam).toBe('secondResult');
144 - expect(transaction.lastCloseParam).toBe('thirdResult');
145 - expect(transaction.isInTransaction()).toBe(false);
146 - });
147 -
148 - /**
149 - * When the operation throws, the transaction should throw, but all of the
150 - * error-free closers should execute gracefully without issue. If a closer
151 - * throws an error, the transaction should prefer to throw the error
152 - * encountered earlier in the operation.
153 - */
154 - it('should throw when wrapped operation throws', function() {
155 -
156 - var performSideEffect;
157 - /**
158 - * New test Transaction subclass.
159 - */
160 - var TestTransaction = function() {
161 - this.reinitializeTransaction();
162 - this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else
163 - this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
164 - this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else
165 - };
166 - mixInto(TestTransaction, Transaction.Mixin);
167 - // Now, none of the close/inits throw, but the operation we wrap will throw.
168 - TestTransaction.prototype.getTransactionWrappers = function() {
169 - return [
170 - {
171 - initialize: function() {
172 - return 'firstResult';
173 - },
174 - close: function(initResult) {
175 - this.firstCloseParam = initResult;
176 - }
177 - },
178 - {
179 - initialize: function() {
180 - return 'secondResult';
181 - },
182 - close: function(initResult) {
183 - this.secondCloseParam = initResult;
184 - }
185 - },
186 - {
187 - initialize: function() {
188 - return 'thirdResult';
189 - },
190 - close: function(initResult) {
191 - this.lastCloseParam = initResult;
192 - }
193 - },
194 - {
195 - initialize: function() {
196 - return 'fourthResult';
197 - },
198 - close: function(initResult) {
199 - throw new Error('The transaction should throw a TypeError.');
200 - }
201 - }
202 - ];
203 - };
204 -
205 - var transaction = new TestTransaction();
206 -
207 - expect(function() {
208 - var isTypeError = false;
209 - try {
210 - transaction.perform(function() {
211 - throw new TypeError("Thrown in main wrapped operation");
212 - });
213 - } catch (err) {
214 - isTypeError = (err instanceof TypeError);
215 - }
216 - return isTypeError;
217 - }()).toBe(true);
218 -
219 - expect(performSideEffect).toBe(undefined);
220 - expect(transaction.firstCloseParam).toBe('firstResult');
221 - expect(transaction.secondCloseParam).toBe('secondResult');
222 - expect(transaction.lastCloseParam).toBe('thirdResult');
223 - expect(transaction.isInTransaction()).toBe(false);
224 - });
225 -
226 - it('should throw errors in transaction close', function() {
227 - var TestTransaction = function() {
228 - this.reinitializeTransaction();
229 - };
230 - mixInto(TestTransaction, Transaction.Mixin);
231 - var exceptionMsg = 'This exception should throw.';
232 - TestTransaction.prototype.getTransactionWrappers = function() {
233 - return [
234 - {
235 - close: function(initResult) {
236 - throw new Error(exceptionMsg);
237 - }
238 - }
239 - ];
240 - };
241 -
242 - var transaction = new TestTransaction();
243 - expect(function() {
244 - transaction.perform(function() {});
245 - }).toThrow(exceptionMsg);
246 - });
247 -
248 - it('should allow nesting of transactions', function() {
249 - var performSideEffect;
250 - var nestedPerformSideEffect;
251 - /**
252 - * New test Transaction subclass.
253 - */
254 - var TestTransaction = function() {
255 - this.reinitializeTransaction();
256 - this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else
257 - this.secondCloseParam = INIT_ERRORED; // WILL be set to something else
258 - this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else
259 - };
260 - mixInto(TestTransaction, Transaction.Mixin);
261 - TestTransaction.prototype.getTransactionWrappers = function() {
262 - return [
263 - {
264 - initialize: function() {
265 - return 'firstResult';
266 - },
267 - close: function(initResult) {
268 - this.firstCloseParam = initResult;
269 - }
270 - },
271 - {
272 - initialize: function() {
273 - this.nestedTransaction = new NestedTransaction();
274 - },
275 - close: function() {
276 - // Test performing a transaction in another transaction's close()
277 - this.nestedTransaction.perform(function() {
278 - nestedPerformSideEffect = 'NESTED_SIDE_EFFECT';
279 - });
280 - }
281 - }
282 - ];
283 - };
284 -
285 - var NestedTransaction = function() {
286 - this.reinitializeTransaction();
287 - };
288 - mixInto(NestedTransaction, Transaction.Mixin);
289 - NestedTransaction.prototype.getTransactionWrappers = function() {
290 - return [{
291 - initialize: function() {
292 - this.hasInitializedNested = true;
293 - },
294 - close: function() {
295 - this.hasClosedNested = true;
296 - }
297 - }];
298 - };
299 -
300 - var transaction = new TestTransaction();
301 -
302 - transaction.perform(function() {
303 - performSideEffect = 'SIDE_EFFECT';
304 - });
305 -
306 - expect(performSideEffect).toBe('SIDE_EFFECT');
307 - expect(nestedPerformSideEffect).toBe('NESTED_SIDE_EFFECT');
308 - expect(transaction.firstCloseParam).toBe('firstResult');
309 - expect(transaction.isInTransaction()).toBe(false);
310 - expect(transaction.nestedTransaction.hasClosedNested).toBe(true);
311 - expect(transaction.nestedTransaction.hasInitializedNested).toBe(true);
312 - expect(transaction.nestedTransaction.isInTransaction()).toBe(false);
313 - });
314 -});
React/utils/__tests__/joinClasses-test.js deleted
-57
@@ -1,57 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -require("../../mock-modules").dontMock('joinClasses');
22 -
23 -var joinClasses = require("../../joinClasses");
24 -
25 -describe('joinClasses', function() {
26 -
27 - it('should return a single className', function() {
28 - expect(joinClasses('aaa')).toEqual('aaa');
29 - });
30 -
31 - it('should join two classes together', function() {
32 - var aaa = 'aaa';
33 - var bbb = 'bbb';
34 - expect(joinClasses(aaa, bbb)).toEqual('aaa bbb');
35 - });
36 -
37 - it('should join many classes together', function() {
38 - var aaa = 'aaa';
39 - var bbb = 'bbb';
40 - var ccc = 'ccc';
41 - var ddd = 'ddd';
42 - var eee = 'eee';
43 - expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa bbb ccc ddd eee');
44 - });
45 -
46 - it('should omit undefined and empty classes', function() {
47 - var aaa = 'aaa';
48 - var bbb;
49 - var ccc = null;
50 - var ddd = '';
51 - var eee = 'eee';
52 - expect(joinClasses(bbb)).toEqual('');
53 - expect(joinClasses(bbb, bbb, bbb)).toEqual('');
54 - expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa eee');
55 - });
56 -
57 -});
React/utils/__tests__/keyMirror-test.js deleted
-71
@@ -1,71 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -require("../../mock-modules").dontMock('keyMirror');
22 -
23 -var keyMirror = require("../../keyMirror");
24 -
25 -describe('keyMirror', function() {
26 - it('should create an object with values matching keys provided', function() {
27 - var mirror = keyMirror({
28 - foo: null,
29 - bar: true,
30 - "baz": { some: "object" },
31 - qux: undefined
32 - });
33 - expect('foo' in mirror).toBe(true);
34 - expect(mirror.foo).toBe('foo');
35 - expect('bar' in mirror).toBe(true);
36 - expect(mirror.bar).toBe('bar');
37 - expect('baz' in mirror).toBe(true);
38 - expect(mirror.baz).toBe('baz');
39 - expect('qux' in mirror).toBe(true);
40 - expect(mirror.qux).toBe('qux');
41 - });
42 -
43 - it('should not use properties from prototypes', function() {
44 - function Klass() {
45 - this.useMeToo = true;
46 - }
47 - Klass.prototype.doNotUse = true;
48 - var instance = new Klass();
49 - instance.useMe = true;
50 -
51 - var mirror = keyMirror(instance);
52 -
53 - expect('doNotUse' in mirror).toBe(false);
54 - expect('useMe' in mirror).toBe(true);
55 - expect('useMeToo' in mirror).toBe(true);
56 - });
57 -
58 - it('should throw when a non-object argument is used', function() {
59 - [null, undefined, 0, 7, ['uno'], true, "string"].forEach(function(testVal) {
60 - expect(keyMirror.bind(null, testVal)).toThrow();
61 - });
62 - });
63 -
64 - it('should work when "constructor" is a key', function() {
65 - var obj = { constructor: true };
66 - expect(keyMirror.bind(null, obj)).not.toThrow();
67 - var mirror = keyMirror(obj);
68 - expect('constructor' in mirror).toBe(true);
69 - });
70 -});
71 -
React/utils/__tests__/mapChildren-test.js deleted
-1
@@ -1 +0,0 @@
1 -throw new Error("nonexistent module required: utils/__tests__/mapChildren-test");
\ No newline at end of file
React/utils/__tests__/memoizeStringOnly-test.js deleted
-37
@@ -1,37 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -describe('memoizeStringOnly', function() {
22 - var memoizeStringOnly;
23 -
24 - beforeEach(function() {
25 - require("../../mock-modules").dumpCache();
26 - memoizeStringOnly = require("../../memoizeStringOnly");
27 - });
28 -
29 - it('should be transparent to callers', function() {
30 - var callback = function(string) {
31 - return string;
32 - };
33 - var memoized = memoizeStringOnly(callback);
34 -
35 - expect(memoized('foo'), callback('foo'));
36 - });
37 -});
React/utils/__tests__/mergeFuncs-test.js deleted
-983
@@ -1,983 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -require("../../mock-modules")
22 - .dontMock('mergeHelpers')
23 - .dontMock('merge')
24 - .dontMock('mergeDeep')
25 - .dontMock('mergeInto')
26 - .dontMock('mergeDeepInto');
27 -
28 -var mergeHelpers;
29 -var merge;
30 -var mergeInto;
31 -var mergeDeep;
32 -var mergeDeepInto;
33 -
34 -var isTerminal;
35 -var MAX_MERGE_DEPTH;
36 -
37 -/**
38 - * Simple helper to traverse an object, calling the callback (cb) on every
39 - * nonTerminal node it finds. It stops once it reaches the maximum depth,
40 - * because we know that the merge functions shouldn't merge past that depth
41 - * anyways. If you don't "stop" once reaching the MAX_MERGE_DEPTH, there won't
42 - * be a practical way to traverse circular structures.
43 - */
44 -var traverseUntilLeaves = function(obj, cb, depth) {
45 - if ((depth || 0) >= MAX_MERGE_DEPTH) {
46 - return;
47 - }
48 - var key;
49 - if (!isTerminal(obj) && !Array.isArray(obj)) {
50 - cb(obj);
51 - for (key in obj) {
52 - if (!obj.hasOwnProperty(key)) {
53 - continue;
54 - }
55 - traverseUntilLeaves(obj[key], cb, (depth || 0) + 1);
56 - }
57 - }
58 -};
59 -
60 -/*
61 - * Checks that the structure of two merged objects are identical. Checks
62 - * MAX_LEVEL because we don't want to block other unit tests if I have an
63 - * infinite loop.
64 - */
65 -var MAX_LEVEL = 50;
66 -var structureEquals = function(one, two, levelParam) {
67 - var level = levelParam || 0;
68 - var oneKey;
69 - var twoKey;
70 - if (level > MAX_LEVEL) {
71 - throw new Error('structure equals computation explored too many levels');
72 - }
73 - if (isTerminal(one) && isTerminal(two)) {
74 - return one === two;
75 - } else if (!isTerminal(one) && !isTerminal(two)) {
76 - var allInOneAreInTwo = true;
77 - for (oneKey in one) {
78 - if (!one.hasOwnProperty(oneKey)) {
79 - continue;
80 - }
81 - if (!structureEquals(one[oneKey], two[oneKey], level + 1)) {
82 - allInOneAreInTwo = false;
83 - }
84 - }
85 - var allInTwoAreInOne = true;
86 - for (twoKey in two) {
87 - if (!two.hasOwnProperty(twoKey)) {
88 - continue;
89 - }
90 - if (!structureEquals(two[twoKey], one[twoKey], level + 1)) {
91 - allInTwoAreInOne = false;
92 - }
93 - }
94 - // Sure, the computations overlap a bit.
95 - return allInOneAreInTwo && allInTwoAreInOne;
96 - } else {
97 - return false;
98 - }
99 -};
100 -
101 -
102 -var makeCircular = function() {
103 - var obj = {};
104 - obj.self = obj;
105 - return obj;
106 -};
107 -
108 -
109 -
110 -/**
111 - * Not a symmetric function. Checks if there are any node references
112 - * (nonTerminal [non-string, non-null, etc]) that exist in inThis. See
113 - * sharesOnlyTerminalMemory.
114 - */
115 -var hasNoNodeReferencesIn = function(obj, inThis) {
116 - traverseUntilLeaves(obj, function(nonTerm) {
117 - traverseUntilLeaves(inThis, function(inThisNonTerm) {
118 - if (inThisNonTerm === nonTerm) {
119 - return false;
120 - }
121 - });
122 - });
123 - return true;
124 -};
125 -
126 -/**
127 - * Checks that two objects share no memory references with each other (except
128 - * possibly at the terminal nodes (such as strings etc)). This is used to test
129 - * isolation of memory. When certain merge operations occur we need to ensure
130 - * that we did not leak references across objects.
131 - */
132 -var sharesOnlyTerminalMemory = function(a, b) {
133 - return hasNoNodeReferencesIn(a, b) && hasNoNodeReferencesIn(b, a);
134 -};
135 -
136 -/**
137 - * Tests all of the merging functions. You provide it data that describes what
138 - * a deep merge looks like and what a shallow merge looks like. It will make
139 - * sure that various input/output contracts are adhered to, in addition to
140 - * ensuring that various guarantees about side-effects are upheld.
141 - * The test data must provide functions createOne/createTwo as a means to
142 - * create test data for objects one/two respsectively - each time these
143 - * functions must return pristine copies so that we can test for side effects
144 - * correctly.
145 - */
146 -var testAllMerges = function(testData) {
147 - var createOne = testData.createOne;
148 - var createTwo = testData.createTwo;
149 - var one;
150 - var two;
151 -
152 - /*
153 - * Test merge()
154 - */
155 - one = createOne();
156 - two = createTwo();
157 - if (testData.mergeShouldThrow) {
158 - expect(function() {
159 - merge(one, two);
160 - }).toThrow();
161 - } else {
162 - var mergeRes = merge(one, two);
163 - if (testData.shallowResultShouldBe) {
164 - expect(structureEquals(
165 - mergeRes,
166 - testData.shallowResultShouldBe)
167 - ).toBe(true);
168 - }
169 - // Ensure the result is not the exact same object memory reference.
170 - expect(mergeRes === one).toBe(false);
171 - }
172 -
173 - /*
174 - * Test mergeInto()
175 - */
176 - one = createOne();
177 - two = createTwo();
178 - if (testData.mergeIntoShouldThrow) {
179 - expect(function() {
180 - mergeInto(one, two);
181 - }).toThrow();
182 - } else {
183 - var mergeIntoRes = mergeInto(one, two);
184 - if (testData.shallowResultShouldBe) {
185 - expect(structureEquals(
186 - one,
187 - testData.shallowResultShouldBe)
188 - ).toBe(true);
189 - }
190 - /*
191 - * Ensure it's the exact same object reference
192 - * TODO: We should ensure that for every object path p in one points to
193 - * the original object reference in one before the mutation.
194 - */
195 - expect(mergeIntoRes === undefined).toBe(true);
196 - }
197 -
198 - /*
199 - * Test mergeDeep()
200 - */
201 - one = createOne();
202 - two = createTwo();
203 - if (testData.mergeDeepShouldThrow) {
204 - expect(function() {
205 - mergeDeep(one, two, testData.arrayStrategy);
206 - }).toThrow();
207 - } else {
208 - var mergeDeepRes = mergeDeep(one, two, testData.arrayStrategy);
209 - if (testData.deepResultShouldBe) {
210 - expect(structureEquals(
211 - mergeDeepRes,
212 - testData.deepResultShouldBe)
213 - ).toBe(true);
214 - }
215 - expect(sharesOnlyTerminalMemory(mergeDeepRes, one)).toBe(true);
216 - expect(sharesOnlyTerminalMemory(mergeDeepRes, two)).toBe(true);
217 - }
218 -
219 - /*
220 - * Test mergeDeepInto()
221 - */
222 - one = createOne();
223 - two = createTwo();
224 - if (testData.mergeDeepIntoShouldThrow) {
225 - expect(function() {
226 - mergeDeepInto(one, two, testData.arrayStrategy);
227 - }).toThrow();
228 - } else {
229 - var mergeDeepIntoRes = mergeDeepInto(one, two, testData.arrayStrategy);
230 - expect(mergeDeepIntoRes).toBe(undefined);
231 - if (testData.deepResultShouldBe) {
232 - expect(structureEquals(
233 - one,
234 - testData.deepResultShouldBe)
235 - ).toBe(true);
236 - }
237 - expect(mergeDeepIntoRes === undefined).toBe(true);
238 - expect(sharesOnlyTerminalMemory(one, two)).toBe(true);
239 - }
240 -
241 -};
242 -
243 -/**
244 - * ReactTextWithEntities is not a React component, but rather a helper function
245 - * that returns an array. You can use that array as a helper function when
246 - * constructing a structure.
247 - */
248 -describe('mergeFuncs', function() {
249 - beforeEach(function() {
250 - require("../../mock-modules").dumpCache();
251 - mergeHelpers = require("../../mergeHelpers");
252 - merge = require("../../merge");
253 - mergeInto = require("../../mergeInto");
254 - mergeDeep = require("../../mergeDeep");
255 - mergeDeepInto = require("../../mergeDeepInto");
256 - isTerminal = mergeHelpers.isTerminal;
257 - MAX_MERGE_DEPTH = mergeHelpers.MAX_MERGE_DEPTH;
258 - });
259 -
260 - var twoLevelsDeep = function() {
261 - return {
262 - shallowObject: {
263 - deepObject: {
264 - a: 'a',
265 - b: 'b'
266 - },
267 - deepObject2: {
268 - one: 'one',
269 - two: 'two'
270 - }
271 - }
272 - };
273 - };
274 -
275 - it('should not throw if first argument is circular', function() {
276 - testAllMerges({
277 - createOne: makeCircular,
278 - createTwo: function() { return {thisOneIsNotCircular: true}; },
279 - mergeShouldThrow: false,
280 - mergeIntoShouldThrow: false,
281 - mergeDeepShouldThrow: true,
282 - mergeDeepIntoShouldThrow: false
283 - });
284 - });
285 -
286 - it('should throw if second argument is circular', function() {
287 - testAllMerges({
288 - createOne: function() { return {thisOneIsNotCircular: true}; },
289 - createTwo: makeCircular,
290 - mergeShouldThrow: false,
291 - mergeIntoShouldThrow: false,
292 - mergeDeepShouldThrow: true,
293 - mergeDeepIntoShouldThrow: true
294 - });
295 - });
296 -
297 - it('should throw if something deep is circular in second param', function() {
298 - testAllMerges({
299 - createOne: function() { return {thisOneIsNotCircular: true}; },
300 - createTwo: function() {
301 - return {
302 - deeper: {
303 - deeper: makeCircular()
304 - }
305 - };
306 - },
307 - mergeShouldThrow: false,
308 - mergeIntoShouldThrow: false,
309 - mergeDeepShouldThrow: true,
310 - mergeDeepIntoShouldThrow: true
311 - });
312 - });
313 -
314 - it('should throw if something deep is circular in first param', function() {
315 - testAllMerges({
316 - createOne: function() {
317 - return {
318 - deeper: {
319 - deeper: makeCircular()
320 - }
321 - };
322 - },
323 - createTwo: function() { return {thisOneIsNotCircular: true}; },
324 - mergeShouldThrow: false,
325 - mergeIntoShouldThrow: false,
326 - mergeDeepShouldThrow: true,
327 - mergeDeepIntoShouldThrow: false
328 - });
329 - });
330 -
331 -
332 - it('should throw exceptions on invalid data/params', function() {
333 - testAllMerges({
334 - createOne: function() { return []; },
335 - createTwo: function() { return {}; },
336 - mergeShouldThrow: true,
337 - mergeIntoShouldThrow: true,
338 - mergeDeepShouldThrow: true,
339 - mergeDeepIntoShouldThrow: true
340 - });
341 - testAllMerges({
342 - createOne: function() { return {}; },
343 - createTwo: function() { return []; },
344 - mergeShouldThrow: true,
345 - mergeIntoShouldThrow: true,
346 - mergeDeepShouldThrow: true,
347 - mergeDeepIntoShouldThrow: true
348 - });
349 - testAllMerges({
350 - createOne: function() { return []; },
351 - createTwo: function() { return {hasDeepStructure: 'yes'}; },
352 - mergeShouldThrow: true,
353 - mergeIntoShouldThrow: true,
354 - mergeDeepShouldThrow: true,
355 - mergeDeepIntoShouldThrow: true
356 - });
357 - testAllMerges({
358 - createOne: function() { return {hasDeepStructure: 'yes'}; },
359 - createTwo: function() { return []; },
360 - mergeShouldThrow: true,
361 - mergeIntoShouldThrow: true,
362 - mergeDeepShouldThrow: true,
363 - mergeDeepIntoShouldThrow: true
364 - });
365 - testAllMerges({
366 - createOne: function() { return {hasDeepStructure: 'yes'}; },
367 - createTwo: function() { return []; },
368 - mergeShouldThrow: true,
369 - mergeIntoShouldThrow: true,
370 - mergeDeepShouldThrow: true,
371 - mergeDeepIntoShouldThrow: true
372 - });
373 - /*
374 - * mergeInto functions do not accept an empty first parameter. There would
375 - * be nothing to mutate!
376 - */
377 - testAllMerges({
378 - createOne: function() { return null; },
379 - createTwo: function() { return {field: 'yes'}; },
380 - mergeIntoShouldThrow: true,
381 - mergeDeepIntoShouldThrow: true,
382 - shallowResultShouldBe: {field: 'yes'},
383 - deepResultShouldBe: {field: 'yes'}
384 - });
385 - testAllMerges({
386 - createOne: function() { return undefined; },
387 - createTwo: function() { return {field: 'yes'}; },
388 - mergeIntoShouldThrow: true,
389 - mergeDeepIntoShouldThrow: true,
390 - shallowResultShouldBe: {field: 'yes'},
391 - deepResultShouldBe: {field: 'yes'}
392 - });
393 - // Every merge function accepts an empty second parameter.
394 - testAllMerges({
395 - createOne: function() { return {field: 'yes'}; },
396 - createTwo: function() { return null; },
397 - shallowResultShouldBe: {field: 'yes'},
398 - deepResultShouldBe: {field: 'yes'}
399 - });
400 - testAllMerges({
401 - createOne: function() { return null; },
402 - createTwo: function() { return null; },
403 - deepResultShouldBe: {},
404 - shallowResultShouldBe: {},
405 - mergeIntoShouldThrow: true,
406 - mergeDeepIntoShouldThrow: true
407 - });
408 - testAllMerges({
409 - createOne: function() { return {field: 'yes'}; },
410 - createTwo: function() { return undefined; },
411 - shallowResultShouldBe: {field: 'yes'},
412 - deepResultShouldBe: {field: 'yes'}
413 - });
414 - testAllMerges({
415 - createOne: function() { return 0; },
416 - createTwo: function() { return {field: 'yes'}; },
417 - mergeShouldThrow: true,
418 - mergeIntoShouldThrow: true,
419 - mergeDeepShouldThrow: true,
420 - mergeDeepIntoShouldThrow: true
421 - });
422 - /*
423 - * The fact that the second param is empty shouldn't change that we still
424 - * error on arrays.
425 - */
426 - testAllMerges({
427 - createOne: function() { return []; },
428 - createTwo: function() { return undefined; },
429 - mergeShouldThrow: true,
430 - mergeIntoShouldThrow: true,
431 - mergeDeepShouldThrow: true,
432 - mergeDeepIntoShouldThrow: true
433 - });
434 - testAllMerges({
435 - createOne: function() { return {field: 'yes'}; },
436 - createTwo: function() { return null; },
437 - shallowResultShouldBe: {field: 'yes'},
438 - deepResultShouldBe: {field: 'yes'}
439 - });
440 - });
441 -
442 -
443 - it('should merge very deep objects correctly.',
444 - function() {
445 - testAllMerges({
446 - createOne: function() {
447 - return {
448 - shouldBeClobberedByNull: {
449 - color: 'blue'
450 - },
451 - shouldGetTwoFieldsWhenDeepMerge: {
452 - firstField: { color: 'red' }
453 - },
454 - shouldRemainUndefined: undefined,
455 - shouldRemainFour: 4,
456 - shouldRemainZero: 0,
457 - shouldBeClobberedByObj: 0
458 - };
459 - },
460 - createTwo: function() {
461 - return {
462 - shouldBeClobberedByNull: null,
463 - shouldGetTwoFieldsWhenDeepMerge: {
464 - secondField: { color: 'black' }
465 - },
466 - shouldBeClobberedByObj: { thisObj: true }
467 - };
468 - },
469 - shallowResultShouldBe: {
470 - shouldBeClobberedByNull: null,
471 - // only gets one field when merged shallowly
472 - shouldGetTwoFieldsWhenDeepMerge: {
473 - secondField: { color: 'black' }
474 - },
475 - shouldRemainUndefined: undefined,
476 - shouldRemainFour: 4,
477 - shouldRemainZero: 0,
478 - shouldBeClobberedByObj: { thisObj: true }
479 - },
480 - deepResultShouldBe: {
481 - shouldRemainUndefined: undefined,
482 - shouldRemainFour: 4,
483 - shouldRemainZero: 0,
484 - shouldBeClobberedByNull: null,
485 - shouldGetTwoFieldsWhenDeepMerge: {
486 - firstField: { color: 'red' },
487 - secondField: { color: 'black' }
488 - },
489 - shouldBeClobberedByObj: { thisObj: true }
490 - }
491 - });
492 - }
493 - );
494 -
495 - it(
496 - 'should not throw with one non-colliding arrays with no arrayStrategy',
497 - function() {
498 - testAllMerges({
499 - createOne: function() { return { hasDeepStructure: 'yes' }; },
500 - createTwo: function() { return { hasArrayDeeper: [] }; },
501 - mergeShouldThrow: false,
502 - mergeIntoShouldThrow: false,
503 - mergeDeepShouldThrow: false,
504 - mergeDeepIntoShouldThrow: false,
505 - shallowResultShouldBe: {
506 - hasDeepStructure: 'yes',
507 - hasArrayDeeper: []
508 - },
509 - deepResultShouldBe: {
510 - hasDeepStructure: 'yes',
511 - hasArrayDeeper: []
512 - }
513 - });
514 - }
515 - );
516 -
517 - it(
518 - 'should not throw with two non-colliding arrays with no arrayStrategy',
519 - function() {
520 - testAllMerges({
521 - createOne: function() {
522 - return {
523 - arrayOne: [1]
524 - };
525 - },
526 - createTwo: function() {
527 - return {
528 - arrayTwo: [2]
529 - };
530 - },
531 - arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,
532 - mergeShouldThrow: false,
533 - mergeIntoShouldThrow: false,
534 - mergeDeepShouldThrow: false,
535 - mergeDeepIntoShouldThrow: false
536 - });
537 - }
538 - ),
539 -
540 - it('should throw if no arrayStrategy supplied on Array merges', function() {
541 - testAllMerges({
542 - createOne: function() {
543 - return {
544 - arrayOne: [1]
545 - };
546 - },
547 - createTwo: function() {
548 - return {
549 - arrayOne: [9]
550 - };
551 - },
552 - shallowResultShouldBe: {
553 - arrayOne: [9]
554 - },
555 - // Doesn't throw on the shallow versions.
556 - mergeShouldThrow: false,
557 - mergeIntoShouldThrow: false,
558 - mergeDeepShouldThrow: true,
559 - mergeDeepIntoShouldThrow: true
560 - });
561 - }),
562 -
563 - it('should not throw if never forced to merge two Arrays', function() {
564 - testAllMerges({
565 - createOne: function() {
566 - return {
567 - arrayOne: [1]
568 - };
569 - },
570 - createTwo: function() {
571 - return {
572 - arrayTwo: [9] // <-- See, never forced to merge with arrayOne
573 - };
574 - },
575 - shallowResultShouldBe: {
576 - arrayOne: [1],
577 - arrayTwo: [9]
578 - },
579 - // Doesn't throw on the shallow versions.
580 - mergeShouldThrow: false,
581 - mergeIntoShouldThrow: false,
582 - mergeDeepShouldThrow: false,
583 - mergeDeepIntoShouldThrow: false
584 - });
585 - }),
586 -
587 - it(
588 - 'should correctly deep merge Arrays with arrayStrategy clobber',
589 - function() {
590 - testAllMerges({
591 - createOne: function() {
592 - return {
593 - deep: {
594 - array: [1],
595 - nonArray: {
596 - hi: 'hi'
597 - }
598 - }
599 - };
600 - },
601 - createTwo: function() {
602 - return {
603 - deep: {
604 - array: [10,11, {deepFieldInArray: 'yes'}],
605 - nonArray: {
606 - bye: 'bye'
607 - }
608 - }
609 - };
610 - },
611 - shallowResultShouldBe: {
612 - deep: {
613 - array: [10,11, {deepFieldInArray: 'yes'}],
614 - nonArray: {
615 - bye: 'bye'
616 - }
617 - }
618 - },
619 - deepResultShouldBe: {
620 - deep: {
621 - array: [10,11, {deepFieldInArray: 'yes'}],
622 - nonArray: {
623 - hi: 'hi',
624 - bye: 'bye'
625 - }
626 - }
627 - },
628 - arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,
629 - mergeShouldThrow: false,
630 - mergeIntoShouldThrow: false,
631 - mergeDeepShouldThrow: false,
632 - mergeDeepIntoShouldThrow: false
633 - });
634 - }
635 - ),
636 -
637 -
638 - it(
639 - 'should correctly deep merge Arrays with arrayStrategy indexByIndex',
640 - function() {
641 - testAllMerges({
642 - createOne: function() {
643 - return {
644 - deep: {
645 - array: [{
646 - atIndexZero: {
647 - indexZeroGreeting: 'You Are At Index Zero',
648 - indexZeroStatus: false
649 - }
650 - }]
651 - }
652 - };
653 - },
654 - createTwo: function() {
655 - return {
656 - deep: {
657 - array: [{
658 - atIndexZero: {
659 - indexZeroStatus: true,
660 - newFieldAtIndexZero: 'newField'
661 - }
662 - },
663 - {
664 - atIndexOne: {
665 - nothingOriginallyAtThisIndex: true
666 - }
667 - }]
668 - }
669 - };
670 - },
671 - shallowResultShouldBe: {
672 - deep: {
673 - array: [{
674 - atIndexZero: {
675 - indexZeroStatus: true,
676 - newFieldAtIndexZero: 'newField'
677 - }
678 - },
679 - {
680 - atIndexOne: {
681 - nothingOriginallyAtThisIndex: true
682 - }
683 - }]
684 - }
685 - },
686 - deepResultShouldBe: {
687 - deep: {
688 - array: [{
689 - atIndexZero: {
690 - indexZeroGreeting: 'You Are At Index Zero', // <-- See!?
691 - indexZeroStatus: true,
692 - newFieldAtIndexZero: 'newField'
693 - }
694 - },
695 - {
696 - atIndexOne: {
697 - nothingOriginallyAtThisIndex: true
698 - }
699 - }]
700 - }
701 - },
702 - arrayStrategy: mergeHelpers.ArrayStrategies.IndexByIndex,
703 - mergeShouldThrow: false,
704 - mergeIntoShouldThrow: false,
705 - mergeDeepShouldThrow: false,
706 - mergeDeepIntoShouldThrow: false
707 - }
708 - );
709 - }),
710 -
711 - it('should merge deep data correctly', function() {
712 - var mergeData = {
713 - shallowObject: {
714 - deepObject: {
715 - c: 'c',
716 - d: 'd'
717 - },
718 - deepObject2: {
719 - three: 'three',
720 - four: 'four'
721 - }
722 - }
723 - };
724 - var deepResult = {
725 - shallowObject: {
726 - deepObject: {
727 - a: 'a',
728 - b: 'b',
729 - c: 'c',
730 - d: 'd'
731 - },
732 - deepObject2: {
733 - one: 'one',
734 - two: 'two',
735 - three: 'three',
736 - four: 'four'
737 - }
738 - }
739 - };
740 - var shallowResult = mergeData; // The same
741 -
742 - testAllMerges({
743 - createOne: function() { return twoLevelsDeep(); },
744 - createTwo: function() { return mergeData; },
745 - mergeShouldThrow: false,
746 - mergeIntoShouldThrow: false,
747 - mergeDeepShouldThrow: false,
748 - mergeDeepIntoShouldThrow: false,
749 - deepResultShouldBe: deepResult,
750 - shallowResultShouldBe: shallowResult
751 - });
752 - });
753 -
754 - it('should fill in complementing regions of data trees', function() {
755 - var mergeData = {
756 - shallowObject: {
757 - newDepth: {
758 - hello: 'goodbye'
759 - }
760 - }
761 - };
762 - var deepResult = {
763 - shallowObject: {
764 - deepObject: {
765 - a: 'a',
766 - b: 'b'
767 - },
768 - deepObject2: {
769 - one: 'one',
770 - two: 'two'
771 - },
772 - // This is added!
773 - newDepth: {
774 - hello: 'goodbye'
775 - }
776 - }
777 - };
778 - var shallowResult = mergeData; // The same
779 -
780 - testAllMerges({
781 - createOne: function() { return twoLevelsDeep(); },
782 - createTwo: function() { return mergeData; },
783 - // The deep merge of the two
784 - deepResultShouldBe: deepResult,
785 - shallowResultShouldBe: shallowResult
786 - });
787 - });
788 -
789 - /**
790 - * Arrays and Objects wipe out terminals (and vice versa).
791 - */
792 - it('should clobber terminals with objects/arrays vice versa', function() {
793 - var makeOne = function() {
794 - return {
795 - thisFieldDoesNothing: {},
796 - deep: {
797 - // Objects
798 - thisShouldSwitchFromObjectToTerminal: {hello: 'goodbye'},
799 - thisShouldSwitchFromTerminalToObject: 'yes',
800 -
801 - // Arrays
802 - thisShouldSwitchFromArrayToTerminal: ['goodbye'],
803 - thisShouldSwitchFromTerminalToArray: 'yes'
804 - }
805 - };
806 - };
807 - var makeTwo = function() {
808 - return {
809 - deep: {
810 - // Objects
811 - thisShouldSwitchFromObjectToTerminal: 'terminal',
812 - thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},
813 -
814 - // Arrays
815 - thisShouldSwitchFromArrayToTerminal: 'terminal',
816 - thisShouldSwitchFromTerminalToArray: ['yay']
817 - }
818 - };
819 - };
820 - var deepResult = {
821 - thisFieldDoesNothing: {
822 -
823 - },
824 - deep: {
825 - // Objects
826 - thisShouldSwitchFromObjectToTerminal: 'terminal',
827 - thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},
828 -
829 - // Arrays
830 - thisShouldSwitchFromArrayToTerminal: 'terminal',
831 - thisShouldSwitchFromTerminalToArray: ['yay']
832 - }
833 - };
834 -
835 - testAllMerges({
836 - createOne: makeOne,
837 - createTwo: makeTwo,
838 - deepResultShouldBe: deepResult, // The deep merge of the two
839 - shallowResultShouldBe: deepResult // The same this time.
840 - });
841 - });
842 -
843 - /**
844 - * Arrays wipe out Objects and Objects wipe out Arrays.
845 - */
846 - it('should clobber terminals with objects/arrays vice versa', function() {
847 - var makeOne = function() {
848 - return {
849 - thisFieldDoesNothing: {},
850 - deep: {
851 - thisShouldSwitchFromObjectToArray: {hello: 'goodbye'},
852 - thisShouldSwitchFromArrayToObject: [1,2,3]
853 - }
854 - };
855 - };
856 - var makeTwo = function() {
857 - return {
858 - deep: {
859 - thisShouldSwitchFromObjectToArray: [7,8,9],
860 - thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}
861 - }
862 - };
863 - };
864 - var deepResult = {
865 - thisFieldDoesNothing: {},
866 - deep: {
867 - thisShouldSwitchFromObjectToArray: [7,8,9],
868 - thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}
869 - }
870 - };
871 -
872 - testAllMerges({
873 - createOne: makeOne,
874 - createTwo: makeTwo,
875 - deepResultShouldBe: deepResult, // The deep merge of the two
876 - shallowResultShouldBe: deepResult // The same this time.
877 - });
878 - });
879 -
880 - it(
881 - 'should not clobber terminals/objects/arrays that are not over-written',
882 - function() {
883 - testAllMerges({
884 - createOne: function() {
885 - return {
886 - deep: {
887 - terminal: 'I am a terminal',
888 - object: {iAmAnObject: true},
889 - array: [1,2,3]
890 - }
891 - };
892 - },
893 - createTwo: function() {
894 - return {
895 - deep: {
896 - completelyDifferentField: 'no collision here!'
897 - }
898 - };
899 - },
900 - shallowResultShouldBe: {
901 - deep: {
902 - completelyDifferentField: 'no collision here!'
903 - }
904 - },
905 - deepResultShouldBe: {
906 - deep: {
907 - completelyDifferentField: 'no collision here!',
908 - terminal: 'I am a terminal',
909 - object: {iAmAnObject: true},
910 - array: [1,2,3]
911 - }
912 - },
913 - mergeShouldThrow: false,
914 - mergeIntoShouldThrow: false,
915 - mergeDeepShouldThrow: false,
916 - mergeDeepIntoShouldThrow: false
917 - }
918 - );
919 - }),
920 -
921 - it('should correctly clobber terminals with cloned arrays', function() {
922 - testAllMerges({
923 - createOne: function() {
924 - return {
925 - deep: {
926 - changesFromTermToArray: 'I am a terminal'
927 - }
928 - };
929 - },
930 - createTwo: function() {
931 - return {
932 - deep: {
933 - changesFromTermToArray: ['I', 'am', 'an', 'array']
934 - }
935 - };
936 - },
937 - shallowResultShouldBe: {
938 - deep: {
939 - changesFromTermToArray: ['I', 'am', 'an', 'array']
940 - }
941 - },
942 - deepResultShouldBe: {
943 - deep: {
944 - changesFromTermToArray: ['I', 'am', 'an', 'array']
945 - }
946 - },
947 - mergeShouldThrow: false,
948 - mergeIntoShouldThrow: false,
949 - mergeDeepShouldThrow: false,
950 - mergeDeepIntoShouldThrow: false
951 - });
952 - }),
953 -
954 - it('should detect terminals correctly in merge* functions', function() {
955 - var boolResFalse = isTerminal(false);
956 - expect(boolResFalse).toBe(true);
957 -
958 - var boolResTrue = isTerminal(true);
959 - expect(boolResTrue).toBe(true);
960 -
961 - var numRes = isTerminal(123);
962 - expect(numRes).toBe(true);
963 -
964 - var zeroRes = isTerminal(0);
965 - expect(zeroRes).toBe(true);
966 -
967 - var stringRes = isTerminal('i am a string');
968 - expect(stringRes).toBe(true);
969 -
970 - var objLiteralRes = isTerminal({somethingHere: true});
971 - expect(objLiteralRes).toBe(false);
972 -
973 - var undefRes = isTerminal(undefined);
974 - expect(undefRes).toBe(true);
975 -
976 - var nullRes = isTerminal(null);
977 - expect(nullRes).toBe(true);
978 -
979 - var arrRes = isTerminal([]);
980 - expect(arrRes).toBe(false);
981 - });
982 -});
983 -
React/utils/__tests__/objFilter-test.js deleted
-88
@@ -1,88 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -var objFilter = require("../../objFilter");
22 -
23 -describe('objFilter', function() {
24 -
25 - var obj = {
26 - A: 'apple',
27 - B: 'banana',
28 - C: 'coconut',
29 - D: 'durian',
30 - E: 'elderberry',
31 - F: 'fig',
32 - G: 'guava',
33 - H: 'hackberry'
34 - };
35 -
36 - it('should accept null', function() {
37 - var filtered = objFilter(null, function() {});
38 - expect(filtered).toBe(null);
39 - });
40 -
41 - it('should return true to create copy', function() {
42 - var filtered = objFilter(obj, function() {
43 - return true;
44 - });
45 - expect(filtered).not.toBe(obj);
46 - expect(filtered).toEqual(obj);
47 - });
48 -
49 - it('should return empty object for a falsey func', function() {
50 - var filtered = objFilter(obj, function() {
51 - return false;
52 - });
53 - expect(filtered).toEqual({});
54 - });
55 -
56 - it('should filter based on value', function() {
57 - var filtered = objFilter(obj, function(value) {
58 - return value.indexOf('berry') !== -1;
59 - });
60 - expect(filtered).toEqual({
61 - E: 'elderberry',
62 - H: 'hackberry'
63 - });
64 - });
65 -
66 - it('should filter based on key', function() {
67 - var filtered = objFilter(obj, function(value, key) {
68 - return (/[AEIOU]/).test(key);
69 - });
70 - expect(filtered).toEqual({
71 - A: 'apple',
72 - E: 'elderberry'
73 - });
74 - });
75 -
76 - it('should filter based on iteration', function() {
77 - var filtered = objFilter(obj, function(value, key, iteration) {
78 - return iteration % 2;
79 - });
80 - expect(filtered).toEqual({
81 - B: 'banana',
82 - D: 'durian',
83 - F: 'fig',
84 - H: 'hackberry'
85 - });
86 - });
87 -
88 -});
React/utils/__tests__/objMap-test.js deleted
-113
@@ -1,113 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * @emails react-core
17 - */
18 -
19 -"use strict";
20 -
21 -var objMap = require("../../objMap");
22 -
23 -describe('objMap', function() {
24 -
25 - var obj = {
26 - A: 'apple',
27 - B: 'banana',
28 - C: 'coconut',
29 - D: 'durian',
30 - E: 'elderberry',
31 - F: 'fig',
32 - G: 'guava',
33 - H: 'hackberry'
34 - };
35 -
36 - it('should accept null', function() {
37 - var mapped = objMap(null, function() {});
38 - expect(mapped).toBe(null);
39 - });
40 -
41 - it('should return value to create copy', function() {
42 - var mapped = objMap(obj, function(value) {
43 - return value;
44 - });
45 - expect(mapped).not.toBe(obj);
46 - expect(mapped).toEqual(obj);
47 - });
48 -
49 - it('should always retain keys', function() {
50 - var mapped = objMap(obj, function() {
51 - return null;
52 - });
53 - expect(mapped).toEqual({
54 - A: null,
55 - B: null,
56 - C: null,
57 - D: null,
58 - E: null,
59 - F: null,
60 - G: null,
61 - H: null
62 - });
63 - });
64 -
65 - it('should map values', function() {
66 - var mapped = objMap(obj, function (value) {
67 - return value.toUpperCase();
68 - });
69 - expect(mapped).toEqual({
70 - A: 'APPLE',
71 - B: 'BANANA',
72 - C: 'COCONUT',
73 - D: 'DURIAN',
74 - E: 'ELDERBERRY',
75 - F: 'FIG',
76 - G: 'GUAVA',
77 - H: 'HACKBERRY'
78 - });
79 - });
80 -
81 - it('should map keys', function() {
82 - var mapped = objMap(obj, function (value, key) {
83 - return key;
84 - });
85 - expect(mapped).toEqual({
86 - A: 'A',
87 - B: 'B',
88 - C: 'C',
89 - D: 'D',
90 - E: 'E',
91 - F: 'F',
92 - G: 'G',
93 - H: 'H'
94 - });
95 - });
96 -
97 - it('should map iterations', function() {
98 - var mapped = objMap(obj, function (value, key, iteration) {
99 - return iteration;
100 - });
101 - expect(mapped).toEqual({
102 - A: 0,
103 - B: 1,
104 - C: 2,
105 - D: 3,
106 - E: 4,
107 - F: 5,
108 - G: 6,
109 - H: 7
110 - });
111 - });
112 -
113 -});
React/vendor/error/__tests__/erx-test.js deleted
-58
@@ -1,58 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * Copyright 2004-present Facebook. All Rights Reserved.
17 - *
18 - * @emails catchen@fb.com
19 - * @emails javascript@lists.facebook.com
20 - */
21 -
22 -require("../../../mock-modules")
23 - .dontMock('erx')
24 - .dontMock('ex');
25 -
26 -describe('erx', function() {
27 - var erx = require("../../../erx");
28 - var ex = require("../../../ex");
29 -
30 - it('should always reverse ex if placeholder and argument match', function() {
31 - expect(erx(ex('zero argument'))).toEqual(['zero argument']);
32 - expect(erx(ex('one argument: %s', 'one')))
33 - .toEqual(['one argument: %s', 'one']);
34 - expect(erx(ex('two arguments: %s, %s', 'one', 2)))
35 - .toEqual(['two arguments: %s, %s', 'one', '2']);
36 - expect(erx(ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 })))
37 - .toEqual(['three arguments: %s, %s, %s', 'one', '2', '[object Object]']);
38 - });
39 -
40 - it('should be idempotent', function() {
41 - var messageWithParams = erx(ex('one argument: %s', 'one'));
42 - expect(messageWithParams).toEqual(erx(messageWithParams));
43 - });
44 -
45 - it('should treat plain text as it was ex-ed with no argument', function() {
46 - expect(erx('plain text')).toEqual(['plain text']);
47 - });
48 -
49 - it('should work when text was appended/prepended to ex-ed text', function() {
50 - expect(erx('prepended text|' + ex('zero argument') + '|appended text'))
51 - .toEqual(['prepended text|zero argument|appended text']);
52 - expect(erx(
53 - 'prepended text|' +
54 - ex('one argument: %s', 'one') +
55 - '|appended text'
56 - )).toEqual(['prepended text|one argument: %s|appended text', 'one']);
57 - });
58 -});
React/vendor/error/__tests__/ex-test.js deleted
-43
@@ -1,43 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * Copyright 2004-present Facebook. All Rights Reserved.
17 - *
18 - * @emails catchen@fb.com
19 - * @emails javascript@lists.facebook.com
20 - */
21 -
22 -require("../../../mock-modules")
23 - .dontMock('ex');
24 -
25 -describe('ex', function() {
26 - var ex = require("../../../ex");
27 -
28 - it('should convert whatever arguments into one string', function() {
29 - expect(typeof ex('zero argument')).toEqual('string');
30 - expect(typeof ex('one argument: %s', 'one')).toEqual('string');
31 - expect(typeof ex('two arguments: %s, %s', 'one', 2))
32 - .toEqual('string');
33 - expect(typeof ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 }))
34 - .toEqual('string');
35 - });
36 -
37 - it('should handle placeholder and argument number mismatch', function() {
38 - expect(typeof ex('zero placeholder and one argument', 'one'))
39 - .toEqual('string');
40 - expect(typeof ex('one placeholder and zero argument: %s'))
41 - .toEqual('string');
42 - });
43 -});
all/HtmlReporter.js deleted
-168
@@ -1,168 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -
3 -exports.HtmlReporter =
4 -jasmine.HtmlReporter = function(_doc) {
5 - var self = this;
6 - var doc = _doc || window.document;
7 -
8 - var reporterView;
9 -
10 - var dom = {};
11 -
12 - // Jasmine Reporter Public Interface
13 - self.logRunningSpecs = false;
14 -
15 - self.reportRunnerStarting = function(runner) {
16 - var specs = runner.specs() || [];
17 -
18 - if (specs.length == 0) {
19 - return;
20 - }
21 -
22 - createReporterDom(runner.env.versionString());
23 - doc.body.appendChild(dom.reporter);
24 - setExceptionHandling();
25 -
26 - reporterView = new jasmine.HtmlReporter.ReporterView(dom);
27 - reporterView.addSpecs(specs, self.specFilter);
28 - };
29 -
30 - self.reportRunnerResults = function(runner) {
31 - reporterView && reporterView.complete();
32 - };
33 -
34 - self.reportSuiteResults = function(suite) {
35 - reporterView.suiteComplete(suite);
36 - };
37 -
38 - self.reportSpecStarting = function(spec) {
39 - if (self.logRunningSpecs) {
40 - self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
41 - }
42 - };
43 -
44 - self.reportSpecResults = function(spec) {
45 - reporterView.specComplete(spec);
46 - };
47 -
48 - self.log = function() {
49 - var console = jasmine.getGlobal().console;
50 - if (console && console.log) {
51 - if (console.log.apply) {
52 - console.log.apply(console, arguments);
53 - } else {
54 - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
55 - }
56 - }
57 - };
58 -
59 - self.specFilter = function(spec) {
60 - if (!focusedSpecName()) {
61 - return true;
62 - }
63 -
64 - return spec.getFullName().indexOf(focusedSpecName()) === 0;
65 - };
66 -
67 - return self;
68 -
69 - function focusedSpecName() {
70 - var specName;
71 -
72 - (function memoizeFocusedSpec() {
73 - if (specName) {
74 - return;
75 - }
76 -
77 - var paramMap = [];
78 - var params = jasmine.HtmlReporter.parameters(doc);
79 -
80 - for (var i = 0; i < params.length; i++) {
81 - var p = params[i].split('=');
82 - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
83 - }
84 -
85 - specName = paramMap.spec;
86 - })();
87 -
88 - return specName;
89 - }
90 -
91 - function createReporterDom(version) {
92 - dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
93 - dom.banner = self.createDom('div', { className: 'banner' },
94 - self.createDom('span', { className: 'title' }, "Jasmine "),
95 - self.createDom('span', { className: 'version' }, version)),
96 -
97 - dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
98 - dom.alert = self.createDom('div', {className: 'alert'},
99 - self.createDom('span', { className: 'exceptions' },
100 - self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
101 - self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
102 - dom.results = self.createDom('div', {className: 'results'},
103 - dom.summary = self.createDom('div', { className: 'summary' }),
104 - dom.details = self.createDom('div', { id: 'details' }))
105 - );
106 - }
107 -
108 - function noTryCatch() {
109 - return window.location.search.match(/catch=false/);
110 - }
111 -
112 - function searchWithCatch() {
113 - var params = jasmine.HtmlReporter.parameters(window.document);
114 - var removed = false;
115 - var i = 0;
116 -
117 - while (!removed && i < params.length) {
118 - if (params[i].match(/catch=/)) {
119 - params.splice(i, 1);
120 - removed = true;
121 - }
122 - i++;
123 - }
124 - if (jasmine.CATCH_EXCEPTIONS) {
125 - params.push("catch=false");
126 - }
127 -
128 - return params.join("&");
129 - }
130 -
131 - function setExceptionHandling() {
132 - var chxCatch = document.getElementById('no_try_catch');
133 -
134 - if (noTryCatch()) {
135 - chxCatch.setAttribute('checked', true);
136 - jasmine.CATCH_EXCEPTIONS = false;
137 - }
138 - chxCatch.onclick = function() {
139 - window.location.search = searchWithCatch();
140 - };
141 - }
142 -};
143 -jasmine.HtmlReporter.parameters = function(doc) {
144 - var paramStr = doc.location.search.substring(1);
145 - var params = [];
146 -
147 - if (paramStr.length > 0) {
148 - params = paramStr.split('&');
149 - }
150 - return params;
151 -}
152 -jasmine.HtmlReporter.sectionLink = function(sectionName) {
153 - var link = '?';
154 - var params = [];
155 -
156 - if (sectionName) {
157 - params.push('spec=' + encodeURIComponent(sectionName));
158 - }
159 - if (!jasmine.CATCH_EXCEPTIONS) {
160 - params.push("catch=false");
161 - }
162 - if (params.length > 0) {
163 - link += params.join("&");
164 - }
165 -
166 - return link;
167 -};
168 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
all/PrintReporter.js deleted
-128
@@ -1,128 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -var diff = require('./diff');
3 -
4 -var red = '\u001b[1;41m';
5 -var reset = '\u001b[0m';
6 -
7 -function highlightDifferences(a, b) {
8 - var changes = diff.diffChars(a, b);
9 -
10 - var ret = {a: '', b: ''};
11 - var change;
12 - for (var i = 0, il = changes.length; i < il; i++) {
13 - change = changes[i];
14 - if (change.added) {
15 - ret.b += red + change.value + reset;
16 - } else if (change.removed) {
17 - ret.a += red + change.value + reset;
18 - } else {
19 - ret.a += change.value;
20 - ret.b += change.value;
21 - }
22 - }
23 - return ret;
24 -}
25 -
26 -function PrintReporter(name, root_directory) {
27 - this.skipCount = 0;
28 - this.failCount = 0;
29 - this.expectCount = 0;
30 - this.specCount = 0;
31 - this.name = name;
32 - this.rootDirectory = root_directory;
33 -}
34 -exports.PrintReporter =
35 -jasmine.PrintReporter = PrintReporter;
36 -
37 -PrintReporter.prototype = new jasmine.Reporter();
38 -// Set verbose=true on the test instance to enable additional logging
39 -PrintReporter.prototype.verbose = false;
40 -PrintReporter.prototype._didSpecName = false;
41 -
42 -PrintReporter.prototype.reportSpecStarting = function(spec) {
43 - this._didSpecName = false;
44 - this._spec = spec;
45 -};
46 -
47 -PrintReporter.prototype.reportRunnerResults = function(runner) {
48 - // Don't print out the spec name at the end
49 - this._didSpecName = true;
50 -
51 - this.log([
52 - this.specCount + " spec",
53 - this.expectCount + " expect",
54 - this.skipCount + " skip",
55 - this.failCount + " fail"
56 - ].join(" "));
57 -
58 - require("./phantom").exit(this.failCount);
59 -};
60 -
61 -
62 -PrintReporter.prototype.reportSuiteResults = function(suite) {
63 - var results = suite.results();
64 - if (this.verbose) {
65 - this.log('Suite "' + suite.description + '": ' +
66 - results.passedCount + '/' + results.totalCount + ' passed.');
67 - }
68 -
69 - // If suite is nested, only count the root suite
70 - if (!suite.parentSuite) {
71 - this.failCount += results.totalCount - results.passedCount;
72 - this.expectCount += results.totalCount;
73 - }
74 -};
75 -
76 -PrintReporter.prototype.reportSpecResults = function(spec) {
77 - if (this.verbose) {
78 - this.log('it... ' +
79 - spec.description + ': ' + (spec.results().passed() ? 'pass' : 'fail'));
80 - }
81 -
82 - var self = this;
83 - var results = spec.results();
84 -
85 - this.specCount += 1;
86 -
87 - if (results.skipped)
88 - this.skipCount += 1;
89 -
90 - results.getItems().forEach(function(result) {
91 - if (result.type == 'log') {
92 - self.log(result.toString());
93 - } else if (result.type == 'expect' && result.passed && !result.passed()) {
94 - var ppActual = jasmine.pp(result.actual);
95 - var ppExpected = jasmine.pp(result.expected);
96 -
97 - var colorDiff = highlightDifferences(ppActual, ppExpected);
98 -
99 - var message = result.message;
100 - message = message.replace(ppActual, colorDiff.a);
101 - message = message.replace(ppExpected, colorDiff.b);
102 -
103 - self.log(message);
104 - if (result.trace.stack) {
105 - self.log();
106 - result.trace.stack.split('\n').forEach(function(stackFrame) {
107 - if (stackFrame.indexOf('/jasmine/lib/jasmine-core') > -1) {
108 - return;
109 - }
110 - if (this.rootDirectory) {
111 - stackFrame = stackFrame.replace(this.rootDirectory + '/', '');
112 - }
113 - self.log(' ' + stackFrame);
114 - }.bind(this));
115 - }
116 - }
117 - });
118 -};
119 -
120 -PrintReporter.prototype.log = function(str) {
121 - if (!this._didSpecName) {
122 - console.log('');
123 - console.log(
124 - this._spec.suite.description + ': it ' + this._spec.description);
125 - this._didSpecName = true;
126 - }
127 - console.log(str || '');
128 -};
all/ReporterView.js deleted
-166
@@ -1,166 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -
3 -jasmine.HtmlReporter.ReporterView = function(dom) {
4 - this.startedAt = new Date();
5 - this.runningSpecCount = 0;
6 - this.completeSpecCount = 0;
7 - this.passedCount = 0;
8 - this.failedCount = 0;
9 - this.skippedCount = 0;
10 -
11 - this.createResultsMenu = function() {
12 - this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
13 - this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
14 - ' | ',
15 - this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
16 -
17 - this.summaryMenuItem.onclick = function() {
18 - dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
19 - };
20 -
21 - this.detailsMenuItem.onclick = function() {
22 - showDetails();
23 - };
24 - };
25 -
26 - this.addSpecs = function(specs, specFilter) {
27 - this.totalSpecCount = specs.length;
28 -
29 - this.views = {
30 - specs: {},
31 - suites: {}
32 - };
33 -
34 - for (var i = 0; i < specs.length; i++) {
35 - var spec = specs[i];
36 - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
37 - if (specFilter(spec)) {
38 - this.runningSpecCount++;
39 - }
40 - }
41 - };
42 -
43 - this.specComplete = function(spec) {
44 - this.completeSpecCount++;
45 -
46 - if (isUndefined(this.views.specs[spec.id])) {
47 - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
48 - }
49 -
50 - var specView = this.views.specs[spec.id];
51 -
52 - switch (specView.status()) {
53 - case 'passed':
54 - this.passedCount++;
55 - break;
56 -
57 - case 'failed':
58 - this.failedCount++;
59 - break;
60 -
61 - case 'skipped':
62 - this.skippedCount++;
63 - break;
64 - }
65 -
66 - specView.refresh();
67 - this.refresh();
68 - };
69 -
70 - this.suiteComplete = function(suite) {
71 - var suiteView = this.views.suites[suite.id];
72 - if (isUndefined(suiteView)) {
73 - return;
74 - }
75 - suiteView.refresh();
76 - };
77 -
78 - this.refresh = function() {
79 -
80 - if (isUndefined(this.resultsMenu)) {
81 - this.createResultsMenu();
82 - }
83 -
84 - // currently running UI
85 - if (isUndefined(this.runningAlert)) {
86 - this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
87 - dom.alert.appendChild(this.runningAlert);
88 - }
89 - this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
90 -
91 - // skipped specs UI
92 - if (isUndefined(this.skippedAlert)) {
93 - this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
94 - }
95 -
96 - this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
97 -
98 - if (this.skippedCount === 1 && isDefined(dom.alert)) {
99 - dom.alert.appendChild(this.skippedAlert);
100 - }
101 -
102 - // passing specs UI
103 - if (isUndefined(this.passedAlert)) {
104 - this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
105 - }
106 - this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
107 -
108 - // failing specs UI
109 - if (isUndefined(this.failedAlert)) {
110 - this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
111 - }
112 - this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
113 -
114 - if (this.failedCount === 1 && isDefined(dom.alert)) {
115 - dom.alert.appendChild(this.failedAlert);
116 - dom.alert.appendChild(this.resultsMenu);
117 - }
118 -
119 - // summary info
120 - this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
121 - this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
122 - };
123 -
124 - this.complete = function() {
125 - dom.alert.removeChild(this.runningAlert);
126 -
127 - this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
128 -
129 - if (this.failedCount === 0) {
130 - dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
131 - } else {
132 - showDetails();
133 - }
134 -
135 - dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
136 - };
137 -
138 - return this;
139 -
140 - function showDetails() {
141 - if (dom.reporter.className.search(/showDetails/) === -1) {
142 - dom.reporter.className += " showDetails";
143 - }
144 - }
145 -
146 - function isUndefined(obj) {
147 - return typeof obj === 'undefined';
148 - }
149 -
150 - function isDefined(obj) {
151 - return !isUndefined(obj);
152 - }
153 -
154 - function specPluralizedFor(count) {
155 - var str = count + " spec";
156 - if (count > 1) {
157 - str += "s"
158 - }
159 - return str;
160 - }
161 -
162 -};
163 -
164 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
165 -
166 -
all/SpecView.js deleted
-81
@@ -1,81 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -
3 -jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
4 - this.spec = spec;
5 - this.dom = dom;
6 - this.views = views;
7 -
8 - this.symbol = this.createDom('li', { className: 'pending' });
9 - this.dom.symbolSummary.appendChild(this.symbol);
10 -
11 - this.summary = this.createDom('div', { className: 'specSummary' },
12 - this.createDom('a', {
13 - className: 'description',
14 - href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
15 - title: this.spec.getFullName()
16 - }, this.spec.description)
17 - );
18 -
19 - this.detail = this.createDom('div', { className: 'specDetail' },
20 - this.createDom('a', {
21 - className: 'description',
22 - href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
23 - title: this.spec.getFullName()
24 - }, this.spec.getFullName())
25 - );
26 -};
27 -
28 -jasmine.HtmlReporter.SpecView.prototype.status = function() {
29 - return this.getSpecStatus(this.spec);
30 -};
31 -
32 -jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
33 - this.symbol.className = this.status();
34 -
35 - switch (this.status()) {
36 - case 'skipped':
37 - break;
38 -
39 - case 'passed':
40 - this.appendSummaryToSuiteDiv();
41 - break;
42 -
43 - case 'failed':
44 - this.appendSummaryToSuiteDiv();
45 - this.appendFailureDetail();
46 - break;
47 - }
48 -};
49 -
50 -jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
51 - this.summary.className += ' ' + this.status();
52 - this.appendToSummary(this.spec, this.summary);
53 -};
54 -
55 -jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
56 - this.detail.className += ' ' + this.status();
57 -
58 - var resultItems = this.spec.results().getItems();
59 - var messagesDiv = this.createDom('div', { className: 'messages' });
60 -
61 - for (var i = 0; i < resultItems.length; i++) {
62 - var result = resultItems[i];
63 -
64 - if (result.type == 'log') {
65 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
66 - } else if (result.type == 'expect' && result.passed && !result.passed()) {
67 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
68 -
69 - if (result.trace.stack) {
70 - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
71 - }
72 - }
73 - }
74 -
75 - if (messagesDiv.childNodes.length > 0) {
76 - this.detail.appendChild(messagesDiv);
77 - this.dom.details.appendChild(this.detail);
78 - }
79 -};
80 -
81 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);
\ No newline at end of file
all/SuiteView.js deleted
-24
@@ -1,24 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -
3 -jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
4 - this.suite = suite;
5 - this.dom = dom;
6 - this.views = views;
7 -
8 - this.element = this.createDom('div', { className: 'suite' },
9 - this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
10 - );
11 -
12 - this.appendToSummary(this.suite, this.element);
13 -};
14 -
15 -jasmine.HtmlReporter.SuiteView.prototype.status = function() {
16 - return this.getSpecStatus(this.suite);
17 -};
18 -
19 -jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
20 - this.element.className += " " + this.status();
21 -};
22 -
23 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
24 -
all/all.js deleted
-38
@@ -1,38 +0,0 @@
1 -require("./phantom");
2 -require("./console");
3 -
4 -// TODO Also bundle jasmine.css here.
5 -var jasmine = require("./jasmine");
6 -require("./jasmine-html");
7 -require("./jasmine-support");
8 -
9 -require("./HtmlReporter");
10 -require("./PrintReporter");
11 -require("./ReporterView");
12 -require("./SpecView");
13 -require("./SuiteView");
14 -
15 -var env = jasmine.getEnv();
16 -env.addReporter(new jasmine.HtmlReporter);
17 -env.addReporter(new jasmine.PrintReporter);
18 -
19 -function exposeFrom(obj) {
20 - obj.spyOn = jasmine.spyOn;
21 - obj.it = jasmine.it;
22 - obj.xit = jasmine.xit;
23 - obj.expect = jasmine.expect;
24 - obj.runs = jasmine.runs;
25 - obj.waits = jasmine.waits;
26 - obj.waitsFor = jasmine.waitsFor;
27 - obj.beforeEach = jasmine.beforeEach;
28 - obj.afterEach = jasmine.afterEach;
29 - obj.describe = jasmine.describe;
30 - obj.xdescribe = jasmine.xdescribe;
31 - obj.jasmine = jasmine;
32 - return obj;
33 -}
34 -jasmine.exposeFrom = exposeFrom;
35 -var global = Function("return this")();
36 -exposeFrom(global);
37 -
38 -module.exports = jasmine;
all/console.js deleted
-92
@@ -1,92 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * This module allows interception of console.* method calls, so that
17 - * listeners other than the native console object can consume logged
18 - * messages.
19 - */
20 -
21 -var global = Function("return this")();
22 -var Ap = Array.prototype;
23 -var slice = Ap.slice;
24 -
25 -var nativeConsole;
26 -if ("console" in global) {
27 - var gc = global.console;
28 - try { delete global.console } catch (ignored) {}
29 - nativeConsole = global.console || gc;
30 - global.console = gc;
31 -}
32 -
33 -// Provide a reliable console interface in all browsers.
34 -global.console = exports;
35 -
36 -function makeLogger(method) {
37 - var logger = exports[method] = function() {
38 - var args = slice.call(arguments);
39 - listeners.forEach(function(listener) {
40 - listener(method, args, logger);
41 - });
42 - };
43 -}
44 -
45 -makeLogger("info");
46 -makeLogger("log");
47 -makeLogger("debug");
48 -makeLogger("warn");
49 -makeLogger("error");
50 -makeLogger("dir");
51 -makeLogger("dirxml");
52 -makeLogger("trace");
53 -makeLogger("assert");
54 -makeLogger("count");
55 -makeLogger("markTimeline");
56 -makeLogger("profile");
57 -makeLogger("profileEnd");
58 -makeLogger("time");
59 -makeLogger("timeEnd");
60 -makeLogger("timeStamp");
61 -makeLogger("group");
62 -makeLogger("groupCollapsed");
63 -makeLogger("groupEnd");
64 -makeLogger("clear");
65 -
66 -var listeners = [];
67 -function addListener(listener) {
68 - listeners.push(listener);
69 -}
70 -exports.addListener = addListener
71 -
72 -function clean(arg) {
73 - if (typeof arg === "string") {
74 - // Remove any xterm-color escape sequences.
75 - // TODO Display colors in console if possible.
76 - arg = arg.replace(/\033\[\d+m/g, "");
77 - }
78 - return arg;
79 -}
80 -
81 -if (nativeConsole) {
82 - // If present, the native console object becomes a listener just like
83 - // any other.
84 - addListener(function(method, args) {
85 - var method = nativeConsole[method];
86 - if (method) {
87 - method.apply(nativeConsole, args.map(clean));
88 - } else {
89 - // Ignore this call.
90 - }
91 - });
92 -}
all/diff.js deleted
-349
@@ -1,349 +0,0 @@
1 -/* See LICENSE file for terms of use */
2 -
3 -/*
4 - * Text diff implementation.
5 - *
6 - * This library supports the following APIS:
7 - * JsDiff.diffChars: Character by character diff
8 - * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
9 - * JsDiff.diffLines: Line based diff
10 - *
11 - * JsDiff.diffCss: Diff targeted at CSS content
12 - *
13 - * These methods are based on the implementation proposed in
14 - * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
15 - * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
16 - */
17 -var JsDiff = (function() {
18 - function clonePath(path) {
19 - return { newPos: path.newPos, components: path.components.slice(0) };
20 - }
21 - function removeEmpty(array) {
22 - var ret = [];
23 - for (var i = 0; i < array.length; i++) {
24 - if (array[i]) {
25 - ret.push(array[i]);
26 - }
27 - }
28 - return ret;
29 - }
30 - function escapeHTML(s) {
31 - var n = s;
32 - n = n.replace(/&/g, "&amp;");
33 - n = n.replace(/</g, "&lt;");
34 - n = n.replace(/>/g, "&gt;");
35 - n = n.replace(/"/g, "&quot;");
36 -
37 - return n;
38 - }
39 -
40 - var fbDiff = function(ignoreWhitespace) {
41 - this.ignoreWhitespace = ignoreWhitespace;
42 - };
43 - fbDiff.prototype = {
44 - diff: function(oldString, newString) {
45 - // Handle the identity case (this is due to unrolling editLength == 0
46 - if (newString == oldString) {
47 - return [{ value: newString }];
48 - }
49 - if (!newString) {
50 - return [{ value: oldString, removed: true }];
51 - }
52 - if (!oldString) {
53 - return [{ value: newString, added: true }];
54 - }
55 -
56 - newString = this.tokenize(newString);
57 - oldString = this.tokenize(oldString);
58 -
59 - var newLen = newString.length, oldLen = oldString.length;
60 - var maxEditLength = newLen + oldLen;
61 - var bestPath = [{ newPos: -1, components: [] }];
62 -
63 - // Seed editLength = 0
64 - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
65 - if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
66 - return bestPath[0].components;
67 - }
68 -
69 - for (var editLength = 1; editLength <= maxEditLength; editLength++) {
70 - for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
71 - var basePath;
72 - var addPath = bestPath[diagonalPath-1],
73 - removePath = bestPath[diagonalPath+1];
74 - oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
75 - if (addPath) {
76 - // No one else is going to attempt to use this value, clear it
77 - bestPath[diagonalPath-1] = undefined;
78 - }
79 -
80 - var canAdd = addPath && addPath.newPos+1 < newLen;
81 - var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
82 - if (!canAdd && !canRemove) {
83 - bestPath[diagonalPath] = undefined;
84 - continue;
85 - }
86 -
87 - // Select the diagonal that we want to branch from. We select the prior
88 - // path whose position in the new string is the farthest from the origin
89 - // and does not pass the bounds of the diff graph
90 - if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
91 - basePath = clonePath(removePath);
92 - this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
93 - } else {
94 - basePath = clonePath(addPath);
95 - basePath.newPos++;
96 - this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
97 - }
98 -
99 - var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
100 -
101 - if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
102 - return basePath.components;
103 - } else {
104 - bestPath[diagonalPath] = basePath;
105 - }
106 - }
107 - }
108 - },
109 -
110 - pushComponent: function(components, value, added, removed) {
111 - var last = components[components.length-1];
112 - if (last && last.added === added && last.removed === removed) {
113 - // We need to clone here as the component clone operation is just
114 - // as shallow array clone
115 - components[components.length-1] =
116 - {value: this.join(last.value, value), added: added, removed: removed };
117 - } else {
118 - components.push({value: value, added: added, removed: removed });
119 - }
120 - },
121 - extractCommon: function(basePath, newString, oldString, diagonalPath) {
122 - var newLen = newString.length,
123 - oldLen = oldString.length,
124 - newPos = basePath.newPos,
125 - oldPos = newPos - diagonalPath;
126 - while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
127 - newPos++;
128 - oldPos++;
129 -
130 - this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
131 - }
132 - basePath.newPos = newPos;
133 - return oldPos;
134 - },
135 -
136 - equals: function(left, right) {
137 - var reWhitespace = /\S/;
138 - if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
139 - return true;
140 - } else {
141 - return left == right;
142 - }
143 - },
144 - join: function(left, right) {
145 - return left + right;
146 - },
147 - tokenize: function(value) {
148 - return value;
149 - }
150 - };
151 -
152 - var CharDiff = new fbDiff();
153 -
154 - var WordDiff = new fbDiff(true);
155 - WordDiff.tokenize = function(value) {
156 - return removeEmpty(value.split(/(\s+|\b)/));
157 - };
158 -
159 - var CssDiff = new fbDiff(true);
160 - CssDiff.tokenize = function(value) {
161 - return removeEmpty(value.split(/([{}:;,]|\s+)/));
162 - };
163 -
164 - var LineDiff = new fbDiff();
165 - LineDiff.tokenize = function(value) {
166 - return value.split(/^/m);
167 - };
168 -
169 - return {
170 - diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
171 - diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
172 - diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
173 -
174 - diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
175 -
176 - createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
177 - var ret = [];
178 -
179 - ret.push("Index: " + fileName);
180 - ret.push("===================================================================");
181 - ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
182 - ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
183 -
184 - var diff = LineDiff.diff(oldStr, newStr);
185 - if (!diff[diff.length-1].value) {
186 - diff.pop(); // Remove trailing newline add
187 - }
188 - diff.push({value: "", lines: []}); // Append an empty value to make cleanup easier
189 -
190 - function contextLines(lines) {
191 - return lines.map(function(entry) { return ' ' + entry; });
192 - }
193 - function eofNL(curRange, i, current) {
194 - var last = diff[diff.length-2],
195 - isLast = i === diff.length-2,
196 - isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
197 -
198 - // Figure out if this is the last line for the given file and missing NL
199 - if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
200 - curRange.push('\\ No newline at end of file');
201 - }
202 - }
203 -
204 - var oldRangeStart = 0, newRangeStart = 0, curRange = [],
205 - oldLine = 1, newLine = 1;
206 - for (var i = 0; i < diff.length; i++) {
207 - var current = diff[i],
208 - lines = current.lines || current.value.replace(/\n$/, "").split("\n");
209 - current.lines = lines;
210 -
211 - if (current.added || current.removed) {
212 - if (!oldRangeStart) {
213 - var prev = diff[i-1];
214 - oldRangeStart = oldLine;
215 - newRangeStart = newLine;
216 -
217 - if (prev) {
218 - curRange = contextLines(prev.lines.slice(-4));
219 - oldRangeStart -= curRange.length;
220 - newRangeStart -= curRange.length;
221 - }
222 - }
223 - curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
224 - eofNL(curRange, i, current);
225 -
226 - if (current.added) {
227 - newLine += lines.length;
228 - } else {
229 - oldLine += lines.length;
230 - }
231 - } else {
232 - if (oldRangeStart) {
233 - // Close out any changes that have been output (or join overlapping)
234 - if (lines.length <= 8 && i < diff.length-2) {
235 - // Overlapping
236 - curRange.push.apply(curRange, contextLines(lines));
237 - } else {
238 - // end the range and output
239 - var contextSize = Math.min(lines.length, 4);
240 - ret.push(
241 - "@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
242 - + " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
243 - + " @@");
244 - ret.push.apply(ret, curRange);
245 - ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
246 - if (lines.length <= 4) {
247 - eofNL(ret, i, current);
248 - }
249 -
250 - oldRangeStart = 0; newRangeStart = 0; curRange = [];
251 - }
252 - }
253 - oldLine += lines.length;
254 - newLine += lines.length;
255 - }
256 - }
257 -
258 - return ret.join('\n') + '\n';
259 - },
260 -
261 - applyPatch: function(oldStr, uniDiff) {
262 - var diffstr = uniDiff.split("\n");
263 - var diff = [];
264 - var remEOFNL = false,
265 - addEOFNL = false;
266 -
267 - for (var i = (diffstr[0][0]=="I"?4:0); i < diffstr.length; i++) {
268 - if(diffstr[i][0] == "@") {
269 - var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
270 - diff.unshift({
271 - start:meh[3],
272 - oldlength:meh[2],
273 - oldlines:[],
274 - newlength:meh[4],
275 - newlines:[]
276 - });
277 - } else if(diffstr[i][0] == '+') {
278 - diff[0].newlines.push(diffstr[i].substr(1));
279 - } else if(diffstr[i][0] == '-') {
280 - diff[0].oldlines.push(diffstr[i].substr(1));
281 - } else if(diffstr[i][0] == ' ') {
282 - diff[0].newlines.push(diffstr[i].substr(1));
283 - diff[0].oldlines.push(diffstr[i].substr(1));
284 - } else if(diffstr[i][0] == '\\') {
285 - if (diffstr[i-1][0] == '+') {
286 - remEOFNL = true;
287 - } else if(diffstr[i-1][0] == '-') {
288 - addEOFNL = true;
289 - }
290 - }
291 - }
292 -
293 - var str = oldStr.split("\n");
294 - for (var i = diff.length - 1; i >= 0; i--) {
295 - var d = diff[i];
296 - for (var j = 0; j < d.oldlength; j++) {
297 - if(str[d.start-1+j] != d.oldlines[j]) {
298 - return false;
299 - }
300 - }
301 - Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
302 - }
303 -
304 - if (remEOFNL) {
305 - while (!str[str.length-1]) {
306 - str.pop();
307 - }
308 - } else if (addEOFNL) {
309 - str.push('');
310 - }
311 - return str.join('\n');
312 - },
313 -
314 - convertChangesToXML: function(changes){
315 - var ret = [];
316 - for ( var i = 0; i < changes.length; i++) {
317 - var change = changes[i];
318 - if (change.added) {
319 - ret.push("<ins>");
320 - } else if (change.removed) {
321 - ret.push("<del>");
322 - }
323 -
324 - ret.push(escapeHTML(change.value));
325 -
326 - if (change.added) {
327 - ret.push("</ins>");
328 - } else if (change.removed) {
329 - ret.push("</del>");
330 - }
331 - }
332 - return ret.join("");
333 - },
334 -
335 - // See: http://code.google.com/p/google-diff-match-patch/wiki/API
336 - convertChangesToDMP: function(changes){
337 - var ret = [], change;
338 - for ( var i = 0; i < changes.length; i++) {
339 - change = changes[i];
340 - ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
341 - }
342 - return ret;
343 - }
344 - };
345 -})();
346 -
347 -if (typeof module !== "undefined") {
348 - module.exports = JsDiff;
349 -}
all/jasmine-html.js deleted
-683
@@ -1,683 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -
3 -jasmine.HtmlReporterHelpers = {};
4 -
5 -jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
6 - var el = document.createElement(type);
7 -
8 - for (var i = 2; i < arguments.length; i++) {
9 - var child = arguments[i];
10 -
11 - if (typeof child === 'string') {
12 - el.appendChild(document.createTextNode(child));
13 - } else {
14 - if (child) {
15 - el.appendChild(child);
16 - }
17 - }
18 - }
19 -
20 - for (var attr in attrs) {
21 - if (attr == "className") {
22 - el[attr] = attrs[attr];
23 - } else {
24 - el.setAttribute(attr, attrs[attr]);
25 - }
26 - }
27 -
28 - return el;
29 -};
30 -
31 -jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
32 - var results = child.results();
33 - var status = results.passed() ? 'passed' : 'failed';
34 - if (results.skipped) {
35 - status = 'skipped';
36 - }
37 -
38 - return status;
39 -};
40 -
41 -jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
42 - var parentDiv = this.dom.summary;
43 - var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
44 - var parent = child[parentSuite];
45 -
46 - if (parent) {
47 - if (typeof this.views.suites[parent.id] == 'undefined') {
48 - this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
49 - }
50 - parentDiv = this.views.suites[parent.id].element;
51 - }
52 -
53 - parentDiv.appendChild(childElement);
54 -};
55 -
56 -
57 -jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
58 - for(var fn in jasmine.HtmlReporterHelpers) {
59 - ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
60 - }
61 -};
62 -
63 -jasmine.HtmlReporter = function(_doc) {
64 - var self = this;
65 - var doc = _doc || window.document;
66 -
67 - var reporterView;
68 -
69 - var dom = {};
70 -
71 - // Jasmine Reporter Public Interface
72 - self.logRunningSpecs = false;
73 -
74 - self.reportRunnerStarting = function(runner) {
75 - var specs = runner.specs() || [];
76 -
77 - if (specs.length == 0) {
78 - return;
79 - }
80 -
81 - createReporterDom(runner.env.versionString());
82 - doc.body.appendChild(dom.reporter);
83 - setExceptionHandling();
84 -
85 - reporterView = new jasmine.HtmlReporter.ReporterView(dom);
86 - reporterView.addSpecs(specs, self.specFilter);
87 - };
88 -
89 - self.reportRunnerResults = function(runner) {
90 - reporterView && reporterView.complete();
91 - };
92 -
93 - self.reportSuiteResults = function(suite) {
94 - reporterView.suiteComplete(suite);
95 - };
96 -
97 - self.reportSpecStarting = function(spec) {
98 - if (self.logRunningSpecs) {
99 - self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
100 - }
101 - };
102 -
103 - self.reportSpecResults = function(spec) {
104 - reporterView.specComplete(spec);
105 - };
106 -
107 - self.log = function() {
108 - var console = jasmine.getGlobal().console;
109 - if (console && console.log) {
110 - if (console.log.apply) {
111 - console.log.apply(console, arguments);
112 - } else {
113 - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
114 - }
115 - }
116 - };
117 -
118 - self.specFilter = function(spec) {
119 - if (!focusedSpecName()) {
120 - return true;
121 - }
122 -
123 - return spec.getFullName().indexOf(focusedSpecName()) === 0;
124 - };
125 -
126 - return self;
127 -
128 - function focusedSpecName() {
129 - var specName;
130 -
131 - (function memoizeFocusedSpec() {
132 - if (specName) {
133 - return;
134 - }
135 -
136 - var paramMap = [];
137 - var params = jasmine.HtmlReporter.parameters(doc);
138 -
139 - for (var i = 0; i < params.length; i++) {
140 - var p = params[i].split('=');
141 - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
142 - }
143 -
144 - specName = paramMap.spec;
145 - })();
146 -
147 - return specName;
148 - }
149 -
150 - function createReporterDom(version) {
151 - dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
152 - dom.banner = self.createDom('div', { className: 'banner' },
153 - self.createDom('span', { className: 'title' }, "Jasmine "),
154 - self.createDom('span', { className: 'version' }, version)),
155 -
156 - dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
157 - dom.alert = self.createDom('div', {className: 'alert'},
158 - self.createDom('span', { className: 'exceptions' },
159 - self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
160 - self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
161 - dom.results = self.createDom('div', {className: 'results'},
162 - dom.summary = self.createDom('div', { className: 'summary' }),
163 - dom.details = self.createDom('div', { id: 'details' }))
164 - );
165 - }
166 -
167 - function noTryCatch() {
168 - return window.location.search.match(/catch=false/);
169 - }
170 -
171 - function searchWithCatch() {
172 - var params = jasmine.HtmlReporter.parameters(window.document);
173 - var removed = false;
174 - var i = 0;
175 -
176 - while (!removed && i < params.length) {
177 - if (params[i].match(/catch=/)) {
178 - params.splice(i, 1);
179 - removed = true;
180 - }
181 - i++;
182 - }
183 - if (jasmine.CATCH_EXCEPTIONS) {
184 - params.push("catch=false");
185 - }
186 -
187 - return params.join("&");
188 - }
189 -
190 - function setExceptionHandling() {
191 - var chxCatch = document.getElementById('no_try_catch');
192 -
193 - if (noTryCatch()) {
194 - chxCatch.setAttribute('checked', true);
195 - jasmine.CATCH_EXCEPTIONS = false;
196 - }
197 - chxCatch.onclick = function() {
198 - window.location.search = searchWithCatch();
199 - };
200 - }
201 -};
202 -jasmine.HtmlReporter.parameters = function(doc) {
203 - var paramStr = doc.location.search.substring(1);
204 - var params = [];
205 -
206 - if (paramStr.length > 0) {
207 - params = paramStr.split('&');
208 - }
209 - return params;
210 -}
211 -jasmine.HtmlReporter.sectionLink = function(sectionName) {
212 - var link = '?';
213 - var params = [];
214 -
215 - if (sectionName) {
216 - params.push('spec=' + encodeURIComponent(sectionName));
217 - }
218 - if (!jasmine.CATCH_EXCEPTIONS) {
219 - params.push("catch=false");
220 - }
221 - if (params.length > 0) {
222 - link += params.join("&");
223 - }
224 -
225 - return link;
226 -};
227 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
228 -jasmine.HtmlReporter.ReporterView = function(dom) {
229 - this.startedAt = new Date();
230 - this.runningSpecCount = 0;
231 - this.completeSpecCount = 0;
232 - this.passedCount = 0;
233 - this.failedCount = 0;
234 - this.skippedCount = 0;
235 -
236 - this.createResultsMenu = function() {
237 - this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
238 - this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
239 - ' | ',
240 - this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
241 -
242 - this.summaryMenuItem.onclick = function() {
243 - dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
244 - };
245 -
246 - this.detailsMenuItem.onclick = function() {
247 - showDetails();
248 - };
249 - };
250 -
251 - this.addSpecs = function(specs, specFilter) {
252 - this.totalSpecCount = specs.length;
253 -
254 - this.views = {
255 - specs: {},
256 - suites: {}
257 - };
258 -
259 - for (var i = 0; i < specs.length; i++) {
260 - var spec = specs[i];
261 - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
262 - if (specFilter(spec)) {
263 - this.runningSpecCount++;
264 - }
265 - }
266 - };
267 -
268 - this.specComplete = function(spec) {
269 - this.completeSpecCount++;
270 -
271 - if (isUndefined(this.views.specs[spec.id])) {
272 - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
273 - }
274 -
275 - var specView = this.views.specs[spec.id];
276 -
277 - switch (specView.status()) {
278 - case 'passed':
279 - this.passedCount++;
280 - break;
281 -
282 - case 'failed':
283 - this.failedCount++;
284 - break;
285 -
286 - case 'skipped':
287 - this.skippedCount++;
288 - break;
289 - }
290 -
291 - specView.refresh();
292 - this.refresh();
293 - };
294 -
295 - this.suiteComplete = function(suite) {
296 - var suiteView = this.views.suites[suite.id];
297 - if (isUndefined(suiteView)) {
298 - return;
299 - }
300 - suiteView.refresh();
301 - };
302 -
303 - this.refresh = function() {
304 -
305 - if (isUndefined(this.resultsMenu)) {
306 - this.createResultsMenu();
307 - }
308 -
309 - // currently running UI
310 - if (isUndefined(this.runningAlert)) {
311 - this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
312 - dom.alert.appendChild(this.runningAlert);
313 - }
314 - this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
315 -
316 - // skipped specs UI
317 - if (isUndefined(this.skippedAlert)) {
318 - this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
319 - }
320 -
321 - this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
322 -
323 - if (this.skippedCount === 1 && isDefined(dom.alert)) {
324 - dom.alert.appendChild(this.skippedAlert);
325 - }
326 -
327 - // passing specs UI
328 - if (isUndefined(this.passedAlert)) {
329 - this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
330 - }
331 - this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
332 -
333 - // failing specs UI
334 - if (isUndefined(this.failedAlert)) {
335 - this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
336 - }
337 - this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
338 -
339 - if (this.failedCount === 1 && isDefined(dom.alert)) {
340 - dom.alert.appendChild(this.failedAlert);
341 - dom.alert.appendChild(this.resultsMenu);
342 - }
343 -
344 - // summary info
345 - this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
346 - this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
347 - };
348 -
349 - this.complete = function() {
350 - dom.alert.removeChild(this.runningAlert);
351 -
352 - this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
353 -
354 - if (this.failedCount === 0) {
355 - dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
356 - } else {
357 - showDetails();
358 - }
359 -
360 - dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
361 - };
362 -
363 - return this;
364 -
365 - function showDetails() {
366 - if (dom.reporter.className.search(/showDetails/) === -1) {
367 - dom.reporter.className += " showDetails";
368 - }
369 - }
370 -
371 - function isUndefined(obj) {
372 - return typeof obj === 'undefined';
373 - }
374 -
375 - function isDefined(obj) {
376 - return !isUndefined(obj);
377 - }
378 -
379 - function specPluralizedFor(count) {
380 - var str = count + " spec";
381 - if (count > 1) {
382 - str += "s"
383 - }
384 - return str;
385 - }
386 -
387 -};
388 -
389 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
390 -
391 -
392 -jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
393 - this.spec = spec;
394 - this.dom = dom;
395 - this.views = views;
396 -
397 - this.symbol = this.createDom('li', { className: 'pending' });
398 - this.dom.symbolSummary.appendChild(this.symbol);
399 -
400 - this.summary = this.createDom('div', { className: 'specSummary' },
401 - this.createDom('a', {
402 - className: 'description',
403 - href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
404 - title: this.spec.getFullName()
405 - }, this.spec.description)
406 - );
407 -
408 - this.detail = this.createDom('div', { className: 'specDetail' },
409 - this.createDom('a', {
410 - className: 'description',
411 - href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
412 - title: this.spec.getFullName()
413 - }, this.spec.getFullName())
414 - );
415 -};
416 -
417 -jasmine.HtmlReporter.SpecView.prototype.status = function() {
418 - return this.getSpecStatus(this.spec);
419 -};
420 -
421 -jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
422 - this.symbol.className = this.status();
423 -
424 - switch (this.status()) {
425 - case 'skipped':
426 - break;
427 -
428 - case 'passed':
429 - this.appendSummaryToSuiteDiv();
430 - break;
431 -
432 - case 'failed':
433 - this.appendSummaryToSuiteDiv();
434 - this.appendFailureDetail();
435 - break;
436 - }
437 -};
438 -
439 -jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
440 - this.summary.className += ' ' + this.status();
441 - this.appendToSummary(this.spec, this.summary);
442 -};
443 -
444 -jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
445 - this.detail.className += ' ' + this.status();
446 -
447 - var resultItems = this.spec.results().getItems();
448 - var messagesDiv = this.createDom('div', { className: 'messages' });
449 -
450 - for (var i = 0; i < resultItems.length; i++) {
451 - var result = resultItems[i];
452 -
453 - if (result.type == 'log') {
454 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
455 - } else if (result.type == 'expect' && result.passed && !result.passed()) {
456 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
457 -
458 - if (result.trace.stack) {
459 - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
460 - }
461 - }
462 - }
463 -
464 - if (messagesDiv.childNodes.length > 0) {
465 - this.detail.appendChild(messagesDiv);
466 - this.dom.details.appendChild(this.detail);
467 - }
468 -};
469 -
470 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
471 - this.suite = suite;
472 - this.dom = dom;
473 - this.views = views;
474 -
475 - this.element = this.createDom('div', { className: 'suite' },
476 - this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
477 - );
478 -
479 - this.appendToSummary(this.suite, this.element);
480 -};
481 -
482 -jasmine.HtmlReporter.SuiteView.prototype.status = function() {
483 - return this.getSpecStatus(this.suite);
484 -};
485 -
486 -jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
487 - this.element.className += " " + this.status();
488 -};
489 -
490 -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
491 -
492 -/* @deprecated Use jasmine.HtmlReporter instead
493 - */
494 -jasmine.TrivialReporter = function(doc) {
495 - this.document = doc || document;
496 - this.suiteDivs = {};
497 - this.logRunningSpecs = false;
498 -};
499 -
500 -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
501 - var el = document.createElement(type);
502 -
503 - for (var i = 2; i < arguments.length; i++) {
504 - var child = arguments[i];
505 -
506 - if (typeof child === 'string') {
507 - el.appendChild(document.createTextNode(child));
508 - } else {
509 - if (child) { el.appendChild(child); }
510 - }
511 - }
512 -
513 - for (var attr in attrs) {
514 - if (attr == "className") {
515 - el[attr] = attrs[attr];
516 - } else {
517 - el.setAttribute(attr, attrs[attr]);
518 - }
519 - }
520 -
521 - return el;
522 -};
523 -
524 -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
525 - var showPassed, showSkipped;
526 -
527 - this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
528 - this.createDom('div', { className: 'banner' },
529 - this.createDom('div', { className: 'logo' },
530 - this.createDom('span', { className: 'title' }, "Jasmine"),
531 - this.createDom('span', { className: 'version' }, runner.env.versionString())),
532 - this.createDom('div', { className: 'options' },
533 - "Show ",
534 - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
535 - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
536 - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
537 - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
538 - )
539 - ),
540 -
541 - this.runnerDiv = this.createDom('div', { className: 'runner running' },
542 - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
543 - this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
544 - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
545 - );
546 -
547 - this.document.body.appendChild(this.outerDiv);
548 -
549 - var suites = runner.suites();
550 - for (var i = 0; i < suites.length; i++) {
551 - var suite = suites[i];
552 - var suiteDiv = this.createDom('div', { className: 'suite' },
553 - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
554 - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
555 - this.suiteDivs[suite.id] = suiteDiv;
556 - var parentDiv = this.outerDiv;
557 - if (suite.parentSuite) {
558 - parentDiv = this.suiteDivs[suite.parentSuite.id];
559 - }
560 - parentDiv.appendChild(suiteDiv);
561 - }
562 -
563 - this.startedAt = new Date();
564 -
565 - var self = this;
566 - showPassed.onclick = function(evt) {
567 - if (showPassed.checked) {
568 - self.outerDiv.className += ' show-passed';
569 - } else {
570 - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
571 - }
572 - };
573 -
574 - showSkipped.onclick = function(evt) {
575 - if (showSkipped.checked) {
576 - self.outerDiv.className += ' show-skipped';
577 - } else {
578 - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
579 - }
580 - };
581 -};
582 -
583 -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
584 - var results = runner.results();
585 - var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
586 - this.runnerDiv.setAttribute("class", className);
587 - //do it twice for IE
588 - this.runnerDiv.setAttribute("className", className);
589 - var specs = runner.specs();
590 - var specCount = 0;
591 - for (var i = 0; i < specs.length; i++) {
592 - if (this.specFilter(specs[i])) {
593 - specCount++;
594 - }
595 - }
596 - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
597 - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
598 - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
599 -
600 - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
601 -};
602 -
603 -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
604 - var results = suite.results();
605 - var status = results.passed() ? 'passed' : 'failed';
606 - if (results.totalCount === 0) { // todo: change this to check results.skipped
607 - status = 'skipped';
608 - }
609 - this.suiteDivs[suite.id].className += " " + status;
610 -};
611 -
612 -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
613 - if (this.logRunningSpecs) {
614 - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
615 - }
616 -};
617 -
618 -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
619 - var results = spec.results();
620 - var status = results.passed() ? 'passed' : 'failed';
621 - if (results.skipped) {
622 - status = 'skipped';
623 - }
624 - var specDiv = this.createDom('div', { className: 'spec ' + status },
625 - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
626 - this.createDom('a', {
627 - className: 'description',
628 - href: '?spec=' + encodeURIComponent(spec.getFullName()),
629 - title: spec.getFullName()
630 - }, spec.description));
631 -
632 -
633 - var resultItems = results.getItems();
634 - var messagesDiv = this.createDom('div', { className: 'messages' });
635 - for (var i = 0; i < resultItems.length; i++) {
636 - var result = resultItems[i];
637 -
638 - if (result.type == 'log') {
639 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
640 - } else if (result.type == 'expect' && result.passed && !result.passed()) {
641 - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
642 -
643 - if (result.trace.stack) {
644 - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
645 - }
646 - }
647 - }
648 -
649 - if (messagesDiv.childNodes.length > 0) {
650 - specDiv.appendChild(messagesDiv);
651 - }
652 -
653 - this.suiteDivs[spec.suite.id].appendChild(specDiv);
654 -};
655 -
656 -jasmine.TrivialReporter.prototype.log = function() {
657 - var console = jasmine.getGlobal().console;
658 - if (console && console.log) {
659 - if (console.log.apply) {
660 - console.log.apply(console, arguments);
661 - } else {
662 - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
663 - }
664 - }
665 -};
666 -
667 -jasmine.TrivialReporter.prototype.getLocation = function() {
668 - return this.document.location;
669 -};
670 -
671 -jasmine.TrivialReporter.prototype.specFilter = function(spec) {
672 - var paramMap = {};
673 - var params = this.getLocation().search.substring(1).split('&');
674 - for (var i = 0; i < params.length; i++) {
675 - var p = params[i].split('=');
676 - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
677 - }
678 -
679 - if (!paramMap.spec) {
680 - return true;
681 - }
682 - return spec.getFullName().indexOf(paramMap.spec) === 0;
683 -};
all/jasmine-support.js deleted
-127
@@ -1,127 +0,0 @@
1 -var jasmine = require("./jasmine");
2 -var spec = false; // TODO
3 -
4 -// Add some matcher for mock functions
5 -jasmine.getEnv().beforeEach(function() {
6 - this.addMatchers({
7 - toBeCalled: function() {
8 - if (this.actual.mock === undefined) {
9 - throw Error('toBeCalled() should be used on a mock function');
10 - }
11 - return this.actual.mock.calls.length !== 0;
12 - },
13 -
14 - lastCalledWith: function() {
15 - if (this.actual.mock === undefined) {
16 - throw Error('toBeCalled() should be used on a mock function');
17 - }
18 - var calls = this.actual.mock.calls;
19 - var args = Array.prototype.slice.call(arguments);
20 - return this.env.equals_(calls[calls.length - 1], args);
21 - },
22 -
23 - toBeCalledWith: function() {
24 - if (this.actual.mock === undefined) {
25 - throw Error('toBeCalled() should be used on a mock function');
26 - }
27 - var args = Array.prototype.slice.call(arguments);
28 - return this.actual.mock.calls.some(function(call) {
29 - return this.env.equals_(call, args);
30 - }.bind(this));
31 - }
32 - });
33 -});
34 -
35 -var _it = jasmine.Env.prototype.it;
36 -var _xit = jasmine.Env.prototype.xit;
37 -jasmine.Env.prototype.it = function(desc, func) {
38 - // If spec is provided, only run matching specs
39 - if (!spec || desc.match(new RegExp(spec, 'i'))) {
40 - return _it.call(this, desc, func);
41 - } else {
42 - return this.xit(desc, func);
43 - }
44 -};
45 -jasmine.Env.prototype.xit = function(desc, func) {
46 - if (typeof func == 'function') {
47 - var matches = func.toString().match(/.*\W?expect\(/g);
48 - if (matches) {
49 - this.reporter.subReporters_[0].skipCount += matches.length;
50 - this.reporter.subReporters_[0].totalCount += matches.length;
51 - }
52 - }
53 - return _xit.call(this, desc, func);
54 -}
55 -
56 -// Mainline Jasmine sets __Jasmine_been_here_before__ on each object to detect
57 -// cycles, but that doesn't work on frozen objects so we use a WeakMap instead.
58 -// We can only do this if if WeakMap is available, but if WeakMap is
59 -// unavailable, then objects probably can't be frozen anyway.
60 -
61 -if (typeof WeakMap !== "undefined") {
62 - var _comparedObjects = new WeakMap;
63 -
64 - jasmine.Env.prototype.compareObjects_ =
65 - function(a, b, mismatchKeys, mismatchValues) {
66 - if (_comparedObjects.get(a) === b && _comparedObjects.get(b) === a) {
67 - return true;
68 - }
69 - var areArrays = jasmine.isArray_(a) && jasmine.isArray_(b);
70 -
71 - _comparedObjects.set(a, b);
72 - _comparedObjects.set(b, a);
73 -
74 - var hasKey = function(obj, keyName) {
75 - return obj != null && obj[keyName] !== jasmine.undefined;
76 - };
77 -
78 - for (var property in b) {
79 - if (areArrays && typeof b[property] == 'function') {
80 - continue;
81 - }
82 - if (!hasKey(a, property) && hasKey(b, property)) {
83 - mismatchKeys.push(
84 - "expected has key '" + property + "', but missing from actual."
85 - );
86 - }
87 - }
88 - for (property in a) {
89 - if (areArrays && typeof a[property] == 'function') {
90 - continue;
91 - }
92 - if (!hasKey(b, property) && hasKey(a, property)) {
93 - mismatchKeys.push(
94 - "expected missing key '" + property + "', but present in actual."
95 - );
96 - }
97 - }
98 - for (property in b) {
99 - // The only different implementation from the original jasmine
100 - if (areArrays &&
101 - (typeof a[property] == 'function' ||
102 - typeof b[property] == 'function')) {
103 - continue;
104 - }
105 - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues))
106 - {
107 - mismatchValues.push(
108 - "'" + property + "' was '" + (b[property] ?
109 - jasmine.util.htmlEscape(b[property].toString()) :
110 - b[property]) +
111 - "' in expected, but was '" + (a[property] ?
112 - jasmine.util.htmlEscape(a[property].toString()) :
113 - a[property]) + "' in actual."
114 - );
115 - }
116 - }
117 -
118 - if (areArrays &&
119 - a.length != b.length) {
120 - mismatchValues.push("arrays were not the same length");
121 - }
122 -
123 - _comparedObjects.delete(a);
124 - _comparedObjects.delete(b);
125 - return (mismatchKeys.length == 0 && mismatchValues.length == 0);
126 - };
127 -}
all/jasmine.js deleted
-2597
@@ -1,2597 +0,0 @@
1 -/**
2 - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
3 - *
4 - * @namespace
5 - */
6 -var jasmine = {};
7 -exports = module.exports = jasmine;
8 -/**
9 - * @private
10 - */
11 -jasmine.unimplementedMethod_ = function() {
12 - throw new Error("unimplemented method");
13 -};
14 -
15 -/**
16 - * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
17 - * a plain old variable and may be redefined by somebody else.
18 - *
19 - * @private
20 - */
21 -jasmine.undefined = jasmine.___undefined___;
22 -
23 -/**
24 - * Show diagnostic messages in the console if set to true
25 - *
26 - */
27 -jasmine.VERBOSE = false;
28 -
29 -/**
30 - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
31 - *
32 - */
33 -jasmine.DEFAULT_UPDATE_INTERVAL = 250;
34 -
35 -/**
36 - * Maximum levels of nesting that will be included when an object is pretty-printed
37 - */
38 -jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
39 -
40 -/**
41 - * Default timeout interval in milliseconds for waitsFor() blocks.
42 - */
43 -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
44 -
45 -/**
46 - * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
47 - * Set to false to let the exception bubble up in the browser.
48 - *
49 - */
50 -jasmine.CATCH_EXCEPTIONS = true;
51 -
52 -jasmine.getGlobal = function() {
53 - function getGlobal() {
54 - return this;
55 - }
56 -
57 - return getGlobal();
58 -};
59 -
60 -/**
61 - * Allows for bound functions to be compared. Internal use only.
62 - *
63 - * @ignore
64 - * @private
65 - * @param base {Object} bound 'this' for the function
66 - * @param name {Function} function to find
67 - */
68 -jasmine.bindOriginal_ = function(base, name) {
69 - var original = base[name];
70 - if (original.apply) {
71 - return function() {
72 - return original.apply(base, arguments);
73 - };
74 - } else {
75 - // IE support
76 - return jasmine.getGlobal()[name];
77 - }
78 -};
79 -
80 -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
81 -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
82 -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
83 -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
84 -
85 -jasmine.MessageResult = function(values) {
86 - this.type = 'log';
87 - this.values = values;
88 - this.trace = new Error(); // todo: test better
89 -};
90 -
91 -jasmine.MessageResult.prototype.toString = function() {
92 - var text = "";
93 - for (var i = 0; i < this.values.length; i++) {
94 - if (i > 0) text += " ";
95 - if (jasmine.isString_(this.values[i])) {
96 - text += this.values[i];
97 - } else {
98 - text += jasmine.pp(this.values[i]);
99 - }
100 - }
101 - return text;
102 -};
103 -
104 -jasmine.ExpectationResult = function(params) {
105 - this.type = 'expect';
106 - this.matcherName = params.matcherName;
107 - this.passed_ = params.passed;
108 - this.expected = params.expected;
109 - this.actual = params.actual;
110 - this.message = this.passed_ ? 'Passed.' : params.message;
111 -
112 - var trace = (params.trace || new Error(this.message));
113 - this.trace = this.passed_ ? '' : trace;
114 -};
115 -
116 -jasmine.ExpectationResult.prototype.toString = function () {
117 - return this.message;
118 -};
119 -
120 -jasmine.ExpectationResult.prototype.passed = function () {
121 - return this.passed_;
122 -};
123 -
124 -/**
125 - * Getter for the Jasmine environment. Ensures one gets created
126 - */
127 -jasmine.getEnv = function() {
128 - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
129 - return env;
130 -};
131 -
132 -/**
133 - * @ignore
134 - * @private
135 - * @param value
136 - * @returns {Boolean}
137 - */
138 -jasmine.isArray_ = function(value) {
139 - return jasmine.isA_("Array", value);
140 -};
141 -
142 -/**
143 - * @ignore
144 - * @private
145 - * @param value
146 - * @returns {Boolean}
147 - */
148 -jasmine.isString_ = function(value) {
149 - return jasmine.isA_("String", value);
150 -};
151 -
152 -/**
153 - * @ignore
154 - * @private
155 - * @param value
156 - * @returns {Boolean}
157 - */
158 -jasmine.isNumber_ = function(value) {
159 - return jasmine.isA_("Number", value);
160 -};
161 -
162 -/**
163 - * @ignore
164 - * @private
165 - * @param {String} typeName
166 - * @param value
167 - * @returns {Boolean}
168 - */
169 -jasmine.isA_ = function(typeName, value) {
170 - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
171 -};
172 -
173 -/**
174 - * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
175 - *
176 - * @param value {Object} an object to be outputted
177 - * @returns {String}
178 - */
179 -jasmine.pp = function(value) {
180 - var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
181 - stringPrettyPrinter.format(value);
182 - return stringPrettyPrinter.string;
183 -};
184 -
185 -/**
186 - * Returns true if the object is a DOM Node.
187 - *
188 - * @param {Object} obj object to check
189 - * @returns {Boolean}
190 - */
191 -jasmine.isDomNode = function(obj) {
192 - return obj.nodeType > 0;
193 -};
194 -
195 -/**
196 - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
197 - *
198 - * @example
199 - * // don't care about which function is passed in, as long as it's a function
200 - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
201 - *
202 - * @param {Class} clazz
203 - * @returns matchable object of the type clazz
204 - */
205 -jasmine.any = function(clazz) {
206 - return new jasmine.Matchers.Any(clazz);
207 -};
208 -
209 -/**
210 - * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
211 - * attributes on the object.
212 - *
213 - * @example
214 - * // don't care about any other attributes than foo.
215 - * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
216 - *
217 - * @param sample {Object} sample
218 - * @returns matchable object for the sample
219 - */
220 -jasmine.objectContaining = function (sample) {
221 - return new jasmine.Matchers.ObjectContaining(sample);
222 -};
223 -
224 -/**
225 - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
226 - *
227 - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
228 - * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
229 - *
230 - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
231 - *
232 - * Spies are torn down at the end of every spec.
233 - *
234 - * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
235 - *
236 - * @example
237 - * // a stub
238 - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
239 - *
240 - * // spy example
241 - * var foo = {
242 - * not: function(bool) { return !bool; }
243 - * }
244 - *
245 - * // actual foo.not will not be called, execution stops
246 - * spyOn(foo, 'not');
247 -
248 - // foo.not spied upon, execution will continue to implementation
249 - * spyOn(foo, 'not').andCallThrough();
250 - *
251 - * // fake example
252 - * var foo = {
253 - * not: function(bool) { return !bool; }
254 - * }
255 - *
256 - * // foo.not(val) will return val
257 - * spyOn(foo, 'not').andCallFake(function(value) {return value;});
258 - *
259 - * // mock example
260 - * foo.not(7 == 7);
261 - * expect(foo.not).toHaveBeenCalled();
262 - * expect(foo.not).toHaveBeenCalledWith(true);
263 - *
264 - * @constructor
265 - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
266 - * @param {String} name
267 - */
268 -jasmine.Spy = function(name) {
269 - /**
270 - * The name of the spy, if provided.
271 - */
272 - this.identity = name || 'unknown';
273 - /**
274 - * Is this Object a spy?
275 - */
276 - this.isSpy = true;
277 - /**
278 - * The actual function this spy stubs.
279 - */
280 - this.plan = function() {
281 - };
282 - /**
283 - * Tracking of the most recent call to the spy.
284 - * @example
285 - * var mySpy = jasmine.createSpy('foo');
286 - * mySpy(1, 2);
287 - * mySpy.mostRecentCall.args = [1, 2];
288 - */
289 - this.mostRecentCall = {};
290 -
291 - /**
292 - * Holds arguments for each call to the spy, indexed by call count
293 - * @example
294 - * var mySpy = jasmine.createSpy('foo');
295 - * mySpy(1, 2);
296 - * mySpy(7, 8);
297 - * mySpy.mostRecentCall.args = [7, 8];
298 - * mySpy.argsForCall[0] = [1, 2];
299 - * mySpy.argsForCall[1] = [7, 8];
300 - */
301 - this.argsForCall = [];
302 - this.calls = [];
303 -};
304 -
305 -/**
306 - * Tells a spy to call through to the actual implemenatation.
307 - *
308 - * @example
309 - * var foo = {
310 - * bar: function() { // do some stuff }
311 - * }
312 - *
313 - * // defining a spy on an existing property: foo.bar
314 - * spyOn(foo, 'bar').andCallThrough();
315 - */
316 -jasmine.Spy.prototype.andCallThrough = function() {
317 - this.plan = this.originalValue;
318 - return this;
319 -};
320 -
321 -/**
322 - * For setting the return value of a spy.
323 - *
324 - * @example
325 - * // defining a spy from scratch: foo() returns 'baz'
326 - * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
327 - *
328 - * // defining a spy on an existing property: foo.bar() returns 'baz'
329 - * spyOn(foo, 'bar').andReturn('baz');
330 - *
331 - * @param {Object} value
332 - */
333 -jasmine.Spy.prototype.andReturn = function(value) {
334 - this.plan = function() {
335 - return value;
336 - };
337 - return this;
338 -};
339 -
340 -/**
341 - * For throwing an exception when a spy is called.
342 - *
343 - * @example
344 - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
345 - * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
346 - *
347 - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
348 - * spyOn(foo, 'bar').andThrow('baz');
349 - *
350 - * @param {String} exceptionMsg
351 - */
352 -jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
353 - this.plan = function() {
354 - throw exceptionMsg;
355 - };
356 - return this;
357 -};
358 -
359 -/**
360 - * Calls an alternate implementation when a spy is called.
361 - *
362 - * @example
363 - * var baz = function() {
364 - * // do some stuff, return something
365 - * }
366 - * // defining a spy from scratch: foo() calls the function baz
367 - * var foo = jasmine.createSpy('spy on foo').andCall(baz);
368 - *
369 - * // defining a spy on an existing property: foo.bar() calls an anonymnous function
370 - * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
371 - *
372 - * @param {Function} fakeFunc
373 - */
374 -jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
375 - this.plan = fakeFunc;
376 - return this;
377 -};
378 -
379 -/**
380 - * Resets all of a spy's the tracking variables so that it can be used again.
381 - *
382 - * @example
383 - * spyOn(foo, 'bar');
384 - *
385 - * foo.bar();
386 - *
387 - * expect(foo.bar.callCount).toEqual(1);
388 - *
389 - * foo.bar.reset();
390 - *
391 - * expect(foo.bar.callCount).toEqual(0);
392 - */
393 -jasmine.Spy.prototype.reset = function() {
394 - this.wasCalled = false;
395 - this.callCount = 0;
396 - this.argsForCall = [];
397 - this.calls = [];
398 - this.mostRecentCall = {};
399 -};
400 -
401 -jasmine.createSpy = function(name) {
402 -
403 - var spyObj = function() {
404 - spyObj.wasCalled = true;
405 - spyObj.callCount++;
406 - var args = jasmine.util.argsToArray(arguments);
407 - spyObj.mostRecentCall.object = this;
408 - spyObj.mostRecentCall.args = args;
409 - spyObj.argsForCall.push(args);
410 - spyObj.calls.push({object: this, args: args});
411 - return spyObj.plan.apply(this, arguments);
412 - };
413 -
414 - var spy = new jasmine.Spy(name);
415 -
416 - for (var prop in spy) {
417 - spyObj[prop] = spy[prop];
418 - }
419 -
420 - spyObj.reset();
421 -
422 - return spyObj;
423 -};
424 -
425 -/**
426 - * Determines whether an object is a spy.
427 - *
428 - * @param {jasmine.Spy|Object} putativeSpy
429 - * @returns {Boolean}
430 - */
431 -jasmine.isSpy = function(putativeSpy) {
432 - return putativeSpy && putativeSpy.isSpy;
433 -};
434 -
435 -/**
436 - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
437 - * large in one call.
438 - *
439 - * @param {String} baseName name of spy class
440 - * @param {Array} methodNames array of names of methods to make spies
441 - */
442 -jasmine.createSpyObj = function(baseName, methodNames) {
443 - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
444 - throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
445 - }
446 - var obj = {};
447 - for (var i = 0; i < methodNames.length; i++) {
448 - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
449 - }
450 - return obj;
451 -};
452 -
453 -/**
454 - * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
455 - *
456 - * Be careful not to leave calls to <code>jasmine.log</code> in production code.
457 - */
458 -jasmine.log = function() {
459 - var spec = jasmine.getEnv().currentSpec;
460 - spec.log.apply(spec, arguments);
461 -};
462 -
463 -/**
464 - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
465 - *
466 - * @example
467 - * // spy example
468 - * var foo = {
469 - * not: function(bool) { return !bool; }
470 - * }
471 - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
472 - *
473 - * @see jasmine.createSpy
474 - * @param obj
475 - * @param methodName
476 - * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
477 - */
478 -var spyOn = function(obj, methodName) {
479 - return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
480 -};
481 -exports.spyOn = spyOn;
482 -
483 -/**
484 - * Creates a Jasmine spec that will be added to the current suite.
485 - *
486 - * // TODO: pending tests
487 - *
488 - * @example
489 - * it('should be true', function() {
490 - * expect(true).toEqual(true);
491 - * });
492 - *
493 - * @param {String} desc description of this specification
494 - * @param {Function} func defines the preconditions and expectations of the spec
495 - */
496 -var it = function(desc, func) {
497 - return jasmine.getEnv().it(desc, func);
498 -};
499 -exports.it = it;
500 -
501 -/**
502 - * Creates a <em>disabled</em> Jasmine spec.
503 - *
504 - * A convenience method that allows existing specs to be disabled temporarily during development.
505 - *
506 - * @param {String} desc description of this specification
507 - * @param {Function} func defines the preconditions and expectations of the spec
508 - */
509 -var xit = function(desc, func) {
510 - return jasmine.getEnv().xit(desc, func);
511 -};
512 -exports.xit = xit;
513 -
514 -/**
515 - * Starts a chain for a Jasmine expectation.
516 - *
517 - * It is passed an Object that is the actual value and should chain to one of the many
518 - * jasmine.Matchers functions.
519 - *
520 - * @param {Object} actual Actual value to test against and expected value
521 - * @return {jasmine.Matchers}
522 - */
523 -var expect = function(actual) {
524 - return jasmine.getEnv().currentSpec.expect(actual);
525 -};
526 -exports.expect = expect;
527 -
528 -/**
529 - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
530 - *
531 - * @param {Function} func Function that defines part of a jasmine spec.
532 - */
533 -var runs = function(func) {
534 - jasmine.getEnv().currentSpec.runs(func);
535 -};
536 -exports.runs = runs;
537 -
538 -/**
539 - * Waits a fixed time period before moving to the next block.
540 - *
541 - * @deprecated Use waitsFor() instead
542 - * @param {Number} timeout milliseconds to wait
543 - */
544 -var waits = function(timeout) {
545 - jasmine.getEnv().currentSpec.waits(timeout);
546 -};
547 -exports.waits = waits;
548 -
549 -/**
550 - * Waits for the latchFunction to return true before proceeding to the next block.
551 - *
552 - * @param {Function} latchFunction
553 - * @param {String} optional_timeoutMessage
554 - * @param {Number} optional_timeout
555 - */
556 -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
557 - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
558 -};
559 -exports.waitsFor = waitsFor;
560 -
561 -/**
562 - * A function that is called before each spec in a suite.
563 - *
564 - * Used for spec setup, including validating assumptions.
565 - *
566 - * @param {Function} beforeEachFunction
567 - */
568 -var beforeEach = function(beforeEachFunction) {
569 - jasmine.getEnv().beforeEach(beforeEachFunction);
570 -};
571 -exports.beforeEach = beforeEach;
572 -
573 -/**
574 - * A function that is called after each spec in a suite.
575 - *
576 - * Used for restoring any state that is hijacked during spec execution.
577 - *
578 - * @param {Function} afterEachFunction
579 - */
580 -var afterEach = function(afterEachFunction) {
581 - jasmine.getEnv().afterEach(afterEachFunction);
582 -};
583 -exports.afterEach = afterEach;
584 -
585 -/**
586 - * Defines a suite of specifications.
587 - *
588 - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
589 - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
590 - * of setup in some tests.
591 - *
592 - * @example
593 - * // TODO: a simple suite
594 - *
595 - * // TODO: a simple suite with a nested describe block
596 - *
597 - * @param {String} description A string, usually the class under test.
598 - * @param {Function} specDefinitions function that defines several specs.
599 - */
600 -var describe = function(description, specDefinitions) {
601 - return jasmine.getEnv().describe(description, specDefinitions);
602 -};
603 -exports.describe = describe;
604 -
605 -/**
606 - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
607 - *
608 - * @param {String} description A string, usually the class under test.
609 - * @param {Function} specDefinitions function that defines several specs.
610 - */
611 -var xdescribe = function(description, specDefinitions) {
612 - return jasmine.getEnv().xdescribe(description, specDefinitions);
613 -};
614 -exports.xdescribe = xdescribe;
615 -
616 -
617 -// Provide the XMLHttpRequest class for IE 5.x-6.x:
618 -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
619 - function tryIt(f) {
620 - try {
621 - return f();
622 - } catch(e) {
623 - }
624 - return null;
625 - }
626 -
627 - var xhr = tryIt(function() {
628 - return new ActiveXObject("Msxml2.XMLHTTP.6.0");
629 - }) ||
630 - tryIt(function() {
631 - return new ActiveXObject("Msxml2.XMLHTTP.3.0");
632 - }) ||
633 - tryIt(function() {
634 - return new ActiveXObject("Msxml2.XMLHTTP");
635 - }) ||
636 - tryIt(function() {
637 - return new ActiveXObject("Microsoft.XMLHTTP");
638 - });
639 -
640 - if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
641 -
642 - return xhr;
643 -} : XMLHttpRequest;
644 -/**
645 - * @namespace
646 - */
647 -jasmine.util = {};
648 -
649 -/**
650 - * Declare that a child class inherit it's prototype from the parent class.
651 - *
652 - * @private
653 - * @param {Function} childClass
654 - * @param {Function} parentClass
655 - */
656 -jasmine.util.inherit = function(childClass, parentClass) {
657 - /**
658 - * @private
659 - */
660 - var subclass = function() {
661 - };
662 - subclass.prototype = parentClass.prototype;
663 - childClass.prototype = new subclass();
664 -};
665 -
666 -jasmine.util.formatException = function(e) {
667 - var lineNumber;
668 - if (e.line) {
669 - lineNumber = e.line;
670 - }
671 - else if (e.lineNumber) {
672 - lineNumber = e.lineNumber;
673 - }
674 -
675 - var file;
676 -
677 - if (e.sourceURL) {
678 - file = e.sourceURL;
679 - }
680 - else if (e.fileName) {
681 - file = e.fileName;
682 - }
683 -
684 - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
685 -
686 - if (file && lineNumber) {
687 - message += ' in ' + file + ' (line ' + lineNumber + ')';
688 - }
689 -
690 - return message;
691 -};
692 -
693 -jasmine.util.htmlEscape = function(str) {
694 - if (!str) return str;
695 - return str.replace(/&/g, '&amp;')
696 - .replace(/</g, '&lt;')
697 - .replace(/>/g, '&gt;');
698 -};
699 -
700 -jasmine.util.argsToArray = function(args) {
701 - var arrayOfArgs = [];
702 - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
703 - return arrayOfArgs;
704 -};
705 -
706 -jasmine.util.extend = function(destination, source) {
707 - for (var property in source) destination[property] = source[property];
708 - return destination;
709 -};
710 -
711 -/**
712 - * Environment for Jasmine
713 - *
714 - * @constructor
715 - */
716 -jasmine.Env = function() {
717 - this.currentSpec = null;
718 - this.currentSuite = null;
719 - this.currentRunner_ = new jasmine.Runner(this);
720 -
721 - this.reporter = new jasmine.MultiReporter();
722 -
723 - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
724 - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
725 - this.lastUpdate = 0;
726 - this.specFilter = function() {
727 - return true;
728 - };
729 -
730 - this.nextSpecId_ = 0;
731 - this.nextSuiteId_ = 0;
732 - this.equalityTesters_ = [];
733 -
734 - // wrap matchers
735 - this.matchersClass = function() {
736 - jasmine.Matchers.apply(this, arguments);
737 - };
738 - jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
739 -
740 - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
741 -};
742 -
743 -
744 -jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
745 -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
746 -jasmine.Env.prototype.setInterval = jasmine.setInterval;
747 -jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
748 -
749 -/**
750 - * @returns an object containing jasmine version build info, if set.
751 - */
752 -jasmine.Env.prototype.version = function () {
753 - if (jasmine.version_) {
754 - return jasmine.version_;
755 - } else {
756 - throw new Error('Version not set');
757 - }
758 -};
759 -
760 -/**
761 - * @returns string containing jasmine version build info, if set.
762 - */
763 -jasmine.Env.prototype.versionString = function() {
764 - if (!jasmine.version_) {
765 - return "version unknown";
766 - }
767 -
768 - var version = this.version();
769 - var versionString = version.major + "." + version.minor + "." + version.build;
770 - if (version.release_candidate) {
771 - versionString += ".rc" + version.release_candidate;
772 - }
773 - versionString += " revision " + version.revision;
774 - return versionString;
775 -};
776 -
777 -/**
778 - * @returns a sequential integer starting at 0
779 - */
780 -jasmine.Env.prototype.nextSpecId = function () {
781 - return this.nextSpecId_++;
782 -};
783 -
784 -/**
785 - * @returns a sequential integer starting at 0
786 - */
787 -jasmine.Env.prototype.nextSuiteId = function () {
788 - return this.nextSuiteId_++;
789 -};
790 -
791 -/**
792 - * Register a reporter to receive status updates from Jasmine.
793 - * @param {jasmine.Reporter} reporter An object which will receive status updates.
794 - */
795 -jasmine.Env.prototype.addReporter = function(reporter) {
796 - this.reporter.addReporter(reporter);
797 -};
798 -
799 -jasmine.Env.prototype.execute = function() {
800 - this.currentRunner_.execute();
801 -};
802 -
803 -jasmine.Env.prototype.describe = function(description, specDefinitions) {
804 - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
805 -
806 - var parentSuite = this.currentSuite;
807 - if (parentSuite) {
808 - parentSuite.add(suite);
809 - } else {
810 - this.currentRunner_.add(suite);
811 - }
812 -
813 - this.currentSuite = suite;
814 -
815 - var declarationError = null;
816 - try {
817 - specDefinitions.call(suite);
818 - } catch(e) {
819 - declarationError = e;
820 - }
821 -
822 - if (declarationError) {
823 - this.it("encountered a declaration exception", function() {
824 - throw declarationError;
825 - });
826 - }
827 -
828 - this.currentSuite = parentSuite;
829 -
830 - return suite;
831 -};
832 -
833 -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
834 - if (this.currentSuite) {
835 - this.currentSuite.beforeEach(beforeEachFunction);
836 - } else {
837 - this.currentRunner_.beforeEach(beforeEachFunction);
838 - }
839 -};
840 -
841 -jasmine.Env.prototype.currentRunner = function () {
842 - return this.currentRunner_;
843 -};
844 -
845 -jasmine.Env.prototype.afterEach = function(afterEachFunction) {
846 - if (this.currentSuite) {
847 - this.currentSuite.afterEach(afterEachFunction);
848 - } else {
849 - this.currentRunner_.afterEach(afterEachFunction);
850 - }
851 -
852 -};
853 -
854 -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
855 - return {
856 - execute: function() {
857 - }
858 - };
859 -};
860 -
861 -jasmine.Env.prototype.it = function(description, func) {
862 - var spec = new jasmine.Spec(this, this.currentSuite, description);
863 - this.currentSuite.add(spec);
864 - this.currentSpec = spec;
865 -
866 - if (func) {
867 - spec.runs(func);
868 - }
869 -
870 - return spec;
871 -};
872 -
873 -jasmine.Env.prototype.xit = function(desc, func) {
874 - var spec = this.it(desc, func);
875 - spec.results_.skipped = true;
876 - spec.runs = function() {};
877 - return spec;
878 -};
879 -
880 -jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
881 - if (a.source != b.source)
882 - mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
883 -
884 - if (a.ignoreCase != b.ignoreCase)
885 - mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
886 -
887 - if (a.global != b.global)
888 - mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
889 -
890 - if (a.multiline != b.multiline)
891 - mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
892 -
893 - if (a.sticky != b.sticky)
894 - mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
895 -
896 - return (mismatchValues.length === 0);
897 -};
898 -
899 -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
900 - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
901 - return true;
902 - }
903 -
904 - a.__Jasmine_been_here_before__ = b;
905 - b.__Jasmine_been_here_before__ = a;
906 -
907 - var hasKey = function(obj, keyName) {
908 - return obj !== null && obj[keyName] !== jasmine.undefined;
909 - };
910 -
911 - for (var property in b) {
912 - if (!hasKey(a, property) && hasKey(b, property)) {
913 - mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
914 - }
915 - }
916 - for (property in a) {
917 - if (!hasKey(b, property) && hasKey(a, property)) {
918 - mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
919 - }
920 - }
921 - for (property in b) {
922 - if (property == '__Jasmine_been_here_before__') continue;
923 - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
924 - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
925 - }
926 - }
927 -
928 - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
929 - mismatchValues.push("arrays were not the same length");
930 - }
931 -
932 - delete a.__Jasmine_been_here_before__;
933 - delete b.__Jasmine_been_here_before__;
934 - return (mismatchKeys.length === 0 && mismatchValues.length === 0);
935 -};
936 -
937 -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
938 - mismatchKeys = mismatchKeys || [];
939 - mismatchValues = mismatchValues || [];
940 -
941 - for (var i = 0; i < this.equalityTesters_.length; i++) {
942 - var equalityTester = this.equalityTesters_[i];
943 - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
944 - if (result !== jasmine.undefined) return result;
945 - }
946 -
947 - if (a === b) return true;
948 -
949 - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
950 - return (a == jasmine.undefined && b == jasmine.undefined);
951 - }
952 -
953 - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
954 - return a === b;
955 - }
956 -
957 - if (a instanceof Date && b instanceof Date) {
958 - return a.getTime() == b.getTime();
959 - }
960 -
961 - if (a.jasmineMatches) {
962 - return a.jasmineMatches(b);
963 - }
964 -
965 - if (b.jasmineMatches) {
966 - return b.jasmineMatches(a);
967 - }
968 -
969 - if (a instanceof jasmine.Matchers.ObjectContaining) {
970 - return a.matches(b);
971 - }
972 -
973 - if (b instanceof jasmine.Matchers.ObjectContaining) {
974 - return b.matches(a);
975 - }
976 -
977 - if (jasmine.isString_(a) && jasmine.isString_(b)) {
978 - return (a == b);
979 - }
980 -
981 - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
982 - return (a == b);
983 - }
984 -
985 - if (a instanceof RegExp && b instanceof RegExp) {
986 - return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
987 - }
988 -
989 - if (typeof a === "object" && typeof b === "object") {
990 - return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
991 - }
992 -
993 - //Straight check
994 - return (a === b);
995 -};
996 -
997 -jasmine.Env.prototype.contains_ = function(haystack, needle) {
998 - if (jasmine.isArray_(haystack)) {
999 - for (var i = 0; i < haystack.length; i++) {
1000 - if (this.equals_(haystack[i], needle)) return true;
1001 - }
1002 - return false;
1003 - }
1004 - return haystack.indexOf(needle) >= 0;
1005 -};
1006 -
1007 -jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
1008 - this.equalityTesters_.push(equalityTester);
1009 -};
1010 -/** No-op base class for Jasmine reporters.
1011 - *
1012 - * @constructor
1013 - */
1014 -jasmine.Reporter = function() {
1015 -};
1016 -
1017 -//noinspection JSUnusedLocalSymbols
1018 -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
1019 -};
1020 -
1021 -//noinspection JSUnusedLocalSymbols
1022 -jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
1023 -};
1024 -
1025 -//noinspection JSUnusedLocalSymbols
1026 -jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
1027 -};
1028 -
1029 -//noinspection JSUnusedLocalSymbols
1030 -jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
1031 -};
1032 -
1033 -//noinspection JSUnusedLocalSymbols
1034 -jasmine.Reporter.prototype.reportSpecResults = function(spec) {
1035 -};
1036 -
1037 -//noinspection JSUnusedLocalSymbols
1038 -jasmine.Reporter.prototype.log = function(str) {
1039 -};
1040 -
1041 -/**
1042 - * Blocks are functions with executable code that make up a spec.
1043 - *
1044 - * @constructor
1045 - * @param {jasmine.Env} env
1046 - * @param {Function} func
1047 - * @param {jasmine.Spec} spec
1048 - */
1049 -jasmine.Block = function(env, func, spec) {
1050 - this.env = env;
1051 - this.func = func;
1052 - this.spec = spec;
1053 -};
1054 -
1055 -jasmine.Block.prototype.execute = function(onComplete) {
1056 - if (!jasmine.CATCH_EXCEPTIONS) {
1057 - this.func.apply(this.spec);
1058 - }
1059 - else {
1060 - try {
1061 - this.func.apply(this.spec);
1062 - } catch (e) {
1063 - this.spec.fail(e);
1064 - }
1065 - }
1066 - onComplete();
1067 -};
1068 -/** JavaScript API reporter.
1069 - *
1070 - * @constructor
1071 - */
1072 -jasmine.JsApiReporter = function() {
1073 - this.started = false;
1074 - this.finished = false;
1075 - this.suites_ = [];
1076 - this.results_ = {};
1077 -};
1078 -
1079 -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
1080 - this.started = true;
1081 - var suites = runner.topLevelSuites();
1082 - for (var i = 0; i < suites.length; i++) {
1083 - var suite = suites[i];
1084 - this.suites_.push(this.summarize_(suite));
1085 - }
1086 -};
1087 -
1088 -jasmine.JsApiReporter.prototype.suites = function() {
1089 - return this.suites_;
1090 -};
1091 -
1092 -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
1093 - var isSuite = suiteOrSpec instanceof jasmine.Suite;
1094 - var summary = {
1095 - id: suiteOrSpec.id,
1096 - name: suiteOrSpec.description,
1097 - type: isSuite ? 'suite' : 'spec',
1098 - children: []
1099 - };
1100 -
1101 - if (isSuite) {
1102 - var children = suiteOrSpec.children();
1103 - for (var i = 0; i < children.length; i++) {
1104 - summary.children.push(this.summarize_(children[i]));
1105 - }
1106 - }
1107 - return summary;
1108 -};
1109 -
1110 -jasmine.JsApiReporter.prototype.results = function() {
1111 - return this.results_;
1112 -};
1113 -
1114 -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
1115 - return this.results_[specId];
1116 -};
1117 -
1118 -//noinspection JSUnusedLocalSymbols
1119 -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
1120 - this.finished = true;
1121 -};
1122 -
1123 -//noinspection JSUnusedLocalSymbols
1124 -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
1125 -};
1126 -
1127 -//noinspection JSUnusedLocalSymbols
1128 -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
1129 - this.results_[spec.id] = {
1130 - messages: spec.results().getItems(),
1131 - result: spec.results().failedCount > 0 ? "failed" : "passed"
1132 - };
1133 -};
1134 -
1135 -//noinspection JSUnusedLocalSymbols
1136 -jasmine.JsApiReporter.prototype.log = function(str) {
1137 -};
1138 -
1139 -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
1140 - var results = {};
1141 - for (var i = 0; i < specIds.length; i++) {
1142 - var specId = specIds[i];
1143 - results[specId] = this.summarizeResult_(this.results_[specId]);
1144 - }
1145 - return results;
1146 -};
1147 -
1148 -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
1149 - var summaryMessages = [];
1150 - var messagesLength = result.messages.length;
1151 - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
1152 - var resultMessage = result.messages[messageIndex];
1153 - summaryMessages.push({
1154 - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
1155 - passed: resultMessage.passed ? resultMessage.passed() : true,
1156 - type: resultMessage.type,
1157 - message: resultMessage.message,
1158 - trace: {
1159 - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
1160 - }
1161 - });
1162 - }
1163 -
1164 - return {
1165 - result : result.result,
1166 - messages : summaryMessages
1167 - };
1168 -};
1169 -
1170 -/**
1171 - * @constructor
1172 - * @param {jasmine.Env} env
1173 - * @param actual
1174 - * @param {jasmine.Spec} spec
1175 - */
1176 -jasmine.Matchers = function(env, actual, spec, opt_isNot) {
1177 - this.env = env;
1178 - this.actual = actual;
1179 - this.spec = spec;
1180 - this.isNot = opt_isNot || false;
1181 - this.reportWasCalled_ = false;
1182 -};
1183 -
1184 -// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
1185 -jasmine.Matchers.pp = function(str) {
1186 - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
1187 -};
1188 -
1189 -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
1190 -jasmine.Matchers.prototype.report = function(result, failing_message, details) {
1191 - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
1192 -};
1193 -
1194 -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
1195 - for (var methodName in prototype) {
1196 - if (methodName == 'report') continue;
1197 - var orig = prototype[methodName];
1198 - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
1199 - }
1200 -};
1201 -
1202 -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
1203 - return function() {
1204 - var matcherArgs = jasmine.util.argsToArray(arguments);
1205 - var result = matcherFunction.apply(this, arguments);
1206 -
1207 - if (this.isNot) {
1208 - result = !result;
1209 - }
1210 -
1211 - if (this.reportWasCalled_) return result;
1212 -
1213 - var message;
1214 - if (!result) {
1215 - if (this.message) {
1216 - message = this.message.apply(this, arguments);
1217 - if (jasmine.isArray_(message)) {
1218 - message = message[this.isNot ? 1 : 0];
1219 - }
1220 - } else {
1221 - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1222 - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
1223 - if (matcherArgs.length > 0) {
1224 - for (var i = 0; i < matcherArgs.length; i++) {
1225 - if (i > 0) message += ",";
1226 - message += " " + jasmine.pp(matcherArgs[i]);
1227 - }
1228 - }
1229 - message += ".";
1230 - }
1231 - }
1232 - var expectationResult = new jasmine.ExpectationResult({
1233 - matcherName: matcherName,
1234 - passed: result,
1235 - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
1236 - actual: this.actual,
1237 - message: message
1238 - });
1239 - this.spec.addMatcherResult(expectationResult);
1240 - return jasmine.undefined;
1241 - };
1242 -};
1243 -
1244 -
1245 -
1246 -
1247 -/**
1248 - * toBe: compares the actual to the expected using ===
1249 - * @param expected
1250 - */
1251 -jasmine.Matchers.prototype.toBe = function(expected) {
1252 - return this.actual === expected;
1253 -};
1254 -
1255 -/**
1256 - * toNotBe: compares the actual to the expected using !==
1257 - * @param expected
1258 - * @deprecated as of 1.0. Use not.toBe() instead.
1259 - */
1260 -jasmine.Matchers.prototype.toNotBe = function(expected) {
1261 - return this.actual !== expected;
1262 -};
1263 -
1264 -/**
1265 - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1266 - *
1267 - * @param expected
1268 - */
1269 -jasmine.Matchers.prototype.toEqual = function(expected) {
1270 - return this.env.equals_(this.actual, expected);
1271 -};
1272 -
1273 -/**
1274 - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1275 - * @param expected
1276 - * @deprecated as of 1.0. Use not.toEqual() instead.
1277 - */
1278 -jasmine.Matchers.prototype.toNotEqual = function(expected) {
1279 - return !this.env.equals_(this.actual, expected);
1280 -};
1281 -
1282 -/**
1283 - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1284 - * a pattern or a String.
1285 - *
1286 - * @param expected
1287 - */
1288 -jasmine.Matchers.prototype.toMatch = function(expected) {
1289 - return new RegExp(expected).test(this.actual);
1290 -};
1291 -
1292 -/**
1293 - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1294 - * @param expected
1295 - * @deprecated as of 1.0. Use not.toMatch() instead.
1296 - */
1297 -jasmine.Matchers.prototype.toNotMatch = function(expected) {
1298 - return !(new RegExp(expected).test(this.actual));
1299 -};
1300 -
1301 -/**
1302 - * Matcher that compares the actual to jasmine.undefined.
1303 - */
1304 -jasmine.Matchers.prototype.toBeDefined = function() {
1305 - return (this.actual !== jasmine.undefined);
1306 -};
1307 -
1308 -/**
1309 - * Matcher that compares the actual to jasmine.undefined.
1310 - */
1311 -jasmine.Matchers.prototype.toBeUndefined = function() {
1312 - return (this.actual === jasmine.undefined);
1313 -};
1314 -
1315 -/**
1316 - * Matcher that compares the actual to null.
1317 - */
1318 -jasmine.Matchers.prototype.toBeNull = function() {
1319 - return (this.actual === null);
1320 -};
1321 -
1322 -/**
1323 - * Matcher that compares the actual to NaN.
1324 - */
1325 -jasmine.Matchers.prototype.toBeNaN = function() {
1326 - this.message = function() {
1327 - return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
1328 - };
1329 -
1330 - return (this.actual !== this.actual);
1331 -};
1332 -
1333 -/**
1334 - * Matcher that boolean not-nots the actual.
1335 - */
1336 -jasmine.Matchers.prototype.toBeTruthy = function() {
1337 - return !!this.actual;
1338 -};
1339 -
1340 -
1341 -/**
1342 - * Matcher that boolean nots the actual.
1343 - */
1344 -jasmine.Matchers.prototype.toBeFalsy = function() {
1345 - return !this.actual;
1346 -};
1347 -
1348 -
1349 -/**
1350 - * Matcher that checks to see if the actual, a Jasmine spy, was called.
1351 - */
1352 -jasmine.Matchers.prototype.toHaveBeenCalled = function() {
1353 - if (arguments.length > 0) {
1354 - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
1355 - }
1356 -
1357 - if (!jasmine.isSpy(this.actual)) {
1358 - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1359 - }
1360 -
1361 - this.message = function() {
1362 - return [
1363 - "Expected spy " + this.actual.identity + " to have been called.",
1364 - "Expected spy " + this.actual.identity + " not to have been called."
1365 - ];
1366 - };
1367 -
1368 - return this.actual.wasCalled;
1369 -};
1370 -
1371 -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
1372 -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
1373 -
1374 -/**
1375 - * Matcher that checks to see if the actual, a Jasmine spy, was not called.
1376 - *
1377 - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
1378 - */
1379 -jasmine.Matchers.prototype.wasNotCalled = function() {
1380 - if (arguments.length > 0) {
1381 - throw new Error('wasNotCalled does not take arguments');
1382 - }
1383 -
1384 - if (!jasmine.isSpy(this.actual)) {
1385 - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1386 - }
1387 -
1388 - this.message = function() {
1389 - return [
1390 - "Expected spy " + this.actual.identity + " to not have been called.",
1391 - "Expected spy " + this.actual.identity + " to have been called."
1392 - ];
1393 - };
1394 -
1395 - return !this.actual.wasCalled;
1396 -};
1397 -
1398 -/**
1399 - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
1400 - *
1401 - * @example
1402 - *
1403 - */
1404 -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
1405 - var expectedArgs = jasmine.util.argsToArray(arguments);
1406 - if (!jasmine.isSpy(this.actual)) {
1407 - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1408 - }
1409 - this.message = function() {
1410 - var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
1411 - var positiveMessage = "";
1412 - if (this.actual.callCount === 0) {
1413 - positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
1414 - } else {
1415 - positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
1416 - }
1417 - return [positiveMessage, invertedMessage];
1418 - };
1419 -
1420 - return this.env.contains_(this.actual.argsForCall, expectedArgs);
1421 -};
1422 -
1423 -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
1424 -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
1425 -
1426 -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
1427 -jasmine.Matchers.prototype.wasNotCalledWith = function() {
1428 - var expectedArgs = jasmine.util.argsToArray(arguments);
1429 - if (!jasmine.isSpy(this.actual)) {
1430 - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1431 - }
1432 -
1433 - this.message = function() {
1434 - return [
1435 - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
1436 - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
1437 - ];
1438 - };
1439 -
1440 - return !this.env.contains_(this.actual.argsForCall, expectedArgs);
1441 -};
1442 -
1443 -/**
1444 - * Matcher that checks that the expected item is an element in the actual Array.
1445 - *
1446 - * @param {Object} expected
1447 - */
1448 -jasmine.Matchers.prototype.toContain = function(expected) {
1449 - return this.env.contains_(this.actual, expected);
1450 -};
1451 -
1452 -/**
1453 - * Matcher that checks that the expected item is NOT an element in the actual Array.
1454 - *
1455 - * @param {Object} expected
1456 - * @deprecated as of 1.0. Use not.toContain() instead.
1457 - */
1458 -jasmine.Matchers.prototype.toNotContain = function(expected) {
1459 - return !this.env.contains_(this.actual, expected);
1460 -};
1461 -
1462 -jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1463 - return this.actual < expected;
1464 -};
1465 -
1466 -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1467 - return this.actual > expected;
1468 -};
1469 -
1470 -/**
1471 - * Matcher that checks that the expected item is equal to the actual item
1472 - * up to a given level of decimal precision (default 2).
1473 - *
1474 - * @param {Number} expected
1475 - * @param {Number} precision, as number of decimal places
1476 - */
1477 -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
1478 - if (!(precision === 0)) {
1479 - precision = precision || 2;
1480 - }
1481 - return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
1482 -};
1483 -
1484 -/**
1485 - * Matcher that checks that the expected exception was thrown by the actual.
1486 - *
1487 - * @param {String} [expected]
1488 - */
1489 -jasmine.Matchers.prototype.toThrow = function(expected) {
1490 - var result = false;
1491 - var exception;
1492 - if (typeof this.actual != 'function') {
1493 - throw new Error('Actual is not a function');
1494 - }
1495 - try {
1496 - this.actual();
1497 - } catch (e) {
1498 - exception = e;
1499 - }
1500 - if (exception) {
1501 - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
1502 - }
1503 -
1504 - var not = this.isNot ? "not " : "";
1505 -
1506 - this.message = function() {
1507 - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
1508 - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
1509 - } else {
1510 - return "Expected function to throw an exception.";
1511 - }
1512 - };
1513 -
1514 - return result;
1515 -};
1516 -
1517 -jasmine.Matchers.Any = function(expectedClass) {
1518 - this.expectedClass = expectedClass;
1519 -};
1520 -
1521 -jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
1522 - if (this.expectedClass == String) {
1523 - return typeof other == 'string' || other instanceof String;
1524 - }
1525 -
1526 - if (this.expectedClass == Number) {
1527 - return typeof other == 'number' || other instanceof Number;
1528 - }
1529 -
1530 - if (this.expectedClass == Function) {
1531 - return typeof other == 'function' || other instanceof Function;
1532 - }
1533 -
1534 - if (this.expectedClass == Object) {
1535 - return typeof other == 'object';
1536 - }
1537 -
1538 - return other instanceof this.expectedClass;
1539 -};
1540 -
1541 -jasmine.Matchers.Any.prototype.jasmineToString = function() {
1542 - return '<jasmine.any(' + this.expectedClass + ')>';
1543 -};
1544 -
1545 -jasmine.Matchers.ObjectContaining = function (sample) {
1546 - this.sample = sample;
1547 -};
1548 -
1549 -jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1550 - mismatchKeys = mismatchKeys || [];
1551 - mismatchValues = mismatchValues || [];
1552 -
1553 - var env = jasmine.getEnv();
1554 -
1555 - var hasKey = function(obj, keyName) {
1556 - return obj != null && obj[keyName] !== jasmine.undefined;
1557 - };
1558 -
1559 - for (var property in this.sample) {
1560 - if (!hasKey(other, property) && hasKey(this.sample, property)) {
1561 - mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1562 - }
1563 - else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
1564 - mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
1565 - }
1566 - }
1567 -
1568 - return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1569 -};
1570 -
1571 -jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
1572 - return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
1573 -};
1574 -// Mock setTimeout, clearTimeout
1575 -// Contributed by Pivotal Computer Systems, www.pivotalsf.com
1576 -
1577 -jasmine.FakeTimer = function() {
1578 - this.reset();
1579 -
1580 - var self = this;
1581 - self.setTimeout = function(funcToCall, millis) {
1582 - self.timeoutsMade++;
1583 - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1584 - return self.timeoutsMade;
1585 - };
1586 -
1587 - self.setInterval = function(funcToCall, millis) {
1588 - self.timeoutsMade++;
1589 - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1590 - return self.timeoutsMade;
1591 - };
1592 -
1593 - self.clearTimeout = function(timeoutKey) {
1594 - self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1595 - };
1596 -
1597 - self.clearInterval = function(timeoutKey) {
1598 - self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1599 - };
1600 -
1601 -};
1602 -
1603 -jasmine.FakeTimer.prototype.reset = function() {
1604 - this.timeoutsMade = 0;
1605 - this.scheduledFunctions = {};
1606 - this.nowMillis = 0;
1607 -};
1608 -
1609 -jasmine.FakeTimer.prototype.tick = function(millis) {
1610 - var oldMillis = this.nowMillis;
1611 - var newMillis = oldMillis + millis;
1612 - this.runFunctionsWithinRange(oldMillis, newMillis);
1613 - this.nowMillis = newMillis;
1614 -};
1615 -
1616 -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
1617 - var scheduledFunc;
1618 - var funcsToRun = [];
1619 - for (var timeoutKey in this.scheduledFunctions) {
1620 - scheduledFunc = this.scheduledFunctions[timeoutKey];
1621 - if (scheduledFunc != jasmine.undefined &&
1622 - scheduledFunc.runAtMillis >= oldMillis &&
1623 - scheduledFunc.runAtMillis <= nowMillis) {
1624 - funcsToRun.push(scheduledFunc);
1625 - this.scheduledFunctions[timeoutKey] = jasmine.undefined;
1626 - }
1627 - }
1628 -
1629 - if (funcsToRun.length > 0) {
1630 - funcsToRun.sort(function(a, b) {
1631 - return a.runAtMillis - b.runAtMillis;
1632 - });
1633 - for (var i = 0; i < funcsToRun.length; ++i) {
1634 - try {
1635 - var funcToRun = funcsToRun[i];
1636 - this.nowMillis = funcToRun.runAtMillis;
1637 - funcToRun.funcToCall();
1638 - if (funcToRun.recurring) {
1639 - this.scheduleFunction(funcToRun.timeoutKey,
1640 - funcToRun.funcToCall,
1641 - funcToRun.millis,
1642 - true);
1643 - }
1644 - } catch(e) {
1645 - }
1646 - }
1647 - this.runFunctionsWithinRange(oldMillis, nowMillis);
1648 - }
1649 -};
1650 -
1651 -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
1652 - this.scheduledFunctions[timeoutKey] = {
1653 - runAtMillis: this.nowMillis + millis,
1654 - funcToCall: funcToCall,
1655 - recurring: recurring,
1656 - timeoutKey: timeoutKey,
1657 - millis: millis
1658 - };
1659 -};
1660 -
1661 -/**
1662 - * @namespace
1663 - */
1664 -jasmine.Clock = {
1665 - defaultFakeTimer: new jasmine.FakeTimer(),
1666 -
1667 - reset: function() {
1668 - jasmine.Clock.assertInstalled();
1669 - jasmine.Clock.defaultFakeTimer.reset();
1670 - },
1671 -
1672 - tick: function(millis) {
1673 - jasmine.Clock.assertInstalled();
1674 - jasmine.Clock.defaultFakeTimer.tick(millis);
1675 - },
1676 -
1677 - runFunctionsWithinRange: function(oldMillis, nowMillis) {
1678 - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
1679 - },
1680 -
1681 - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
1682 - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
1683 - },
1684 -
1685 - useMock: function() {
1686 - if (!jasmine.Clock.isInstalled()) {
1687 - var spec = jasmine.getEnv().currentSpec;
1688 - spec.after(jasmine.Clock.uninstallMock);
1689 -
1690 - jasmine.Clock.installMock();
1691 - }
1692 - },
1693 -
1694 - installMock: function() {
1695 - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
1696 - },
1697 -
1698 - uninstallMock: function() {
1699 - jasmine.Clock.assertInstalled();
1700 - jasmine.Clock.installed = jasmine.Clock.real;
1701 - },
1702 -
1703 - real: {
1704 - setTimeout: jasmine.getGlobal().setTimeout,
1705 - clearTimeout: jasmine.getGlobal().clearTimeout,
1706 - setInterval: jasmine.getGlobal().setInterval,
1707 - clearInterval: jasmine.getGlobal().clearInterval
1708 - },
1709 -
1710 - assertInstalled: function() {
1711 - if (!jasmine.Clock.isInstalled()) {
1712 - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
1713 - }
1714 - },
1715 -
1716 - isInstalled: function() {
1717 - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
1718 - },
1719 -
1720 - installed: null
1721 -};
1722 -jasmine.Clock.installed = jasmine.Clock.real;
1723 -
1724 -//else for IE support
1725 -jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
1726 - if (jasmine.Clock.installed.setTimeout.apply) {
1727 - return jasmine.Clock.installed.setTimeout.apply(this, arguments);
1728 - } else {
1729 - return jasmine.Clock.installed.setTimeout(funcToCall, millis);
1730 - }
1731 -};
1732 -
1733 -jasmine.getGlobal().setInterval = function(funcToCall, millis) {
1734 - if (jasmine.Clock.installed.setInterval.apply) {
1735 - return jasmine.Clock.installed.setInterval.apply(this, arguments);
1736 - } else {
1737 - return jasmine.Clock.installed.setInterval(funcToCall, millis);
1738 - }
1739 -};
1740 -
1741 -jasmine.getGlobal().clearTimeout = function(timeoutKey) {
1742 - if (jasmine.Clock.installed.clearTimeout.apply) {
1743 - return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
1744 - } else {
1745 - return jasmine.Clock.installed.clearTimeout(timeoutKey);
1746 - }
1747 -};
1748 -
1749 -jasmine.getGlobal().clearInterval = function(timeoutKey) {
1750 - if (jasmine.Clock.installed.clearTimeout.apply) {
1751 - return jasmine.Clock.installed.clearInterval.apply(this, arguments);
1752 - } else {
1753 - return jasmine.Clock.installed.clearInterval(timeoutKey);
1754 - }
1755 -};
1756 -
1757 -/**
1758 - * @constructor
1759 - */
1760 -jasmine.MultiReporter = function() {
1761 - this.subReporters_ = [];
1762 -};
1763 -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1764 -
1765 -jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1766 - this.subReporters_.push(reporter);
1767 -};
1768 -
1769 -(function() {
1770 - var functionNames = [
1771 - "reportRunnerStarting",
1772 - "reportRunnerResults",
1773 - "reportSuiteResults",
1774 - "reportSpecStarting",
1775 - "reportSpecResults",
1776 - "log"
1777 - ];
1778 - for (var i = 0; i < functionNames.length; i++) {
1779 - var functionName = functionNames[i];
1780 - jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1781 - return function() {
1782 - for (var j = 0; j < this.subReporters_.length; j++) {
1783 - var subReporter = this.subReporters_[j];
1784 - if (subReporter[functionName]) {
1785 - subReporter[functionName].apply(subReporter, arguments);
1786 - }
1787 - }
1788 - };
1789 - })(functionName);
1790 - }
1791 -})();
1792 -/**
1793 - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1794 - *
1795 - * @constructor
1796 - */
1797 -jasmine.NestedResults = function() {
1798 - /**
1799 - * The total count of results
1800 - */
1801 - this.totalCount = 0;
1802 - /**
1803 - * Number of passed results
1804 - */
1805 - this.passedCount = 0;
1806 - /**
1807 - * Number of failed results
1808 - */
1809 - this.failedCount = 0;
1810 - /**
1811 - * Was this suite/spec skipped?
1812 - */
1813 - this.skipped = false;
1814 - /**
1815 - * @ignore
1816 - */
1817 - this.items_ = [];
1818 -};
1819 -
1820 -/**
1821 - * Roll up the result counts.
1822 - *
1823 - * @param result
1824 - */
1825 -jasmine.NestedResults.prototype.rollupCounts = function(result) {
1826 - this.totalCount += result.totalCount;
1827 - this.passedCount += result.passedCount;
1828 - this.failedCount += result.failedCount;
1829 -};
1830 -
1831 -/**
1832 - * Adds a log message.
1833 - * @param values Array of message parts which will be concatenated later.
1834 - */
1835 -jasmine.NestedResults.prototype.log = function(values) {
1836 - this.items_.push(new jasmine.MessageResult(values));
1837 -};
1838 -
1839 -/**
1840 - * Getter for the results: message & results.
1841 - */
1842 -jasmine.NestedResults.prototype.getItems = function() {
1843 - return this.items_;
1844 -};
1845 -
1846 -/**
1847 - * Adds a result, tracking counts (total, passed, & failed)
1848 - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1849 - */
1850 -jasmine.NestedResults.prototype.addResult = function(result) {
1851 - if (result.type != 'log') {
1852 - if (result.items_) {
1853 - this.rollupCounts(result);
1854 - } else {
1855 - this.totalCount++;
1856 - if (result.passed()) {
1857 - this.passedCount++;
1858 - } else {
1859 - this.failedCount++;
1860 - }
1861 - }
1862 - }
1863 - this.items_.push(result);
1864 -};
1865 -
1866 -/**
1867 - * @returns {Boolean} True if <b>everything</b> below passed
1868 - */
1869 -jasmine.NestedResults.prototype.passed = function() {
1870 - return this.passedCount === this.totalCount;
1871 -};
1872 -/**
1873 - * Base class for pretty printing for expectation results.
1874 - */
1875 -jasmine.PrettyPrinter = function() {
1876 - this.ppNestLevel_ = 0;
1877 -};
1878 -
1879 -/**
1880 - * Formats a value in a nice, human-readable string.
1881 - *
1882 - * @param value
1883 - */
1884 -jasmine.PrettyPrinter.prototype.format = function(value) {
1885 - this.ppNestLevel_++;
1886 - try {
1887 - if (value === jasmine.undefined) {
1888 - this.emitScalar('undefined');
1889 - } else if (value === null) {
1890 - this.emitScalar('null');
1891 - } else if (value === jasmine.getGlobal()) {
1892 - this.emitScalar('<global>');
1893 - } else if (value.jasmineToString) {
1894 - this.emitScalar(value.jasmineToString());
1895 - } else if (typeof value === 'string') {
1896 - this.emitString(value);
1897 - } else if (jasmine.isSpy(value)) {
1898 - this.emitScalar("spy on " + value.identity);
1899 - } else if (value instanceof RegExp) {
1900 - this.emitScalar(value.toString());
1901 - } else if (typeof value === 'function') {
1902 - this.emitScalar('Function');
1903 - } else if (typeof value.nodeType === 'number') {
1904 - this.emitScalar('HTMLNode');
1905 - } else if (value instanceof Date) {
1906 - this.emitScalar('Date(' + value + ')');
1907 - } else if (value.__Jasmine_been_here_before__) {
1908 - this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1909 - } else if (jasmine.isArray_(value) || typeof value == 'object') {
1910 - value.__Jasmine_been_here_before__ = true;
1911 - if (jasmine.isArray_(value)) {
1912 - this.emitArray(value);
1913 - } else {
1914 - this.emitObject(value);
1915 - }
1916 - delete value.__Jasmine_been_here_before__;
1917 - } else {
1918 - this.emitScalar(value.toString());
1919 - }
1920 - } finally {
1921 - this.ppNestLevel_--;
1922 - }
1923 -};
1924 -
1925 -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1926 - for (var property in obj) {
1927 - if (!obj.hasOwnProperty(property)) continue;
1928 - if (property == '__Jasmine_been_here_before__') continue;
1929 - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
1930 - obj.__lookupGetter__(property) !== null) : false);
1931 - }
1932 -};
1933 -
1934 -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1935 -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1936 -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1937 -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1938 -
1939 -jasmine.StringPrettyPrinter = function() {
1940 - jasmine.PrettyPrinter.call(this);
1941 -
1942 - this.string = '';
1943 -};
1944 -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1945 -
1946 -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1947 - this.append(value);
1948 -};
1949 -
1950 -jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1951 - this.append("'" + value + "'");
1952 -};
1953 -
1954 -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1955 - if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1956 - this.append("Array");
1957 - return;
1958 - }
1959 -
1960 - this.append('[ ');
1961 - for (var i = 0; i < array.length; i++) {
1962 - if (i > 0) {
1963 - this.append(', ');
1964 - }
1965 - this.format(array[i]);
1966 - }
1967 - this.append(' ]');
1968 -};
1969 -
1970 -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1971 - if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1972 - this.append("Object");
1973 - return;
1974 - }
1975 -
1976 - var self = this;
1977 - this.append('{ ');
1978 - var first = true;
1979 -
1980 - this.iterateObject(obj, function(property, isGetter) {
1981 - if (first) {
1982 - first = false;
1983 - } else {
1984 - self.append(', ');
1985 - }
1986 -
1987 - self.append(property);
1988 - self.append(' : ');
1989 - if (isGetter) {
1990 - self.append('<getter>');
1991 - } else {
1992 - self.format(obj[property]);
1993 - }
1994 - });
1995 -
1996 - this.append(' }');
1997 -};
1998 -
1999 -jasmine.StringPrettyPrinter.prototype.append = function(value) {
2000 - this.string += value;
2001 -};
2002 -jasmine.Queue = function(env) {
2003 - this.env = env;
2004 -
2005 - // parallel to blocks. each true value in this array means the block will
2006 - // get executed even if we abort
2007 - this.ensured = [];
2008 - this.blocks = [];
2009 - this.running = false;
2010 - this.index = 0;
2011 - this.offset = 0;
2012 - this.abort = false;
2013 -};
2014 -
2015 -jasmine.Queue.prototype.addBefore = function(block, ensure) {
2016 - if (ensure === jasmine.undefined) {
2017 - ensure = false;
2018 - }
2019 -
2020 - this.blocks.unshift(block);
2021 - this.ensured.unshift(ensure);
2022 -};
2023 -
2024 -jasmine.Queue.prototype.add = function(block, ensure) {
2025 - if (ensure === jasmine.undefined) {
2026 - ensure = false;
2027 - }
2028 -
2029 - this.blocks.push(block);
2030 - this.ensured.push(ensure);
2031 -};
2032 -
2033 -jasmine.Queue.prototype.insertNext = function(block, ensure) {
2034 - if (ensure === jasmine.undefined) {
2035 - ensure = false;
2036 - }
2037 -
2038 - this.ensured.splice((this.index + this.offset + 1), 0, ensure);
2039 - this.blocks.splice((this.index + this.offset + 1), 0, block);
2040 - this.offset++;
2041 -};
2042 -
2043 -jasmine.Queue.prototype.start = function(onComplete) {
2044 - this.running = true;
2045 - this.onComplete = onComplete;
2046 - this.next_();
2047 -};
2048 -
2049 -jasmine.Queue.prototype.isRunning = function() {
2050 - return this.running;
2051 -};
2052 -
2053 -jasmine.Queue.LOOP_DONT_RECURSE = true;
2054 -
2055 -jasmine.Queue.prototype.next_ = function() {
2056 - var self = this;
2057 - var goAgain = true;
2058 -
2059 - while (goAgain) {
2060 - goAgain = false;
2061 -
2062 - if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
2063 - var calledSynchronously = true;
2064 - var completedSynchronously = false;
2065 -
2066 - var onComplete = function () {
2067 - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
2068 - completedSynchronously = true;
2069 - return;
2070 - }
2071 -
2072 - if (self.blocks[self.index].abort) {
2073 - self.abort = true;
2074 - }
2075 -
2076 - self.offset = 0;
2077 - self.index++;
2078 -
2079 - var now = new Date().getTime();
2080 - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
2081 - self.env.lastUpdate = now;
2082 - self.env.setTimeout(function() {
2083 - self.next_();
2084 - }, 0);
2085 - } else {
2086 - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
2087 - goAgain = true;
2088 - } else {
2089 - self.next_();
2090 - }
2091 - }
2092 - };
2093 - self.blocks[self.index].execute(onComplete);
2094 -
2095 - calledSynchronously = false;
2096 - if (completedSynchronously) {
2097 - onComplete();
2098 - }
2099 -
2100 - } else {
2101 - self.running = false;
2102 - if (self.onComplete) {
2103 - self.onComplete();
2104 - }
2105 - }
2106 - }
2107 -};
2108 -
2109 -jasmine.Queue.prototype.results = function() {
2110 - var results = new jasmine.NestedResults();
2111 - for (var i = 0; i < this.blocks.length; i++) {
2112 - if (this.blocks[i].results) {
2113 - results.addResult(this.blocks[i].results());
2114 - }
2115 - }
2116 - return results;
2117 -};
2118 -
2119 -
2120 -/**
2121 - * Runner
2122 - *
2123 - * @constructor
2124 - * @param {jasmine.Env} env
2125 - */
2126 -jasmine.Runner = function(env) {
2127 - var self = this;
2128 - self.env = env;
2129 - self.queue = new jasmine.Queue(env);
2130 - self.before_ = [];
2131 - self.after_ = [];
2132 - self.suites_ = [];
2133 -};
2134 -
2135 -jasmine.Runner.prototype.execute = function() {
2136 - var self = this;
2137 - if (self.env.reporter.reportRunnerStarting) {
2138 - self.env.reporter.reportRunnerStarting(this);
2139 - }
2140 - self.queue.start(function () {
2141 - self.finishCallback();
2142 - });
2143 -};
2144 -
2145 -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
2146 - beforeEachFunction.typeName = 'beforeEach';
2147 - this.before_.splice(0,0,beforeEachFunction);
2148 -};
2149 -
2150 -jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
2151 - afterEachFunction.typeName = 'afterEach';
2152 - this.after_.splice(0,0,afterEachFunction);
2153 -};
2154 -
2155 -
2156 -jasmine.Runner.prototype.finishCallback = function() {
2157 - this.env.reporter.reportRunnerResults(this);
2158 -};
2159 -
2160 -jasmine.Runner.prototype.addSuite = function(suite) {
2161 - this.suites_.push(suite);
2162 -};
2163 -
2164 -jasmine.Runner.prototype.add = function(block) {
2165 - if (block instanceof jasmine.Suite) {
2166 - this.addSuite(block);
2167 - }
2168 - this.queue.add(block);
2169 -};
2170 -
2171 -jasmine.Runner.prototype.specs = function () {
2172 - var suites = this.suites();
2173 - var specs = [];
2174 - for (var i = 0; i < suites.length; i++) {
2175 - specs = specs.concat(suites[i].specs());
2176 - }
2177 - return specs;
2178 -};
2179 -
2180 -jasmine.Runner.prototype.suites = function() {
2181 - return this.suites_;
2182 -};
2183 -
2184 -jasmine.Runner.prototype.topLevelSuites = function() {
2185 - var topLevelSuites = [];
2186 - for (var i = 0; i < this.suites_.length; i++) {
2187 - if (!this.suites_[i].parentSuite) {
2188 - topLevelSuites.push(this.suites_[i]);
2189 - }
2190 - }
2191 - return topLevelSuites;
2192 -};
2193 -
2194 -jasmine.Runner.prototype.results = function() {
2195 - return this.queue.results();
2196 -};
2197 -/**
2198 - * Internal representation of a Jasmine specification, or test.
2199 - *
2200 - * @constructor
2201 - * @param {jasmine.Env} env
2202 - * @param {jasmine.Suite} suite
2203 - * @param {String} description
2204 - */
2205 -jasmine.Spec = function(env, suite, description) {
2206 - if (!env) {
2207 - throw new Error('jasmine.Env() required');
2208 - }
2209 - if (!suite) {
2210 - throw new Error('jasmine.Suite() required');
2211 - }
2212 - var spec = this;
2213 - spec.id = env.nextSpecId ? env.nextSpecId() : null;
2214 - spec.env = env;
2215 - spec.suite = suite;
2216 - spec.description = description;
2217 - spec.queue = new jasmine.Queue(env);
2218 -
2219 - spec.afterCallbacks = [];
2220 - spec.spies_ = [];
2221 -
2222 - spec.results_ = new jasmine.NestedResults();
2223 - spec.results_.description = description;
2224 - spec.matchersClass = null;
2225 -};
2226 -
2227 -jasmine.Spec.prototype.getFullName = function() {
2228 - return this.suite.getFullName() + ' ' + this.description + '.';
2229 -};
2230 -
2231 -
2232 -jasmine.Spec.prototype.results = function() {
2233 - return this.results_;
2234 -};
2235 -
2236 -/**
2237 - * All parameters are pretty-printed and concatenated together, then written to the spec's output.
2238 - *
2239 - * Be careful not to leave calls to <code>jasmine.log</code> in production code.
2240 - */
2241 -jasmine.Spec.prototype.log = function() {
2242 - return this.results_.log(arguments);
2243 -};
2244 -
2245 -jasmine.Spec.prototype.runs = function (func) {
2246 - var block = new jasmine.Block(this.env, func, this);
2247 - this.addToQueue(block);
2248 - return this;
2249 -};
2250 -
2251 -jasmine.Spec.prototype.addToQueue = function (block) {
2252 - if (this.queue.isRunning()) {
2253 - this.queue.insertNext(block);
2254 - } else {
2255 - this.queue.add(block);
2256 - }
2257 -};
2258 -
2259 -/**
2260 - * @param {jasmine.ExpectationResult} result
2261 - */
2262 -jasmine.Spec.prototype.addMatcherResult = function(result) {
2263 - this.results_.addResult(result);
2264 -};
2265 -
2266 -jasmine.Spec.prototype.expect = function(actual) {
2267 - var positive = new (this.getMatchersClass_())(this.env, actual, this);
2268 - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
2269 - return positive;
2270 -};
2271 -
2272 -/**
2273 - * Waits a fixed time period before moving to the next block.
2274 - *
2275 - * @deprecated Use waitsFor() instead
2276 - * @param {Number} timeout milliseconds to wait
2277 - */
2278 -jasmine.Spec.prototype.waits = function(timeout) {
2279 - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
2280 - this.addToQueue(waitsFunc);
2281 - return this;
2282 -};
2283 -
2284 -/**
2285 - * Waits for the latchFunction to return true before proceeding to the next block.
2286 - *
2287 - * @param {Function} latchFunction
2288 - * @param {String} optional_timeoutMessage
2289 - * @param {Number} optional_timeout
2290 - */
2291 -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
2292 - var latchFunction_ = null;
2293 - var optional_timeoutMessage_ = null;
2294 - var optional_timeout_ = null;
2295 -
2296 - for (var i = 0; i < arguments.length; i++) {
2297 - var arg = arguments[i];
2298 - switch (typeof arg) {
2299 - case 'function':
2300 - latchFunction_ = arg;
2301 - break;
2302 - case 'string':
2303 - optional_timeoutMessage_ = arg;
2304 - break;
2305 - case 'number':
2306 - optional_timeout_ = arg;
2307 - break;
2308 - }
2309 - }
2310 -
2311 - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
2312 - this.addToQueue(waitsForFunc);
2313 - return this;
2314 -};
2315 -
2316 -jasmine.Spec.prototype.fail = function (e) {
2317 - var expectationResult = new jasmine.ExpectationResult({
2318 - passed: false,
2319 - message: e ? jasmine.util.formatException(e) : 'Exception',
2320 - trace: { stack: e.stack }
2321 - });
2322 - this.results_.addResult(expectationResult);
2323 -};
2324 -
2325 -jasmine.Spec.prototype.getMatchersClass_ = function() {
2326 - return this.matchersClass || this.env.matchersClass;
2327 -};
2328 -
2329 -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
2330 - var parent = this.getMatchersClass_();
2331 - var newMatchersClass = function() {
2332 - parent.apply(this, arguments);
2333 - };
2334 - jasmine.util.inherit(newMatchersClass, parent);
2335 - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
2336 - this.matchersClass = newMatchersClass;
2337 -};
2338 -
2339 -jasmine.Spec.prototype.finishCallback = function() {
2340 - this.env.reporter.reportSpecResults(this);
2341 -};
2342 -
2343 -jasmine.Spec.prototype.finish = function(onComplete) {
2344 - this.removeAllSpies();
2345 - this.finishCallback();
2346 - if (onComplete) {
2347 - onComplete();
2348 - }
2349 -};
2350 -
2351 -jasmine.Spec.prototype.after = function(doAfter) {
2352 - if (this.queue.isRunning()) {
2353 - this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
2354 - } else {
2355 - this.afterCallbacks.unshift(doAfter);
2356 - }
2357 -};
2358 -
2359 -jasmine.Spec.prototype.execute = function(onComplete) {
2360 - var spec = this;
2361 - if (!spec.env.specFilter(spec)) {
2362 - spec.results_.skipped = true;
2363 - spec.finish(onComplete);
2364 - return;
2365 - }
2366 -
2367 - this.env.reporter.reportSpecStarting(this);
2368 -
2369 - spec.env.currentSpec = spec;
2370 -
2371 - spec.addBeforesAndAftersToQueue();
2372 -
2373 - spec.queue.start(function () {
2374 - spec.finish(onComplete);
2375 - });
2376 -};
2377 -
2378 -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
2379 - var runner = this.env.currentRunner();
2380 - var i;
2381 -
2382 - for (var suite = this.suite; suite; suite = suite.parentSuite) {
2383 - for (i = 0; i < suite.before_.length; i++) {
2384 - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
2385 - }
2386 - }
2387 - for (i = 0; i < runner.before_.length; i++) {
2388 - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
2389 - }
2390 - for (i = 0; i < this.afterCallbacks.length; i++) {
2391 - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
2392 - }
2393 - for (suite = this.suite; suite; suite = suite.parentSuite) {
2394 - for (i = 0; i < suite.after_.length; i++) {
2395 - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
2396 - }
2397 - }
2398 - for (i = 0; i < runner.after_.length; i++) {
2399 - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
2400 - }
2401 -};
2402 -
2403 -jasmine.Spec.prototype.explodes = function() {
2404 - throw 'explodes function should not have been called';
2405 -};
2406 -
2407 -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
2408 - if (obj == jasmine.undefined) {
2409 - throw "spyOn could not find an object to spy upon for " + methodName + "()";
2410 - }
2411 -
2412 - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
2413 - throw methodName + '() method does not exist';
2414 - }
2415 -
2416 - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
2417 - throw new Error(methodName + ' has already been spied upon');
2418 - }
2419 -
2420 - var spyObj = jasmine.createSpy(methodName);
2421 -
2422 - this.spies_.push(spyObj);
2423 - spyObj.baseObj = obj;
2424 - spyObj.methodName = methodName;
2425 - spyObj.originalValue = obj[methodName];
2426 -
2427 - obj[methodName] = spyObj;
2428 -
2429 - return spyObj;
2430 -};
2431 -
2432 -jasmine.Spec.prototype.removeAllSpies = function() {
2433 - for (var i = 0; i < this.spies_.length; i++) {
2434 - var spy = this.spies_[i];
2435 - spy.baseObj[spy.methodName] = spy.originalValue;
2436 - }
2437 - this.spies_ = [];
2438 -};
2439 -
2440 -/**
2441 - * Internal representation of a Jasmine suite.
2442 - *
2443 - * @constructor
2444 - * @param {jasmine.Env} env
2445 - * @param {String} description
2446 - * @param {Function} specDefinitions
2447 - * @param {jasmine.Suite} parentSuite
2448 - */
2449 -jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
2450 - var self = this;
2451 - self.id = env.nextSuiteId ? env.nextSuiteId() : null;
2452 - self.description = description;
2453 - self.queue = new jasmine.Queue(env);
2454 - self.parentSuite = parentSuite;
2455 - self.env = env;
2456 - self.before_ = [];
2457 - self.after_ = [];
2458 - self.children_ = [];
2459 - self.suites_ = [];
2460 - self.specs_ = [];
2461 -};
2462 -
2463 -jasmine.Suite.prototype.getFullName = function() {
2464 - var fullName = this.description;
2465 - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
2466 - fullName = parentSuite.description + ' ' + fullName;
2467 - }
2468 - return fullName;
2469 -};
2470 -
2471 -jasmine.Suite.prototype.finish = function(onComplete) {
2472 - this.env.reporter.reportSuiteResults(this);
2473 - this.finished = true;
2474 - if (typeof(onComplete) == 'function') {
2475 - onComplete();
2476 - }
2477 -};
2478 -
2479 -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
2480 - beforeEachFunction.typeName = 'beforeEach';
2481 - this.before_.unshift(beforeEachFunction);
2482 -};
2483 -
2484 -jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
2485 - afterEachFunction.typeName = 'afterEach';
2486 - this.after_.unshift(afterEachFunction);
2487 -};
2488 -
2489 -jasmine.Suite.prototype.results = function() {
2490 - return this.queue.results();
2491 -};
2492 -
2493 -jasmine.Suite.prototype.add = function(suiteOrSpec) {
2494 - this.children_.push(suiteOrSpec);
2495 - if (suiteOrSpec instanceof jasmine.Suite) {
2496 - this.suites_.push(suiteOrSpec);
2497 - this.env.currentRunner().addSuite(suiteOrSpec);
2498 - } else {
2499 - this.specs_.push(suiteOrSpec);
2500 - }
2501 - this.queue.add(suiteOrSpec);
2502 -};
2503 -
2504 -jasmine.Suite.prototype.specs = function() {
2505 - return this.specs_;
2506 -};
2507 -
2508 -jasmine.Suite.prototype.suites = function() {
2509 - return this.suites_;
2510 -};
2511 -
2512 -jasmine.Suite.prototype.children = function() {
2513 - return this.children_;
2514 -};
2515 -
2516 -jasmine.Suite.prototype.execute = function(onComplete) {
2517 - var self = this;
2518 - this.queue.start(function () {
2519 - self.finish(onComplete);
2520 - });
2521 -};
2522 -jasmine.WaitsBlock = function(env, timeout, spec) {
2523 - this.timeout = timeout;
2524 - jasmine.Block.call(this, env, null, spec);
2525 -};
2526 -
2527 -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
2528 -
2529 -jasmine.WaitsBlock.prototype.execute = function (onComplete) {
2530 - if (jasmine.VERBOSE) {
2531 - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
2532 - }
2533 - this.env.setTimeout(function () {
2534 - onComplete();
2535 - }, this.timeout);
2536 -};
2537 -/**
2538 - * A block which waits for some condition to become true, with timeout.
2539 - *
2540 - * @constructor
2541 - * @extends jasmine.Block
2542 - * @param {jasmine.Env} env The Jasmine environment.
2543 - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
2544 - * @param {Function} latchFunction A function which returns true when the desired condition has been met.
2545 - * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
2546 - * @param {jasmine.Spec} spec The Jasmine spec.
2547 - */
2548 -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
2549 - this.timeout = timeout || env.defaultTimeoutInterval;
2550 - this.latchFunction = latchFunction;
2551 - this.message = message;
2552 - this.totalTimeSpentWaitingForLatch = 0;
2553 - jasmine.Block.call(this, env, null, spec);
2554 -};
2555 -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
2556 -
2557 -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
2558 -
2559 -jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
2560 - if (jasmine.VERBOSE) {
2561 - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
2562 - }
2563 - var latchFunctionResult;
2564 - try {
2565 - latchFunctionResult = this.latchFunction.apply(this.spec);
2566 - } catch (e) {
2567 - this.spec.fail(e);
2568 - onComplete();
2569 - return;
2570 - }
2571 -
2572 - if (latchFunctionResult) {
2573 - onComplete();
2574 - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
2575 - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
2576 - this.spec.fail({
2577 - name: 'timeout',
2578 - message: message
2579 - });
2580 -
2581 - this.abort = true;
2582 - onComplete();
2583 - } else {
2584 - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
2585 - var self = this;
2586 - this.env.setTimeout(function() {
2587 - self.execute(onComplete);
2588 - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
2589 - }
2590 -};
2591 -
2592 -jasmine.version_= {
2593 - "major": 1,
2594 - "minor": 3,
2595 - "build": 1,
2596 - "revision": 1354556913
2597 -};
all/phantom.js deleted
-44
@@ -1,44 +0,0 @@
1 -/**
2 - * Copyright 2013 Facebook, Inc.
3 - *
4 - * Licensed under the Apache License, Version 2.0 (the "License");
5 - * you may not use this file except in compliance with the License.
6 - * You may obtain a copy of the License at
7 - *
8 - * http://www.apache.org/licenses/LICENSE-2.0
9 - *
10 - * Unless required by applicable law or agreed to in writing, software
11 - * distributed under the License is distributed on an "AS IS" BASIS,
12 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 - * See the License for the specific language governing permissions and
14 - * limitations under the License.
15 - *
16 - * This module provides a bridge from content-land to phantom-land via the
17 - * window.callPhantom interface.
18 - */
19 -
20 -var console = require("./console");
21 -var global = Function("return this")();
22 -
23 -if (global.callPhantom) {
24 - // Phantom's onConsoleMessage support is lacking (only one argument
25 - // supported, and it must be a string), so we use callPhantom to
26 - // forward console messages instead.
27 - console.addListener(function(method, args) {
28 - global.callPhantom({
29 - type: "console",
30 - method: method,
31 - args: args
32 - });
33 - });
34 -
35 - exports.exit = function(code) {
36 - global.callPhantom({
37 - type: "exit",
38 - code: code
39 - });
40 - };
41 -
42 -} else {
43 - exports.exit = function() {};
44 -}