Summary:
@public
Introduce `overflow:scroll` so that scrolling can be implemented without the current overflow:visible hackiness. Currently we use AT_MOST to measure in the cross axis but not in the main axis. This was done to enable scrolling containers where children are not constraint in the main axis by their parent. This caused problems for non-scrolling containers though as it meant that their children cannot be measured correctly in the main axis. Introducing `overflow:scroll` fixes this.
Reviewed By: astreet
Differential Revision: D3855801
Summary:
@public
This is to be able to depend on ReactClippingViewGroup from BaseViewManager. Devs using ReactClippingViewGroup may need to update their imports when updating past this commit.
Reviewed By: lexs
Differential Revision: D3835328
Summary:
We were always getting LEFT explicitly, and, due to RTL support, we
should be asking for START instead.
Reviewed By: sriramramani
Differential Revision: D3836816
Summary:
@public
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3841658
Summary:
Fix TextInput padding on Nodes. We used to not call super and used
to manually do the setting of padding. This stops us from running the same
logic that non-Nodes runs (we bypassed it), so this fixes it.
Reviewed By: astreet
Differential Revision: D3825227
Summary:
Due to the RTL implementation, the ViewProps spacing array has START
and END, whereas Nodes should deal with RIGHT and LEFT directly (just like
non-Nodes does). This is the same implementation in use by non-Nodes.
Reviewed By: astreet
Differential Revision: D3809028
Summary:
Nodes historically had two image implementations -
DrawImageWithDrawee and DrawImageWithPipeline. The drawee implementation
was the default (per request of the Fresco team). At this point, there is
no point of having two (especially since updates to one need to be made to
the other), so this patch removes pipeline.
Reviewed By: sriramramani
Differential Revision: D3755523
Summary:
Nodes would typically clip its images, and then Fresco would then
re-clip as part of ScaleTypeDrawable - in addition to being unnecessary,
it's also incorrect, beacuse it causes the image to be smaller than it
should be.
Reviewed By: sriramramani
Differential Revision: D3754778
Summary:
@public
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3751097
Summary:
@public
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3751097
Summary:
This is just a minor cleanup, use constants for the LEFT
and RIGHT alignments, since they are hide.
Reviewed By: sriramramani
Differential Revision: D3746019
Summary: Adds a flag that can be set in FlatViewGroup to see known performance issues in Nodes objects. This is mostly useful in internal development of Nodes, and will be a dead code path when not set.
Reviewed By: ahmedre
Differential Revision: D3732675
Summary: Node region bounds are assumed to equal the underlying node bounds. In the case of hit slop, these need to be abstracted.
Reviewed By: ahmedre
Differential Revision: D3713430
Summary:
This is minor, but for our use case a SparseArray is going to be faster as long as we have less than 10,000 clipped subviews, and will also use much less memory.
Faster because of the boxing, unboxing and hash caching; less memory as it is two arrays instead of the object overhead of the HashMap.
Reviewed By: ahmedre
Differential Revision: D3704326
Summary: Previously, the first time we collected a draw view, we would make a clone, even though the draw view had never been mutated. This refactors draw view to avoid this extra allocate.
Reviewed By: ahmedre
Differential Revision: D3719056
Summary:
In Nodes, there were certain cases where text wasn't drawn due to an
optimization that skipped measuring because the size was already known.
Reviewed By: emilsjolander
Differential Revision: D3713841
Summary:
For Nodes that don't mount to views, measureLayout wasn't working
because our calls for getting the width and height would return the view delta
bounds, which won't exist for Nodes. #accept2ship
Differential Revision: D3707880
Summary:
Nodes currently doesn't ask Fresco to resize images, but this is
potentially problematic (ex having a camera photo of 6000x1500 causes a crash
due to the massive size).
Differential Revision: D3687944
Summary: Adds support for horizontal clipping, though the FlatViewGroup needs to be made aware still of which it is.
Reviewed By: ahmedre
Differential Revision: D3673501
Summary: This optimizes node region searches in clipping cases, and does position calculation for drawCommands off of the UI thread.
Reviewed By: ahmedre
Differential Revision: D3665301
Summary: Add jni bindings for csslayout. First step in many of removing LayoutEngine.java and performing all layout in native.
Reviewed By: lucasr
Differential Revision: D3648793
Summary:
Use ImageRequestBuilder directly in Nodes, just like we do for
non-Nodes.
Reviewed By: sriramramani
Differential Revision:
D3660610
Ninja: Sandcastle is broken. 25 denizens of the Facebook republic are affected by this unrelated issue today.
Summary: Add directional aware clipping to DrawCommandManager. Currently not attached to FlatViewGroup logic, with the plan to keep this unattached until we are clipping the way we want to in the final state.
Reviewed By: ahmedre
Differential Revision: D3622253
Summary: @public Make UIOperation public so that custom implementations can expose instances of it.
Reviewed By: ahmedre
Differential Revision: D3618197
Summary:
Support rounded clipping in Nodes. Before, if a view had
a radius and had overflow of hidden, its children could still draw
outside of it (specifically, in the area between the rounded rect
and square rect) - this is due to the fact that clipping is, by
default, rectangular. This patch supports this type of rounded
clipping.
Differential Revision: D3634861
Summary: Previously, we had no information about the positioning of the view until after we had attached it. We have the position information attached to the shadow node, but this attaches it to the DrawView as well. It also removes the need for AbstractClippingDrawCommand.
Reviewed By: ahmedre
Differential Revision: D3609092
Summary: @public Change the textalign setter to support RTL. In order to support text alignment according to layout style, move the textalign setter bridge function from ReactTextViewManager.java to ReactTextShadowNode.java and calculate it correctly on RCTTextUpdate.
Reviewed By: dmmiller
Differential Revision: D3597494
Summary:
This patch fixes measureInWindow for Nodes backed by Views.
Whereas the intention was to call the super implementation when we have a
Node backed by a View, we instead called the super implementation of
measure, which doesn't measure relative to window.
Differential Revision: D3607890
Summary:
Currently we have race conditions in DrawView related to isViewGroupClipped, where we create a copy of the DrawView before we update the clipping state, and think the view is unclipped in the next iteration.
Also we are sometimes creating a DrawView with a reactTag of 0.
This fixes both, and is part of the upcoming DrawView bounds change, but is a separate issue that is live in current source.
Reviewed By: ahmedre
Differential Revision: D3598499
Summary:
@public
This is pure cleanup so that we can make sure that all events are living in the same time space (currently nano seconds).
Reviewed By: foghina
Differential Revision: D3593884
Summary:
View the comment thread for discussion:
https://www.facebook.com/groups/1505872839725322/permalink/1630102823968989
Our current behaviour of add then immediately remove if a view is clipped pretty much guarantees that we kill network requests for images in feed. We have a better fix for that in the pipeline, but this is a low risk fix in the meantime.
Reviewed By: ahmedre
Differential Revision: D3597785
Summary:
This PR was split from a commit originally in #8619. /cc dmmiller
When an inline image was larger than the specified line height,
the image would be clipped. This changes the behavior so
that the line height is changed to make room for the inline
image. This is consistent with the behavior of RN for iOS.
Here's how the change works.
ReactTextView now receives its line height from the layout thread
rather than directly from JavaScript.
The reason is that the layout thread may pick a different line height.
In the case that the tallest inline image is larger than the line
height supplied by JavaScript, we want to use that image's height as
the line height rather than the supplied line height.
Also fixed a bug where the image, which is supposed to be baseline
aligned, would be positioned at the wrong y location. To fix this,
we use `y` (the baseline) in the `draw` method rather than trying
to calculate the baseline from `bottom`. For more information
see https://code.google.com/p/andro
Closes https://github.com/facebook/react-native/pull/8907
Differential Revision: D3592781
Pulled By: dmmiller
Summary:
DrawImageWithDrawee has caused NPEs when using Nodes in various cases
in RNFeed. This patch explicitly throws a RuntimeException, so that we can
debug as to whether this is coming from bad sources or a bad size for the
image.
Differential Revision: D3574998
Summary: This is the most straightforward fix for the double detach issue. If a view is not attached, then addViewInLayout never propagates onAttach, and adding through attachViewToParent is a no op. We could hack something in to attach clipped FlatViewGroups in onClippingRect, but any other view that relies on onAttachedToWindow will have similar issues.
Reviewed By: ahmedre
Differential Revision: D3560565
Summary: Since Nodes' manageChildren doesn't enqueue the child updates immediately, commands were being directed to non-updated views. Previously we applied updates for the shadow node before dispatching the command, but we can instead wait to fire commands until after we update the view hierarchy.
Reviewed By: ahmedre
Differential Revision: D3568541
Summary: Supports show layout bounds either by override within FlatViewGroup, or if show layout bounds is set in settings. Currently requires app restart to disable.
Reviewed By: ahmedre
Differential Revision: D3553669
Summary: Fixes needing to specify exact height of react views in Mason. Uses a ViewTreeObserver to delay draw until we have correct bounds.
Reviewed By: sriramramani
Differential Revision: D3527122
Summary:
Nodes wasn't supporting text decorations to the line (strike through
and underline). This patch implements that.
Differential Revision: D3512711
Summary: We do want to only apply updates when a view previously wasn't mounted and didn't have a backing view created. Previously we were applying updates to the view regardless of the mount state, which resulted in positioning bugs. Rather than revert, I cleaned up the code Ahmed fixed, since didUpdate || ensureBackingViewIsCreated() was both a bug and obscure, as the two should have a swapped order.
Reviewed By: sriramramani
Differential Revision: D3538734
Summary:
@public
Text was not correctly respecting padding. We would account for it when measuring, but then not actually apply the padding to the text. This adds support for proper padding
Reviewed By: andreicoman11
Differential Revision: D3516692
Summary:
Previously, to fix the issue of commands happening before the Views
were made and attached to the hierarchy, a check was added to see if a node
had not been mounted to a View, to update its hierarchy. In reality, we need
to do this irrespective, since a node could be mounted to a View, but its
children may not yet be attached, for example. Note that if there is nothing
to be done, this won't do extra work (i.e. applyUpdates recursively goes
through the tree from the node on which we did the operation to apply updates,
but if there are no updates, we stop traversing that praticular subtree).
Reviewed By: sriramramani
Differential Revision: D3511462
Summary:
The TextInput spannables are being set wrong by Nodes. Consequently,
when you hit space after a word, anything you type is highlighted, though it
shouldn't be.
Differential Revision: D3507516
Summary:
The results from measureInWindow were always wrong the first time it
was called. This was due to the fact that the view in question was not
actually a view yet, so the results were incorrect. This patch uses the
existing measure functionality (which can measure virtual nodes) to measure
the view, while modifying it to properly get the results relative to the
window instead of relative to the root view.
Reviewed By: sriramramani
Differential Revision: D3501544
Summary:
Depends on D3120798
Depends on D3120631
Enables D3120631 for nodes. This implementation seems to work but let me know if I'm doing something really stupid.
Reviewed By: ahmedre
Differential Revision: D3120814
Summary:
Modals were broken in Nodes, because the custom measurement logic for
all the children of the ReactModalShadowNode was not being applied (because we
wrapped it in a NativeViewWrapper). This change adds a custom flat node type
for modals.
Differential Revision: D3499557
Summary:
Fix DrawImageWithPipeline's code for checking whether or not an image
request exists or not to be the same as DrawImageWithDrawee's.
Differential Revision: D3489532
Summary:
In manageChildren, we were assuming that the indices that
were passed in to be removed were sorted, however, they weren't.
This patch sorts the children to be removed. Note that it doesn't
explicitly sort move, since these are sorted by the MoveProxy class.
Reviewed By: astreet
Differential Revision: D3474639
Summary:
Groups encountered a pretty major crash where, in many cases,
we would find that DrawCommands and Views were out of sync. This
turns out to be due to the fact that when we drop views from the
root view, we remove each child using removeChildAt (which ultimately
causes an invalidate and redraw). If this happens for a
FlatViewGroup, this causes issues where the Views are all removed,
but there are some DrawCommands (potentially DrawViews) that aren't
removed, hence them going out of sync.
Reviewed By: astreet
Differential Revision: D3473916
Summary: Currently only FlatViewGroup children were clipped, rather than all offscreen Android views.
Reviewed By: ahmedre
Differential Revision: D3462002
Summary:
During the patch for fixing the order of UI operations, we apply
updates to any node receiving a ViewManager command in order to ensure that
nodes that were not yet mounted to a View and not yet attached to their parent
would be properly able to receive the event. However, if a node is already a
view, calling the update could cause unwanted things to happen (for example,
the View's bounds changing improperly), because we're only traversing that
node of the tree and down (instead of the entire tree). This fixes the issue
by only applying updates to the node if the view mount state has changed.
Reviewed By: sriramramani
Differential Revision: D3448356
Summary:
A Layout's text can either be an Ellipsizer or a SpannedEllipsizer.
SpannedEllipsizer implements Spannable, but Ellipsizer doesn't. We were
casting the Layout's text directly to a Spanned without first checking as to
whether or not it was actually a Spanned.
Reviewed By: sriramramani
Differential Revision: D3435075
Summary:
The nodes version of D3364550. The only difference is that here we
don't get `onSizeChanged` but `onBoundsChanged`, and we need to compute the
height/width of the target image from those bounds. ahmedre please let me know
if any of these assumptions are in any way incorrect.
Reviewed By: ahmedre
Differential Revision: D3424843
Summary:
This is needed for the upcoming loading from multiple sources (D3364550 for the non-nodes version) and cache interrogation (D3392751 for non-nodes version).
This postpones creating the DraweeRequestHelper until the image size is known, which in the nodes universe is when `onBoundsChanged` is called.
Reviewed By: foghina, ahmedre
Differential Revision: D3413467
Summary:
Fix touch inspector when using Nodes by implementing custom logic.
This logic now takes into account that non-View nodes need to be clickable.
Reviewed By: astreet
Differential Revision: D3433927
Summary:
Made some improvements to RCTText based on some of our learnings from components for android. This now resembles diffusion/FBS/browse/master/fbandroid/java/com/facebook/components/widget/TextSpec.java
Things that have improved:
- Calculation of text width is now faster (we noticed in components that .getWith() on the layout is all that is needed and it is much faster)
- Use text layout builder to abstract away a lot of the low level details of static / boring layouts and text measurements
- Handle MeasureMode correctly, previously AT_MOST was not supported.
- Better handling of RTL text by using TextLayoutBuilder where I made changes to support RTL text in components. Specifically RTL text measured with UNSPECIFIED or AT_MOST.
- There was an incorrect assumption being made that when measure() was not called the text had to be boring. This is incorrect, Arabic text is never boring for example. Also multiline text is not boring either and may have exact sizing.
Reviewed By: ahmedre
Differential Revision: D3374752
Summary:
The dispatchViewManager command should, according to the spec, only
be executed after children are added. On Nodes, however, due to the fact that
the Views in question may not have been created until the call to the command
occurred, the dispatchViewManagerCommand may occur too early. Consequently,
ensure that we apply any state updates to the Node represented by that
reactTag before we enqueue the view manager command (this will ensure that
views are properly added to the parent, etc before sending the command).
Reviewed By: astreet
Differential Revision: D3428855
Summary:
@public
This adds support for specifying multiple sources for an image component, so that native can choose the best one based on the flexbox-computed size of the image.
The API is as follows: the image component receives in the `source` prop an array of objects of the type `{uri, width, height}`. On the native side, the native component will wait for the layout pass to receive the width and height of the image, and then parse the array to find the best fitting one. For now, this does not support local resources, but it will be added soon.
To see how this works and play with it, there's an example called `MultipleSourcesExample` under `ImageExample` In UIExplorer.
Reviewed By: foghina
Differential Revision: D3364550
Summary:
Historically, removeClippedSubviews for Nodes would not clip views
that overflowed their parent. This patch changes that, so that Nodes can
properly clip views when they are off screen (even if they have descendants
that overflow the bounds of their parent).
This is done by calculating a set of offsets from the actual width and
height of the view, and using those in the clipping calculations.
Reviewed By: sriramramani
Differential Revision: D3409859
Summary:
As an optimization, for something like a ScrollView which contains
a FlatViewGroup containing posts, make sure that each post is explicitly
mounted to a View. This may help improve performance, especially when said
Views are otherwise inlined as DrawCommands instead of actual Views.
Reviewed By: astreet
Differential Revision: D3161232
Summary:
The removeClippedSubviews optimization often detaches views while
maintaining strong references to them (so they can be attached again later
on). However, when removing the parent view, any detached views end up not
being cleaned up or removed, thus leaking memory. This fixes this by
explicitly dropping detached views when the parent is removed.
Reviewed By: astreet
Differential Revision: D3337513
Summary:
Text in Nodes is squashed into a single DrawCommand for drawing a
Boring or StaticLayout. Touch is handled using a TextNodeRegion subclass of
NodeRegion that knows how to identify pieces of text inside of the DrawCommand
based on spans in the text. However, we only use a TextNodeRegion on the
second call for updateNodeRegion for an RCTText. If there is only one call,
the NodeRegion will just be a normal one. This patch ensures that the
NodeRegion for an RCTText is always a TextNodeRegion, allowing for null
Layouts that are set when the DrawCommand is made.
Reviewed By: astreet
Differential Revision: D3291682
Summary:
As of D3235050, Nodes supports the optimization of removing clipped
subviews from the hierarchy. However, because Nodes supports overflow:visible,
this could cause issues when DrawCommands overflow the bounds of their parent
container. This patch fixes this by not clipping any overflowing Nodes.
Reviewed By: astreet
Differential Revision: D3235072
Summary:
RN has an optimization in which a ScrollView (or similar ViewGroups)
can ask to remove clipped subviews from the View hierarchy. This patch
implements this optimization for Nodes, but instead of adding and removing the
Views, it attaches and detaches Views instead.
Note that this patch does not handle overflow: visible. This is addressed in a
stacked patch on top of this patch (to simplify the review process).
Reviewed By: astreet
Differential Revision: D3235050
Summary:
Nodes crashed when setJSResponder was called on a virtual (non-View)
node, because a View could not be found using that react tag. The solution is
two fold - first, to figure out the View parent and pass that to
setJSResponder in addition to that of the virtual tag. Secondly, we weren't
mounting views that had animation properties (transform, for example) to
Views, which caused related code to fail.
Reviewed By: sriramramani
Differential Revision: D3301310
Summary:
Canvas.save by default saves both the matrix (for translations,
scaling, etc) and the clip (clipRect) - in most of our cases, we really only
care to save and restore the clip, not the matrix.
Reviewed By: sriramramani
Differential Revision: D3235698
Summary:
With nodes, it's possible for a touchable region to not be
explicitly mounted to a View. To work around this (and allow the region to
be the handler of the touch event), FlatViewGroup intercepts touch events
when the touch lies within any of the virtual NodeRegions.
This can sometimes be wrong - the canonical example is when touch starts
outside of a particular FlatViewGroup (so someone else, for example a
sibling) intercepts the touch event, and then the person moves over a
different FlatViewGroup, causing it to intercept the touch event when it
shouldn't. To fix this, we only allow intercepting touch events due to
NodeRegions on the down event.
Reviewed By: astreet
Differential Revision: D3160152
Summary:
By default, Nodes causes views to not be clipped, unless overflow is
explicitly set to hidden. Consequently, Nodes sets all the clipping bounds to
negative infinity, and does some extra work (saving the canvas layer,
clipping, etc) before drawing. This optimization skips the extra work when
it's not needed.
Reviewed By: sriramramani
Differential Revision: D3161268
Summary:
Initially, we used to mount nodes to Views anytime a node was
clicked. This was not useful, since we could still not handle touch when
a touch event was already dispatched. Later, a fix was pushed that
supported handling touch events for non-View NodeRegions. Part of the
intention was to remove this code, but it was forgotten.
Reviewed By: sriramramani
Differential Revision: D3160532
Summary: This allows users of the API to have greater control over handling RTL. One example is Components which needs this greater control to correctly handle RTL.
Differential Revision: D3120721