Delete ReactARTStack (#9895)
Dan Abramov committed
Jun 8, 2017 at 17:05 UTC
6f1d2c940deb97c781536b55531cc1f6cb1cd1ac
3 files changed
+1
-659
src/renderers/art/ReactART.js
deleted
-18
@@ -1,18 +0,0 @@
1
-/**
2
- * Copyright (c) 2013-present Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @providesModule ReactART
10
- */
11
-
12
-'use strict';
13
-
14
-const ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
15
-
16
-module.exports = ReactDOMFeatureFlags.useFiber
17
- ? require('ReactARTFiber')
18
- : require('ReactARTStack');
src/renderers/art/ReactARTStack.js
deleted
-640
@@ -1,640 +0,0 @@
1
-/**
2
- * Copyright (c) 2013-present Facebook, Inc.
3
- * All rights reserved.
4
- *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
8
- *
9
- * @providesModule ReactARTStack
10
- */
11
-
12
-'use strict';
13
-
14
-require('art/modes/current').setCurrent(
15
- require('art/modes/fast-noSideEffects'), // Flip this to DOM mode for debugging
16
-);
17
-
18
-const Transform = require('art/core/transform');
19
-const Mode = require('art/modes/current');
20
-
21
-const React = require('react');
22
-const ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
23
-const ReactDOM = require('react-dom');
24
-const ReactInstanceMap = require('ReactInstanceMap');
25
-const ReactMultiChild = require('ReactMultiChild');
26
-
27
-const emptyObject = require('fbjs/lib/emptyObject');
28
-const invariant = require('fbjs/lib/invariant');
29
-
30
-const ReactDOMInternals =
31
- ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
32
-const ReactUpdates = ReactDOMInternals.ReactUpdates;
33
-
34
-const pooledTransform = new Transform();
35
-
36
-// Utilities
37
-
38
-function childrenAsString(children) {
39
- if (!children) {
40
- return '';
41
- }
42
- if (typeof children === 'string') {
43
- return children;
44
- }
45
- if (children.length) {
46
- return children.join('\n');
47
- }
48
- return '';
49
-}
50
-
51
-function createComponent(name) {
52
- const ReactARTComponent = function(element) {
53
- this.node = null;
54
- this.subscriptions = null;
55
- this.listeners = null;
56
- this._mountImage = null;
57
- this._renderedChildren = null;
58
- this.construct(element);
59
- };
60
- ReactARTComponent.displayName = name;
61
- for (let i = 1, l = arguments.length; i < l; i++) {
62
- Object.assign(ReactARTComponent.prototype, arguments[i]);
63
- }
64
-
65
- return ReactARTComponent;
66
-}
67
-
68
-/**
69
- * Insert `node` into `parentNode` after `referenceNode`.
70
- */
71
-function injectAfter(parentNode, referenceNode, node) {
72
- let beforeNode;
73
- if (
74
- node.parentNode === parentNode &&
75
- node.previousSibling === referenceNode
76
- ) {
77
- return;
78
- }
79
- if (referenceNode == null) {
80
- // node is supposed to be first.
81
- beforeNode = parentNode.firstChild;
82
- } else {
83
- // node is supposed to be after referenceNode.
84
- beforeNode = referenceNode.nextSibling;
85
- }
86
- if (beforeNode && beforeNode.previousSibling !== node) {
87
- // Cases where `node === beforeNode` should get filtered out by earlier
88
- // checks and the behavior isn't well-defined.
89
- invariant(
90
- node !== beforeNode,
91
- 'ReactART: Can not insert node before itself',
92
- );
93
- node.injectBefore(beforeNode);
94
- } else if (node.parentNode !== parentNode) {
95
- node.inject(parentNode);
96
- }
97
-}
98
-
99
-// ContainerMixin for components that can hold ART nodes
100
-
101
-const ContainerMixin = Object.assign({}, ReactMultiChild, {
102
- /**
103
- * Moves a child component to the supplied index.
104
- *
105
- * @param {ReactComponent} child Component to move.
106
- * @param {number} toIndex Destination index of the element.
107
- * @protected
108
- */
109
- moveChild: function(child, afterNode, toIndex, lastIndex) {
110
- const childNode = child._mountImage;
111
- injectAfter(this.node, afterNode, childNode);
112
- },
113
-
114
- /**
115
- * Creates a child component.
116
- *
117
- * @param {ReactComponent} child Component to create.
118
- * @param {object} childNode ART node to insert.
119
- * @protected
120
- */
121
- createChild: function(child, afterNode, childNode) {
122
- child._mountImage = childNode;
123
- injectAfter(this.node, afterNode, childNode);
124
- },
125
-
126
- /**
127
- * Removes a child component.
128
- *
129
- * @param {ReactComponent} child Child to remove.
130
- * @protected
131
- */
132
- removeChild: function(child) {
133
- child._mountImage.eject();
134
- child._mountImage = null;
135
- },
136
-
137
- updateChildrenAtRoot: function(nextChildren, transaction) {
138
- this.updateChildren(nextChildren, transaction, emptyObject);
139
- },
140
-
141
- mountAndInjectChildrenAtRoot: function(children, transaction) {
142
- this.mountAndInjectChildren(children, transaction, emptyObject);
143
- },
144
-
145
- /**
146
- * Override to bypass batch updating because it is not necessary.
147
- *
148
- * @param {?object} nextChildren.
149
- * @param {ReactReconcileTransaction} transaction
150
- * @internal
151
- * @override {ReactMultiChild.updateChildren}
152
- */
153
- updateChildren: function(nextChildren, transaction, context) {
154
- this._updateChildren(nextChildren, transaction, context);
155
- },
156
-
157
- // Shorthands
158
-
159
- mountAndInjectChildren: function(children, transaction, context) {
160
- const mountedImages = this.mountChildren(children, transaction, context);
161
- // Each mount image corresponds to one of the flattened children
162
- let i = 0;
163
- for (let key in this._renderedChildren) {
164
- if (this._renderedChildren.hasOwnProperty(key)) {
165
- const child = this._renderedChildren[key];
166
- child._mountImage = mountedImages[i];
167
- mountedImages[i].inject(this.node);
168
- i++;
169
- }
170
- }
171
- },
172
-});
173
-
174
-// Surface is a React DOM Component, not an ART component. It serves as the
175
-// entry point into the ART reconciler.
176
-
177
-class Surface extends React.Component {
178
- componentDidMount() {
179
- const domNode = ReactDOM.findDOMNode(this);
180
-
181
- this.node = Mode.Surface(+this.props.width, +this.props.height, domNode);
182
-
183
- const transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
184
- transaction.perform(
185
- this.mountAndInjectChildren,
186
- this,
187
- this.props.children,
188
- transaction,
189
- ReactInstanceMap.get(this)._context,
190
- );
191
- ReactUpdates.ReactReconcileTransaction.release(transaction);
192
- }
193
-
194
- componentDidUpdate(oldProps) {
195
- const node = this.node;
196
- if (
197
- this.props.width != oldProps.width ||
198
- this.props.height != oldProps.height
199
- ) {
200
- node.resize(+this.props.width, +this.props.height);
201
- }
202
-
203
- const doUpdate = () => {
204
- const transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
205
- transaction.perform(
206
- this.updateChildren,
207
- this,
208
- this.props.children,
209
- transaction,
210
- ReactInstanceMap.get(this)._context,
211
- );
212
- ReactUpdates.ReactReconcileTransaction.release(transaction);
213
- };
214
-
215
- if (ReactDefaultBatchingStrategy.isBatchingUpdates) {
216
- doUpdate();
217
- } else {
218
- ReactUpdates.batchedUpdates(doUpdate);
219
- }
220
-
221
- if (node.render) {
222
- node.render();
223
- }
224
- }
225
-
226
- componentWillUnmount() {
227
- this.unmountChildren();
228
- }
229
-
230
- render() {
231
- // This is going to be a placeholder because we don't know what it will
232
- // actually resolve to because ART may render canvas, vml or svg tags here.
233
- // We only allow a subset of properties since others might conflict with
234
- // ART's properties.
235
- const props = this.props;
236
-
237
- // TODO: ART's Canvas Mode overrides surface title and cursor
238
- const Tag = Mode.Surface.tagName;
239
- return (
240
- <Tag
241
- accessKey={props.accessKey}
242
- className={props.className}
243
- draggable={props.draggable}
244
- role={props.role}
245
- style={props.style}
246
- tabIndex={props.tabIndex}
247
- title={props.title}
248
- />
249
- );
250
- }
251
-}
252
-Surface.displayName = 'Surface';
253
-Object.assign(Surface.prototype, ContainerMixin);
254
-
255
-// Various nodes that can go into a surface
256
-
257
-const EventTypes = {
258
- onMouseMove: 'mousemove',
259
- onMouseOver: 'mouseover',
260
- onMouseOut: 'mouseout',
261
- onMouseUp: 'mouseup',
262
- onMouseDown: 'mousedown',
263
- onClick: 'click',
264
-};
265
-
266
-const NodeMixin = {
267
- construct: function(element) {
268
- this._currentElement = element;
269
- },
270
-
271
- getNativeNode: function() {
272
- return this.node;
273
- },
274
-
275
- getPublicInstance: function() {
276
- return this.node;
277
- },
278
-
279
- putEventListener: function(type, listener) {
280
- const subscriptions = this.subscriptions || (this.subscriptions = {});
281
- const listeners = this.listeners || (this.listeners = {});
282
- listeners[type] = listener;
283
- if (listener) {
284
- if (!subscriptions[type]) {
285
- subscriptions[type] = this.node.subscribe(type, this.handleEvent, this);
286
- }
287
- } else {
288
- if (subscriptions[type]) {
289
- subscriptions[type]();
290
- delete subscriptions[type];
291
- }
292
- }
293
- },
294
-
295
- handleEvent: function(event) {
296
- const listener = this.listeners[event.type];
297
- if (!listener) {
298
- return;
299
- }
300
- if (typeof listener === 'function') {
301
- listener.call(this, event);
302
- } else if (listener.handleEvent) {
303
- listener.handleEvent(event);
304
- }
305
- },
306
-
307
- destroyEventListeners: function() {
308
- const subscriptions = this.subscriptions;
309
- if (subscriptions) {
310
- for (let type in subscriptions) {
311
- subscriptions[type]();
312
- }
313
- }
314
- this.subscriptions = null;
315
- this.listeners = null;
316
- },
317
-
318
- applyNodeProps: function(oldProps, props) {
319
- const node = this.node;
320
-
321
- const scaleX = props.scaleX != null
322
- ? props.scaleX
323
- : props.scale != null ? props.scale : 1;
324
- const scaleY = props.scaleY != null
325
- ? props.scaleY
326
- : props.scale != null ? props.scale : 1;
327
-
328
- pooledTransform
329
- .transformTo(1, 0, 0, 1, 0, 0)
330
- .move(props.x || 0, props.y || 0)
331
- .rotate(props.rotation || 0, props.originX, props.originY)
332
- .scale(scaleX, scaleY, props.originX, props.originY);
333
-
334
- if (props.transform != null) {
335
- pooledTransform.transform(props.transform);
336
- }
337
-
338
- if (
339
- node.xx !== pooledTransform.xx ||
340
- node.yx !== pooledTransform.yx ||
341
- node.xy !== pooledTransform.xy ||
342
- node.yy !== pooledTransform.yy ||
343
- node.x !== pooledTransform.x ||
344
- node.y !== pooledTransform.y
345
- ) {
346
- node.transformTo(pooledTransform);
347
- }
348
-
349
- if (props.cursor !== oldProps.cursor || props.title !== oldProps.title) {
350
- node.indicate(props.cursor, props.title);
351
- }
352
-
353
- if (node.blend && props.opacity !== oldProps.opacity) {
354
- node.blend(props.opacity == null ? 1 : props.opacity);
355
- }
356
-
357
- if (props.visible !== oldProps.visible) {
358
- if (props.visible == null || props.visible) {
359
- node.show();
360
- } else {
361
- node.hide();
362
- }
363
- }
364
-
365
- for (let type in EventTypes) {
366
- this.putEventListener(EventTypes[type], props[type]);
367
- }
368
- },
369
-
370
- mountComponentIntoNode: function(rootID, container) {
371
- throw new Error(
372
- 'You cannot render an ART component standalone. ' +
373
- 'You need to wrap it in a Surface.',
374
- );
375
- },
376
-};
377
-
378
-// Group
379
-
380
-const Group = createComponent('Group', NodeMixin, ContainerMixin, {
381
- mountComponent: function(
382
- transaction,
383
- nativeParent,
384
- nativeContainerInfo,
385
- context,
386
- ) {
387
- this.node = Mode.Group();
388
- const props = this._currentElement.props;
389
- this.applyGroupProps(emptyObject, props);
390
- this.mountAndInjectChildren(props.children, transaction, context);
391
- return this.node;
392
- },
393
-
394
- receiveComponent: function(nextComponent, transaction, context) {
395
- const props = nextComponent.props;
396
- const oldProps = this._currentElement.props;
397
- this.applyGroupProps(oldProps, props);
398
- this.updateChildren(props.children, transaction, context);
399
- this._currentElement = nextComponent;
400
- },
401
-
402
- applyGroupProps: function(oldProps, props) {
403
- this.node.width = props.width;
404
- this.node.height = props.height;
405
- this.applyNodeProps(oldProps, props);
406
- },
407
-
408
- unmountComponent: function() {
409
- this.destroyEventListeners();
410
- this.unmountChildren();
411
- },
412
-});
413
-
414
-// ClippingRectangle
415
-const ClippingRectangle = createComponent(
416
- 'ClippingRectangle',
417
- NodeMixin,
418
- ContainerMixin,
419
- {
420
- mountComponent: function(
421
- transaction,
422
- nativeParent,
423
- nativeContainerInfo,
424
- context,
425
- ) {
426
- this.node = Mode.ClippingRectangle();
427
- const props = this._currentElement.props;
428
- this.applyClippingProps(emptyObject, props);
429
- this.mountAndInjectChildren(props.children, transaction, context);
430
- return this.node;
431
- },
432
-
433
- receiveComponent: function(nextComponent, transaction, context) {
434
- const props = nextComponent.props;
435
- const oldProps = this._currentElement.props;
436
- this.applyClippingProps(oldProps, props);
437
- this.updateChildren(props.children, transaction, context);
438
- this._currentElement = nextComponent;
439
- },
440
-
441
- applyClippingProps: function(oldProps, props) {
442
- this.node.width = props.width;
443
- this.node.height = props.height;
444
- this.node.x = props.x;
445
- this.node.y = props.y;
446
- this.applyNodeProps(oldProps, props);
447
- },
448
-
449
- unmountComponent: function() {
450
- this.destroyEventListeners();
451
- this.unmountChildren();
452
- },
453
- },
454
-);
455
-
456
-// Renderables
457
-
458
-const RenderableMixin = Object.assign({}, NodeMixin, {
459
- applyRenderableProps: function(oldProps, props) {
460
- if (oldProps.fill !== props.fill) {
461
- if (props.fill && props.fill.applyFill) {
462
- props.fill.applyFill(this.node);
463
- } else {
464
- this.node.fill(props.fill);
465
- }
466
- }
467
- if (
468
- oldProps.stroke !== props.stroke ||
469
- oldProps.strokeWidth !== props.strokeWidth ||
470
- oldProps.strokeCap !== props.strokeCap ||
471
- oldProps.strokeJoin !== props.strokeJoin ||
472
- // TODO: Consider a deep check of stokeDash.
473
- // This may benefit the VML version in IE.
474
- oldProps.strokeDash !== props.strokeDash
475
- ) {
476
- this.node.stroke(
477
- props.stroke,
478
- props.strokeWidth,
479
- props.strokeCap,
480
- props.strokeJoin,
481
- props.strokeDash,
482
- );
483
- }
484
- this.applyNodeProps(oldProps, props);
485
- },
486
-
487
- unmountComponent: function() {
488
- this.destroyEventListeners();
489
- },
490
-});
491
-
492
-// Shape
493
-
494
-const Shape = createComponent('Shape', RenderableMixin, {
495
- construct: function(element) {
496
- this._currentElement = element;
497
- this._oldDelta = null;
498
- this._oldPath = null;
499
- },
500
-
501
- mountComponent: function(
502
- transaction,
503
- nativeParent,
504
- nativeContainerInfo,
505
- context,
506
- ) {
507
- this.node = Mode.Shape();
508
- const props = this._currentElement.props;
509
- this.applyShapeProps(emptyObject, props);
510
- return this.node;
511
- },
512
-
513
- receiveComponent: function(nextComponent, transaction, context) {
514
- const props = nextComponent.props;
515
- const oldProps = this._currentElement.props;
516
- this.applyShapeProps(oldProps, props);
517
- this._currentElement = nextComponent;
518
- },
519
-
520
- applyShapeProps: function(oldProps, props) {
521
- const oldDelta = this._oldDelta;
522
- const oldPath = this._oldPath;
523
- const path = props.d || childrenAsString(props.children);
524
-
525
- if (
526
- path.delta !== oldDelta ||
527
- path !== oldPath ||
528
- oldProps.width !== props.width ||
529
- oldProps.height !== props.height
530
- ) {
531
- this.node.draw(path, props.width, props.height);
532
-
533
- this._oldPath = path;
534
- this._oldDelta = path.delta;
535
- }
536
-
537
- this.applyRenderableProps(oldProps, props);
538
- },
539
-});
540
-
541
-// Text
542
-
543
-const Text = createComponent('Text', RenderableMixin, {
544
- construct: function(element) {
545
- this._currentElement = element;
546
- this._oldString = null;
547
- },
548
-
549
- mountComponent: function(
550
- transaction,
551
- nativeParent,
552
- nativeContainerInfo,
553
- context,
554
- ) {
555
- const props = this._currentElement.props;
556
- const newString = childrenAsString(props.children);
557
- this.node = Mode.Text(newString, props.font, props.alignment, props.path);
558
- this._oldString = newString;
559
- this.applyRenderableProps(emptyObject, props);
560
- return this.node;
561
- },
562
-
563
- isSameFont: function(oldFont, newFont) {
564
- if (oldFont === newFont) {
565
- return true;
566
- }
567
- if (typeof newFont === 'string' || typeof oldFont === 'string') {
568
- return false;
569
- }
570
- return (
571
- newFont.fontSize === oldFont.fontSize &&
572
- newFont.fontStyle === oldFont.fontStyle &&
573
- newFont.fontVariant === oldFont.fontVariant &&
574
- newFont.fontWeight === oldFont.fontWeight &&
575
- newFont.fontFamily === oldFont.fontFamily
576
- );
577
- },
578
-
579
- receiveComponent: function(nextComponent, transaction, context) {
580
- const props = nextComponent.props;
581
- const oldProps = this._currentElement.props;
582
-
583
- const oldString = this._oldString;
584
- const newString = childrenAsString(props.children);
585
-
586
- if (
587
- oldString !== newString ||
588
- !this.isSameFont(oldProps.font, props.font) ||
589
- oldProps.alignment !== props.alignment ||
590
- oldProps.path !== props.path
591
- ) {
592
- this.node.draw(newString, props.font, props.alignment, props.path);
593
- this._oldString = newString;
594
- }
595
-
596
- this.applyRenderableProps(oldProps, props);
597
- this._currentElement = nextComponent;
598
- },
599
-});
600
-
601
-// Declarative fill type objects - API design not finalized
602
-
603
-const slice = Array.prototype.slice;
604
-
605
-function LinearGradient(stops, x1, y1, x2, y2) {
606
- this.args = slice.call(arguments);
607
-}
608
-
609
-LinearGradient.prototype.applyFill = function(node) {
610
- node.fillLinear.apply(node, this.args);
611
-};
612
-
613
-function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
614
- this.args = slice.call(arguments);
615
-}
616
-
617
-RadialGradient.prototype.applyFill = function(node) {
618
- node.fillRadial.apply(node, this.args);
619
-};
620
-
621
-function Pattern(url, width, height, left, top) {
622
- this.args = slice.call(arguments);
623
-}
624
-
625
-Pattern.prototype.applyFill = function(node) {
626
- node.fillImage.apply(node, this.args);
627
-};
628
-
629
-module.exports = {
630
- ClippingRectangle,
631
- Group,
632
- LinearGradient,
633
- Path: Mode.Path,
634
- Pattern,
635
- RadialGradient,
636
- Shape,
637
- Surface,
638
- Text,
639
- Transform,
640
-};
src/renderers/art/__tests__/ReactART-test.js
+1
-1
@@ -24,7 +24,7 @@ var TestComponent;
24
25
var Missing = {};
26
27
-var ReactART = require('ReactART');
27
+var ReactART = require('ReactARTFiber');
28
var ARTSVGMode = require('art/modes/svg');
29
var ARTCurrentMode = require('art/modes/current');
30