Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0c3168f150 | ||
|
40861c699e | ||
|
d8fee24778 | ||
|
5c617a5947 | ||
|
ff0a3f39d9 | ||
|
bfb4dabf0c | ||
|
58d14ee557 | ||
|
c5182c4bf5 | ||
|
132b016bae | ||
|
4785e95a0c | ||
|
be94a5ef8d | ||
|
208b70a93c | ||
|
6c3155ae3b | ||
|
32f071c2ad | ||
|
fdd1dbe3a9 | ||
|
1ca5bb694d | ||
|
b4cfaa916c | ||
|
fc6c85996e | ||
|
969f055f47 | ||
|
58328d01ef | ||
|
d90914f3dc | ||
|
3a0a86788e | ||
|
a77aa9a41e | ||
|
7217471427 | ||
|
bcc36cc1b2 | ||
|
16052085d0 | ||
|
c20f2864ab | ||
|
4185a44393 | ||
|
c79c5e3c9d | ||
|
35a9f33abb | ||
|
32f128640b | ||
|
18d19af7ec | ||
|
2ee2dd439f | ||
|
5edfb679e7 | ||
|
f45059e1e6 | ||
|
c9384762ee | ||
|
7ea50439ce | ||
|
154e67adbc | ||
|
570a193b7e | ||
|
79e294c927 | ||
|
5d75c7c4c8 | ||
|
7c688cea68 | ||
|
7640cd667f |
@@ -1,9 +1,10 @@
|
||||
[cxx]
|
||||
gtest_dep = //lib/gtest:gtest
|
||||
[android]
|
||||
target = android-23
|
||||
target = android-25
|
||||
build_tools_version = 26.0.2
|
||||
[ndk]
|
||||
ndk_version = 13.1.3345770
|
||||
ndk_version = 15.2.4203891
|
||||
compiler = clang
|
||||
app_platform = android-21
|
||||
cpu_abis = arm64, armv7, x86, x86_64
|
||||
|
@@ -12,6 +12,8 @@ compiler: clang
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- $HOME/android-sdk
|
||||
- $HOME/android-ndk
|
||||
|
||||
env:
|
||||
- TARGET=c
|
||||
@@ -73,6 +75,8 @@ before_install:
|
||||
export TERMINAL=dumb;
|
||||
source scripts/android-setup.sh && installAndroidSDK
|
||||
export ANDROID_SDK=$ANDROID_HOME
|
||||
export ANDROID_NDK_REPOSITORY=$HOME/android-ndk
|
||||
export ANDROID_NDK_HOME=$ANDROID_NDK_REPOSITORY/android-ndk-r15c
|
||||
fi
|
||||
|
||||
# JavaScript
|
||||
|
4
BUCK
4
BUCK
@@ -21,9 +21,9 @@ TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ["-std=c++11"
|
||||
cxx_library(
|
||||
name = "yoga",
|
||||
srcs = glob(["yoga/*.c"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
exported_headers = subdir_glob([("", "yoga/*.h")]),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob([("", "yoga/*.h")]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
soname = "libyogacore.$(ext)",
|
||||
tests = [":YogaTests"],
|
||||
visibility = ["PUBLIC"],
|
||||
|
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'Yoga'
|
||||
spec.version = '1.5.0'
|
||||
spec.version = '1.7.0'
|
||||
spec.license = { :type => 'BSD', :file => "LICENSE" }
|
||||
spec.homepage = 'https://facebook.github.io/yoga/'
|
||||
spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/c/'
|
||||
@@ -11,7 +11,7 @@ Pod::Spec.new do |spec|
|
||||
spec.authors = 'Facebook'
|
||||
spec.source = {
|
||||
:git => 'https://github.com/facebook/yoga.git',
|
||||
:tag => '1.5.0',
|
||||
:tag => '1.7.0',
|
||||
}
|
||||
|
||||
spec.module_name = 'yoga'
|
||||
|
@@ -1,6 +1,6 @@
|
||||
podspec = Pod::Spec.new do |spec|
|
||||
spec.name = 'YogaKit'
|
||||
spec.version = '1.5.0'
|
||||
spec.version = '1.7.0'
|
||||
spec.license = { :type => 'BSD', :file => "LICENSE" }
|
||||
spec.homepage = 'https://facebook.github.io/yoga/'
|
||||
spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/yogakit/'
|
||||
@@ -11,14 +11,14 @@ podspec = Pod::Spec.new do |spec|
|
||||
spec.authors = 'Facebook'
|
||||
spec.source = {
|
||||
:git => 'https://github.com/facebook/yoga.git',
|
||||
:tag => '1.5.0',
|
||||
:tag => '1.7.0',
|
||||
}
|
||||
|
||||
spec.platform = :ios
|
||||
spec.ios.deployment_target = '8.0'
|
||||
spec.ios.frameworks = 'UIKit'
|
||||
|
||||
spec.dependency 'Yoga', '~> 1.5'
|
||||
spec.dependency 'Yoga', '~> 1.7'
|
||||
spec.source_files = 'YogaKit/Source/*.{h,m,swift}'
|
||||
spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h'
|
||||
spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h'
|
||||
|
@@ -30,12 +30,13 @@ COMPILER_FLAGS = [
|
||||
apple_library(
|
||||
name = "YogaKit",
|
||||
srcs = glob(["Source/**/*.m"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
exported_headers = glob(["Source/**/*.h"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/UIKit.framework",
|
||||
],
|
||||
link_whole = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
yoga_dep(":yoga"),
|
||||
|
@@ -8,7 +8,7 @@
|
||||
YogaKit is available to install via [CocoaPods](https://cocoapods.org/).
|
||||
|
||||
```
|
||||
pod 'YogaKit', '~> 1.5'
|
||||
pod 'YogaKit', '~> 1.7'
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
@@ -20,6 +20,10 @@ typedef void (^YGLayoutConfigurationBlock)(YGLayout *);
|
||||
The YGLayout that is attached to this view. It is lazily created.
|
||||
*/
|
||||
@property (nonatomic, readonly, strong) YGLayout *yoga;
|
||||
/**
|
||||
Indicates whether or not Yoga is enabled
|
||||
*/
|
||||
@property (nonatomic, readonly, assign) BOOL isYogaEnabled;
|
||||
|
||||
/**
|
||||
In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend`
|
||||
|
@@ -26,6 +26,11 @@ static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey;
|
||||
return yoga;
|
||||
}
|
||||
|
||||
- (BOOL)isYogaEnabled
|
||||
{
|
||||
return objc_getAssociatedObject(self, kYGYogaAssociatedKey) != nil;
|
||||
}
|
||||
|
||||
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
|
||||
{
|
||||
if (block != nil) {
|
||||
|
@@ -361,7 +361,7 @@ static void YGAttachNodesFromViewHierachy(UIView *const view)
|
||||
|
||||
NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count];
|
||||
for (UIView *subview in view.subviews) {
|
||||
if (subview.yoga.isIncludedInLayout) {
|
||||
if (subview.yoga.isEnabled && subview.yoga.isIncludedInLayout) {
|
||||
[subviewsToInclude addObject:subview];
|
||||
}
|
||||
}
|
||||
|
@@ -4,9 +4,9 @@ PODS:
|
||||
- IGListKit/Default (2.1.0):
|
||||
- IGListKit/Diffing
|
||||
- IGListKit/Diffing (2.1.0)
|
||||
- Yoga (1.5.0)
|
||||
- YogaKit (1.5.0):
|
||||
- Yoga (~> 1.5)
|
||||
- Yoga (1.7.0)
|
||||
- YogaKit (1.7.0):
|
||||
- Yoga (~> 1.7)
|
||||
|
||||
DEPENDENCIES:
|
||||
- IGListKit (~> 2.1.0)
|
||||
|
@@ -22,7 +22,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':yoga')
|
||||
api project(':yoga')
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
|
@@ -10,6 +10,8 @@ include_defs("//YOGA_DEFS")
|
||||
cxx_binary(
|
||||
name = "benchmark",
|
||||
srcs = glob(["*.c"]),
|
||||
headers = subdir_glob([("", "*.h")]),
|
||||
header_namespace = "",
|
||||
compiler_flags = [
|
||||
"-fno-omit-frame-pointer",
|
||||
"-fexceptions",
|
||||
@@ -18,8 +20,6 @@ cxx_binary(
|
||||
"-O3",
|
||||
"-std=c11",
|
||||
],
|
||||
header_namespace = "",
|
||||
headers = subdir_glob([("", "*.h")]),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
yoga_dep(":yoga"),
|
||||
|
10
build.gradle
10
build.gradle
@@ -3,12 +3,12 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url 'https://maven.google.com/' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
|
||||
classpath 'com.nabilhachicha:android-native-dependencies:0.1'
|
||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@@ -24,8 +24,8 @@ allprojects {
|
||||
ext {
|
||||
minSdkVersion = 14
|
||||
targetSdkVersion = 25
|
||||
compileSdkVersion = 25
|
||||
buildToolsVersion = '25.0.2'
|
||||
compileSdkVersion = 26
|
||||
buildToolsVersion = '26.0.2'
|
||||
sourceCompatibilityVersion = JavaVersion.VERSION_1_7
|
||||
targetCompatibilityVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
@@ -595,12 +595,14 @@ namespace Facebook.Yoga
|
||||
Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline);
|
||||
}
|
||||
|
||||
public void CalculateLayout()
|
||||
public void CalculateLayout(
|
||||
float width = YogaConstants.Undefined,
|
||||
float height = YogaConstants.Undefined)
|
||||
{
|
||||
Native.YGNodeCalculateLayout(
|
||||
_ygNode,
|
||||
YogaConstants.Undefined,
|
||||
YogaConstants.Undefined,
|
||||
width,
|
||||
height,
|
||||
Native.YGNodeStyleGetDirection(_ygNode));
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
#if __IOS__
|
||||
using NativeView = UIKit.UIView;
|
||||
using NativeScrollView = UIKit.UIScrollView;
|
||||
#endif
|
||||
|
||||
namespace Facebook.YogaKit
|
||||
@@ -699,12 +700,12 @@ namespace Facebook.YogaKit
|
||||
{
|
||||
get
|
||||
{
|
||||
return _node.StyleAspectRatio;
|
||||
return _node.AspectRatio;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_node.StyleAspectRatio = value;
|
||||
_node.AspectRatio = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,6 +717,17 @@ namespace Facebook.YogaKit
|
||||
float width = 0;
|
||||
float height = 0;
|
||||
GetWidthHeightOfNativeView(view, out width, out height);
|
||||
if (view is NativeScrollView)
|
||||
{
|
||||
if (FlexDirection == YogaFlexDirection.Column || FlexDirection == YogaFlexDirection.ColumnReverse)
|
||||
{
|
||||
height = float.NaN;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = float.NaN;
|
||||
}
|
||||
}
|
||||
CalculateLayoutWithSize(this, width, height);
|
||||
ApplyLayoutToViewHierarchy(view);
|
||||
}
|
||||
@@ -743,9 +755,7 @@ namespace Facebook.YogaKit
|
||||
|
||||
var node = layout._node;
|
||||
|
||||
node.Width = width;
|
||||
node.Height = height;
|
||||
node.CalculateLayout();
|
||||
node.CalculateLayout(width, height);
|
||||
|
||||
return new SizeF { Width = node.LayoutWidth, Height = node.LayoutHeight };
|
||||
}
|
||||
@@ -775,14 +785,14 @@ namespace Facebook.YogaKit
|
||||
float result;
|
||||
if (measureMode == YogaMeasureMode.Exactly)
|
||||
{
|
||||
result = (float)constrainedSize;
|
||||
result = constrainedSize;
|
||||
}
|
||||
else if (measureMode == YogaMeasureMode.AtMost)
|
||||
{
|
||||
result = (float)Math.Min(constrainedSize, measuredSize);
|
||||
result = Math.Min(constrainedSize, measuredSize);
|
||||
}
|
||||
else {
|
||||
result = (float)measuredSize;
|
||||
result = measuredSize;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -820,7 +830,7 @@ namespace Facebook.YogaKit
|
||||
var subviewsToInclude = new List<NativeView>();
|
||||
foreach (var subview in view.Subviews)
|
||||
{
|
||||
if (subview.Yoga().IsIncludeInLayout)
|
||||
if (subview.Yoga().IsEnabled && subview.Yoga().IsIncludeInLayout)
|
||||
{
|
||||
subviewsToInclude.Add(subview);
|
||||
}
|
||||
@@ -856,7 +866,7 @@ namespace Facebook.YogaKit
|
||||
|
||||
static double RoundPointValue(float value)
|
||||
{
|
||||
float scale = NativePointScale;
|
||||
float scale = NativePixelScale;
|
||||
|
||||
return Math.Round(value * scale) / scale;
|
||||
}
|
||||
|
@@ -22,8 +22,6 @@
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<MtouchFastDev>true</MtouchFastDev>
|
||||
<MtouchProfiling>true</MtouchProfiling>
|
||||
<MtouchUseSGen>true</MtouchUseSGen>
|
||||
<MtouchUseRefCounting>true</MtouchUseRefCounting>
|
||||
<IOSDebuggerPort>17481</IOSDebuggerPort>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
@@ -39,8 +37,6 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<MtouchUseSGen>true</MtouchUseSGen>
|
||||
<MtouchUseRefCounting>true</MtouchUseRefCounting>
|
||||
<MtouchFloat32>true</MtouchFloat32>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
@@ -56,8 +52,6 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<MtouchUseSGen>true</MtouchUseSGen>
|
||||
<MtouchUseRefCounting>true</MtouchUseRefCounting>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
|
||||
@@ -76,8 +70,6 @@
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<MtouchFastDev>true</MtouchFastDev>
|
||||
<MtouchProfiling>true</MtouchProfiling>
|
||||
<MtouchUseSGen>true</MtouchUseSGen>
|
||||
<MtouchUseRefCounting>true</MtouchUseRefCounting>
|
||||
<MtouchFloat32>true</MtouchFloat32>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
@@ -102,6 +94,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="UnitTestAppDelegate.cs" />
|
||||
<Compile Include="YogaKitNativeTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Facebook.YogaKit.iOS\Facebook.YogaKit.iOS.csproj">
|
||||
|
51
csharp/iOS/Facebook.YogaKit.iOS.Tests/YogaKitNativeTest.cs
Normal file
51
csharp/iOS/Facebook.YogaKit.iOS.Tests/YogaKitNativeTest.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Drawing;
|
||||
using Facebook.Yoga;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using UIKit;
|
||||
using CoreGraphics;
|
||||
|
||||
namespace Facebook.YogaKit.iOS.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class YogaKitNativeTest
|
||||
{
|
||||
[Test]
|
||||
public void ScrollViewVertical()
|
||||
{
|
||||
var view = new UIScrollView() {
|
||||
Frame = new CGRect(0, 0, 100, 100),
|
||||
};
|
||||
|
||||
view.Yoga().Overflow = YogaOverflow.Scroll;
|
||||
var subview = new UIView();
|
||||
subview.Yoga().Height = 1000;
|
||||
subview.Yoga().IsEnabled = true;
|
||||
|
||||
view.AddSubview(subview);
|
||||
view.Yoga().IsEnabled = true;
|
||||
view.Yoga().ApplyLayout();
|
||||
Assert.True(view.ContentSize.Height == 1000);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NormalViewVertical()
|
||||
{
|
||||
var view = new UIView() {
|
||||
Frame = new CGRect(0,0, 100, 100),
|
||||
};
|
||||
|
||||
|
||||
var subview = new UIView();
|
||||
subview.Yoga().Height = 1000;
|
||||
subview.Yoga().Width = 2;
|
||||
subview.Yoga().IsEnabled = true;
|
||||
|
||||
view.AddSubview(subview);
|
||||
view.Yoga().IsEnabled = true;
|
||||
view.Yoga().ApplyLayout();
|
||||
Assert.True(view.Bounds.Height == 100);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -23,14 +23,21 @@ namespace Facebook.YogaKit
|
||||
height = (float)view.Bounds.Height;
|
||||
}
|
||||
|
||||
static float NativePixelScale => (float)UIScreen.MainScreen.Scale;
|
||||
static float NativePixelScale => (float)UIScreen.MainScreen.Scale;
|
||||
|
||||
|
||||
static void ApplyLayoutToNativeView(UIView view, YogaNode node)
|
||||
{
|
||||
var topLeft = new CGPoint(node.LayoutX, node.LayoutY);
|
||||
var bottomRight = new CGPoint(topLeft.X + node.LayoutWidth, topLeft.Y + node.LayoutHeight);
|
||||
view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
|
||||
if (view is UIScrollView scrollView)
|
||||
{
|
||||
scrollView.ContentSize = new CGSize(RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
|
||||
}
|
||||
}
|
||||
|
||||
bool _disposed;
|
||||
|
@@ -8,36 +8,11 @@ permalink: /docs/api/csharp/
|
||||
|
||||
### Lifecycle
|
||||
|
||||
Create a `YogaNode` via its default constructor or the static `Create()` builder method and use `Reset` if you want to pool and re-use nodes. The native memory of a `YogaNode` will automatically be freed when the node is garbage collected.
|
||||
Create a `YogaNode` via its default constructor and use `Reset` if you want to pool and re-use nodes. The native memory of a `YogaNode` will automatically be freed when the node is garbage collected.
|
||||
|
||||
```csharp
|
||||
YogaNode();
|
||||
void Reset();
|
||||
|
||||
static YogaNode Create(
|
||||
YogaDirection? styleDirection = null,
|
||||
YogaFlexDirection? flexDirection = null,
|
||||
YogaJustify? justifyContent = null,
|
||||
YogaAlign? alignContent = null,
|
||||
YogaAlign? alignItems = null,
|
||||
YogaAlign? alignSelf = null,
|
||||
YogaPositionType? positionType = null,
|
||||
YogaWrap? wrap = null,
|
||||
YogaOverflow? overflow = null,
|
||||
float? flex = null,
|
||||
float? flexGrow = null,
|
||||
float? flexShrink = null,
|
||||
float? flexBasis = null,
|
||||
Spacing position = null,
|
||||
Spacing margin = null,
|
||||
Spacing padding = null,
|
||||
Spacing border = null,
|
||||
float? Width = null,
|
||||
float? Height = null,
|
||||
float? MaxWidth = null,
|
||||
float? MaxHeight = null,
|
||||
float? MinWidth = null,
|
||||
float? MinHeight = null);
|
||||
```
|
||||
|
||||
### Children
|
||||
@@ -95,6 +70,9 @@ enum YogaAlign
|
||||
Center,
|
||||
FlexEnd,
|
||||
Stretch,
|
||||
Baseline,
|
||||
SpaceBetween,
|
||||
SpaceAround
|
||||
}
|
||||
|
||||
YogaAlign AlignItems {get, set};
|
||||
@@ -113,6 +91,7 @@ enum YogaWrap
|
||||
{
|
||||
NoWrap,
|
||||
Wrap,
|
||||
WrapReverse
|
||||
}
|
||||
|
||||
YogaWrap Wrap {get, set};
|
||||
@@ -197,18 +176,13 @@ enum YogaMeasureMode
|
||||
AtMost,
|
||||
}
|
||||
|
||||
public delegate long MeasureFunction(
|
||||
public delegate YogaSize MeasureFunction(
|
||||
YogaNode node,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode);
|
||||
|
||||
class MeasureOutput
|
||||
{
|
||||
public static long Make(int width, int height);
|
||||
}
|
||||
|
||||
void SetMeasureFunction(MeasureFunction measureFunction);
|
||||
bool IsMeasureDefined();
|
||||
|
||||
|
@@ -9,7 +9,7 @@ permalink: /docs/api/yogakit/
|
||||
|
||||
YogaKit is a Objective-C (and Swift-compatible) wrapper for Yoga. It allows iOS Developers to manage the layout of their views using the power of Yoga.
|
||||
|
||||
Layout configuration is done via the [YGLayout](https://github.com/facebook/yoga/blob/master/YogaKit/YGLayout.h) object. YogaKit exposes `YGLayout` via a [category](https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html) on [UIView](https://developer.apple.com/reference/uikit/uiview).
|
||||
Layout configuration is done via the [YGLayout](https://github.com/facebook/yoga/blob/master/YogaKit/Source/YGLayout.h) object. YogaKit exposes `YGLayout` via a [category](https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html) on [UIView](https://developer.apple.com/reference/uikit/uiview).
|
||||
|
||||
### Lifecycle
|
||||
|
||||
|
@@ -124,18 +124,20 @@ root.addChildAt(image, 1);
|
||||
<div class="blockContent">
|
||||
<div markdown="1" style="width: 700px; max-width: 100%;">
|
||||
```csharp
|
||||
YogaNode root = YogaNode.Create(
|
||||
width: 500,
|
||||
height: 300,
|
||||
);
|
||||
YogaNode root = new YogaNode {
|
||||
Width = 500,
|
||||
Height = 300
|
||||
};
|
||||
|
||||
YogaNode image = YogaNode.Create(flexGrow: 1);
|
||||
YogaNode image = new YogaNode {
|
||||
FlexGrow = 1
|
||||
};
|
||||
|
||||
YogaNode text = YogaNode.Create(
|
||||
width: 300,
|
||||
height: 25,
|
||||
margin: new Spacing(left: 20, top: 20, right: 20, bottom: 20),
|
||||
);
|
||||
YogaNode text = new YogaNode {
|
||||
Width = 300,
|
||||
Height = 25,
|
||||
Margin = 20
|
||||
};
|
||||
|
||||
root.Insert(image, 0);
|
||||
root.Insert(text, 1);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
||||
VERSION_NAME=1.5.2-SNAPSHOT
|
||||
VERSION_NAME=1.7.0
|
||||
POM_URL=https://github.com/facebook/yoga
|
||||
POM_SCM_URL=https://github.com/facebook/yoga.git
|
||||
POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-bin.zip
|
||||
|
11
java/BUCK
11
java/BUCK
@@ -10,6 +10,7 @@ include_defs("//YOGA_DEFS")
|
||||
cxx_library(
|
||||
name = "jni",
|
||||
srcs = glob(["jni/*.cpp"]),
|
||||
header_namespace = "",
|
||||
compiler_flags = [
|
||||
"-fno-omit-frame-pointer",
|
||||
"-fexceptions",
|
||||
@@ -19,7 +20,6 @@ cxx_library(
|
||||
"-O3",
|
||||
"-std=c++11",
|
||||
],
|
||||
header_namespace = "",
|
||||
soname = "libyoga.$(ext)",
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
@@ -32,6 +32,7 @@ cxx_library(
|
||||
java_library(
|
||||
name = "java",
|
||||
srcs = glob(["com/facebook/yoga/*.java"]),
|
||||
required_for_source_only_abi = True,
|
||||
source = "1.7",
|
||||
target = "1.7",
|
||||
tests = [
|
||||
@@ -58,3 +59,11 @@ java_test(
|
||||
JUNIT_TARGET,
|
||||
],
|
||||
)
|
||||
|
||||
java_binary(
|
||||
name = "yoga",
|
||||
deps = [
|
||||
":java",
|
||||
FBJNI_JAVA_TARGET,
|
||||
],
|
||||
)
|
||||
|
@@ -50,10 +50,10 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
||||
compile 'com.facebook.soloader:soloader:0.2.0'
|
||||
provided project(':yoga:proguard-annotations')
|
||||
testCompile 'junit:junit:4.12'
|
||||
compileOnly 'com.google.code.findbugs:jsr305:3.0.1'
|
||||
compileOnly project(':yoga:proguard-annotations')
|
||||
implementation 'com.facebook.soloader:soloader:0.2.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
|
@@ -422,9 +422,7 @@ void jni_YGConfigSetLogger(alias_ref<jobject>, jlong nativePointer, alias_ref<jo
|
||||
|
||||
auto context = YGConfigGetContext(config);
|
||||
if (context) {
|
||||
auto jlogger = reinterpret_cast<global_ref<jobject> *>(context);
|
||||
jlogger->releaseAlias();
|
||||
delete jlogger;
|
||||
delete reinterpret_cast<global_ref<jobject> *>(context);
|
||||
}
|
||||
|
||||
if (logger) {
|
||||
|
43
java/tests/com/facebook/yoga/YogaLoggerTest.java
Normal file
43
java/tests/com/facebook/yoga/YogaLoggerTest.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga;
|
||||
|
||||
import org.junit.Test;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class YogaLoggerTest {
|
||||
@Test
|
||||
public void testLoggerLeak() throws Exception {
|
||||
final YogaConfig config = new YogaConfig();
|
||||
YogaLogger logger = new YogaLogger() {
|
||||
@Override
|
||||
public void log(YogaNode yogaNode, YogaLogLevel level, String message) {
|
||||
}
|
||||
};
|
||||
config.setLogger(logger);
|
||||
config.setLogger(null);
|
||||
WeakReference<Object> ref = new WeakReference<Object>(logger);
|
||||
// noinspection UnusedAssignment
|
||||
logger = null;
|
||||
// try and free for the next 5 seconds, usually it works after the
|
||||
// first GC attempt.
|
||||
for (int i=0; i < 50; i++) {
|
||||
System.gc();
|
||||
if (ref.get() == null) {
|
||||
// free successfully
|
||||
return;
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
fail("YogaLogger leaked");
|
||||
}
|
||||
}
|
11
javascript/.babelrc
Normal file
11
javascript/.babelrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"replace-require",
|
||||
{
|
||||
"fs": "{}",
|
||||
"path": "{}"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "yoga-layout",
|
||||
"version": "1.5.0",
|
||||
"version": "1.7.0",
|
||||
"description": "Yoga is a cross-platform layout engine enabling maximum collaboration within your team by implementing an API many designers are familiar with, and opening it up to developers across different platforms.",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/yoga.git"
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/yoga.git"
|
||||
},
|
||||
|
||||
"main": "./sources/entry-node",
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
"build:node": "npm -- run copy-sources && npm -- run node-gyp configure build",
|
||||
"build:browser": "npm -- run copy-sources && npm -- run node-gyp configure build --asmjs=1",
|
||||
"postbuild:browser": "babel build/Release/nbind.js --out-file build/Release/nbind.js",
|
||||
"build:standalone": "webpack",
|
||||
"build:all": "npm -- run build:node && npm -- run build:browser && npm -- run build:standalone",
|
||||
"build": "cross-env \"npm --if-present -- run build:$npm_package_config_platform\"",
|
||||
@@ -54,6 +55,9 @@
|
||||
|
||||
"devDependencies": {
|
||||
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-core": "^6.25.0",
|
||||
"babel-plugin-replace-require": "^0.0.4",
|
||||
"cross-env": "^4.0.0",
|
||||
"mocha": "^3.2.0",
|
||||
"webpack": "^2.2.0-rc.2"
|
||||
|
@@ -152,6 +152,159 @@ aws4@^1.2.1:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755"
|
||||
|
||||
babel-cli@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.24.1.tgz#207cd705bba61489b2ea41b5312341cf6aca2283"
|
||||
dependencies:
|
||||
babel-core "^6.24.1"
|
||||
babel-polyfill "^6.23.0"
|
||||
babel-register "^6.24.1"
|
||||
babel-runtime "^6.22.0"
|
||||
commander "^2.8.1"
|
||||
convert-source-map "^1.1.0"
|
||||
fs-readdir-recursive "^1.0.0"
|
||||
glob "^7.0.0"
|
||||
lodash "^4.2.0"
|
||||
output-file-sync "^1.1.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
slash "^1.0.0"
|
||||
source-map "^0.5.0"
|
||||
v8flags "^2.0.10"
|
||||
optionalDependencies:
|
||||
chokidar "^1.6.1"
|
||||
|
||||
babel-code-frame@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
|
||||
dependencies:
|
||||
chalk "^1.1.0"
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
babel-core@^6.24.1, babel-core@^6.25.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729"
|
||||
dependencies:
|
||||
babel-code-frame "^6.22.0"
|
||||
babel-generator "^6.25.0"
|
||||
babel-helpers "^6.24.1"
|
||||
babel-messages "^6.23.0"
|
||||
babel-register "^6.24.1"
|
||||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.25.0"
|
||||
babel-traverse "^6.25.0"
|
||||
babel-types "^6.25.0"
|
||||
babylon "^6.17.2"
|
||||
convert-source-map "^1.1.0"
|
||||
debug "^2.1.1"
|
||||
json5 "^0.5.0"
|
||||
lodash "^4.2.0"
|
||||
minimatch "^3.0.2"
|
||||
path-is-absolute "^1.0.0"
|
||||
private "^0.1.6"
|
||||
slash "^1.0.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
babel-generator@^6.25.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc"
|
||||
dependencies:
|
||||
babel-messages "^6.23.0"
|
||||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.25.0"
|
||||
detect-indent "^4.0.0"
|
||||
jsesc "^1.3.0"
|
||||
lodash "^4.2.0"
|
||||
source-map "^0.5.0"
|
||||
trim-right "^1.0.1"
|
||||
|
||||
babel-helpers@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.24.1"
|
||||
|
||||
babel-messages@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-discard-module-references@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-discard-module-references/-/babel-plugin-discard-module-references-1.1.2.tgz#898007cbeb472cef76ef11e1af485b41d4241747"
|
||||
|
||||
babel-plugin-replace-require@^0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-replace-require/-/babel-plugin-replace-require-0.0.4.tgz#2afe99c8cfd1a9faf5fa2a807bdb35c30a4970f8"
|
||||
dependencies:
|
||||
babylon "^6.14.1"
|
||||
|
||||
babel-polyfill@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.10.0"
|
||||
|
||||
babel-register@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f"
|
||||
dependencies:
|
||||
babel-core "^6.24.1"
|
||||
babel-runtime "^6.22.0"
|
||||
core-js "^2.4.0"
|
||||
home-or-tmp "^2.0.0"
|
||||
lodash "^4.2.0"
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.2"
|
||||
|
||||
babel-runtime@^6.22.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.10.0"
|
||||
|
||||
babel-template@^6.24.1, babel-template@^6.25.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-traverse "^6.25.0"
|
||||
babel-types "^6.25.0"
|
||||
babylon "^6.17.2"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-traverse@^6.25.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1"
|
||||
dependencies:
|
||||
babel-code-frame "^6.22.0"
|
||||
babel-messages "^6.23.0"
|
||||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.25.0"
|
||||
babylon "^6.17.2"
|
||||
debug "^2.2.0"
|
||||
globals "^9.0.0"
|
||||
invariant "^2.2.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-types@^6.25.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.2.0"
|
||||
to-fast-properties "^1.0.1"
|
||||
|
||||
babylon@^6.14.1, babylon@^6.17.2:
|
||||
version "6.17.4"
|
||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a"
|
||||
|
||||
balanced-match@^0.4.1:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
@@ -311,7 +464,7 @@ center-align@^0.1.1:
|
||||
align-text "^0.1.3"
|
||||
lazy-cache "^1.0.3"
|
||||
|
||||
chalk@^1.1.1:
|
||||
chalk@^1.1.0, chalk@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
dependencies:
|
||||
@@ -321,7 +474,7 @@ chalk@^1.1.1:
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chokidar@^1.4.3:
|
||||
chokidar@^1.4.3, chokidar@^1.6.1:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
|
||||
dependencies:
|
||||
@@ -372,7 +525,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@2.9.0, commander@^2.9.0, commander@~2.9.0:
|
||||
commander@2.9.0, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
||||
dependencies:
|
||||
@@ -396,6 +549,14 @@ constants-browserify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
||||
|
||||
convert-source-map@^1.1.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
|
||||
|
||||
core-js@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@@ -423,6 +584,21 @@ create-hmac@^1.1.0, create-hmac@^1.1.2:
|
||||
create-hash "^1.1.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
cross-env@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-4.0.0.tgz#16083862d08275a4628b0b243b121bedaa55dd80"
|
||||
dependencies:
|
||||
cross-spawn "^5.1.0"
|
||||
is-windows "^1.0.0"
|
||||
|
||||
cross-spawn@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
|
||||
dependencies:
|
||||
lru-cache "^4.0.1"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cryptiles@2.x.x:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
|
||||
@@ -460,7 +636,7 @@ date-now@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
||||
|
||||
debug@2.2.0, debug@^2.2.0, debug@~2.2.0:
|
||||
debug@2.2.0, debug@^2.1.1, debug@^2.2.0, debug@~2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
|
||||
dependencies:
|
||||
@@ -489,6 +665,12 @@ des.js@^1.0.0:
|
||||
inherits "^2.0.1"
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
detect-indent@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
|
||||
dependencies:
|
||||
repeating "^2.0.0"
|
||||
|
||||
diff@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf"
|
||||
@@ -524,9 +706,9 @@ emojis-list@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
|
||||
|
||||
emscripten-library-decorator@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/emscripten-library-decorator/-/emscripten-library-decorator-0.2.0.tgz#54f08075a9f82d7091729fd1daa97aa0e025d4f3"
|
||||
emscripten-library-decorator@~0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emscripten-library-decorator/-/emscripten-library-decorator-0.2.2.tgz#d035f023e2a84c68305cc842cdeea38e67683c40"
|
||||
|
||||
enhanced-resolve@^3.0.0:
|
||||
version "3.0.2"
|
||||
@@ -575,6 +757,10 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
events@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
|
||||
@@ -654,6 +840,10 @@ form-data@~2.1.1:
|
||||
combined-stream "^1.0.5"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs-readdir-recursive@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
@@ -754,7 +944,7 @@ glob@7.0.5:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.3, glob@^7.0.5:
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
|
||||
dependencies:
|
||||
@@ -765,7 +955,11 @@ glob@^7.0.3, glob@^7.0.5:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
globals@^9.0.0:
|
||||
version "9.18.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
||||
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.4:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
|
||||
@@ -823,6 +1017,13 @@ hoek@2.x.x:
|
||||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
|
||||
home-or-tmp@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
os-tmpdir "^1.0.1"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b"
|
||||
@@ -870,6 +1071,12 @@ interpret@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c"
|
||||
|
||||
invariant@^2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
invert-kv@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
|
||||
@@ -912,6 +1119,12 @@ is-extglob@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
|
||||
|
||||
is-finite@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-fullwidth-code-point@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
||||
@@ -959,6 +1172,10 @@ is-utf8@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
|
||||
is-windows@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
|
||||
|
||||
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
@@ -983,10 +1200,18 @@ jodid25519@^1.0.0:
|
||||
dependencies:
|
||||
jsbn "~0.1.0"
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd"
|
||||
|
||||
jsesc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
|
||||
|
||||
json-loader@^0.5.4:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de"
|
||||
@@ -1115,7 +1340,7 @@ lodash.keys@^3.0.0:
|
||||
lodash.isarguments "^3.0.0"
|
||||
lodash.isarray "^3.0.0"
|
||||
|
||||
lodash@^4.14.0, lodash@^4.3.0:
|
||||
lodash@^4.14.0, lodash@^4.2.0, lodash@^4.3.0:
|
||||
version "4.17.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.3.tgz#557ed7d2a9438cac5fd5a43043ca60cb455e01f7"
|
||||
|
||||
@@ -1123,6 +1348,19 @@ longest@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
lru-cache@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
|
||||
dependencies:
|
||||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
memory-fs@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
||||
@@ -1190,7 +1428,7 @@ minimist@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
|
||||
mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
@@ -1216,17 +1454,17 @@ ms@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
|
||||
|
||||
nan@^2.3.0, nan@^2.4.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8"
|
||||
nan@^2.3.0, nan@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
|
||||
|
||||
nbind@arcanis/nbind:
|
||||
version "0.3.7"
|
||||
resolved "https://codeload.github.com/arcanis/nbind/tar.gz/26eae81cbec9b697a25f20c48630e7a6b4275498"
|
||||
nbind@^0.3.8:
|
||||
version "0.3.12"
|
||||
resolved "https://registry.yarnpkg.com/nbind/-/nbind-0.3.12.tgz#5b022d45950c1d664b360b54e6c29fa2fa5b8a59"
|
||||
dependencies:
|
||||
emscripten-library-decorator "~0.2.0"
|
||||
emscripten-library-decorator "~0.2.2"
|
||||
mkdirp "~0.5.1"
|
||||
nan "^2.4.0"
|
||||
nan "^2.6.2"
|
||||
|
||||
node-gyp@^3.4.0:
|
||||
version "3.4.0"
|
||||
@@ -1371,7 +1609,7 @@ os-locale@^1.4.0:
|
||||
dependencies:
|
||||
lcid "^1.0.0"
|
||||
|
||||
os-tmpdir@^1.0.0:
|
||||
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
||||
@@ -1382,6 +1620,14 @@ osenv@0:
|
||||
os-homedir "^1.0.0"
|
||||
os-tmpdir "^1.0.0"
|
||||
|
||||
output-file-sync@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.4"
|
||||
mkdirp "^0.5.1"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
pako@~0.2.0:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
|
||||
@@ -1463,6 +1709,10 @@ preserve@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||
|
||||
private@^0.1.6:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
@@ -1475,6 +1725,10 @@ prr@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
|
||||
|
||||
pseudomap@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
||||
|
||||
public-encrypt@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
|
||||
@@ -1573,6 +1827,10 @@ readdirp@^2.0.0:
|
||||
readable-stream "^2.0.2"
|
||||
set-immediate-shim "^1.0.1"
|
||||
|
||||
regenerator-runtime@^0.10.0:
|
||||
version "0.10.5"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
|
||||
|
||||
regex-cache@^0.4.2:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
|
||||
@@ -1588,6 +1846,12 @@ repeat-string@^1.5.2:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||
|
||||
repeating@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
|
||||
dependencies:
|
||||
is-finite "^1.0.0"
|
||||
|
||||
request@2, request@^2.79.0:
|
||||
version "2.79.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
|
||||
@@ -1663,10 +1927,24 @@ sha.js@^2.3.6:
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
||||
slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
||||
sntp@1.x.x:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
|
||||
@@ -1677,7 +1955,13 @@ source-list-map@~0.1.0:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.7.tgz#d4b5ce2a46535c72c7e8527c71a77d250618172e"
|
||||
|
||||
source-map@^0.5.3, source-map@~0.5.1, source-map@~0.5.3:
|
||||
source-map-support@^0.4.2:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
|
||||
@@ -1808,12 +2092,20 @@ to-arraybuffer@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||
|
||||
to-fast-properties@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
|
||||
|
||||
tough-cookie@~2.3.0:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
trim-right@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
@@ -1850,6 +2142,10 @@ url@^0.11.0:
|
||||
punycode "1.3.2"
|
||||
querystring "0.2.0"
|
||||
|
||||
user-home@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
@@ -1864,6 +2160,12 @@ uuid@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
|
||||
|
||||
v8flags@^2.0.10:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
|
||||
dependencies:
|
||||
user-home "^1.1.1"
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
|
||||
@@ -1928,7 +2230,7 @@ which-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
|
||||
|
||||
which@1:
|
||||
which@1, which@^1.2.9:
|
||||
version "1.2.12"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192"
|
||||
dependencies:
|
||||
@@ -1971,6 +2273,10 @@ y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
|
||||
yallist@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
||||
|
||||
yargs-parser@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.0.tgz#6ced869cd05a3dca6a1eaee38b68aeed4b0b4101"
|
||||
|
@@ -22,6 +22,8 @@ prebuilt_cxx_library(
|
||||
cxx_library(
|
||||
name = "fbjni",
|
||||
srcs = glob(["src/main/cpp/**/*.cpp"]),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob([("src/main/cpp/include", "**/*.h")]),
|
||||
compiler_flags = [
|
||||
"-DLOG_TAG=\"libfb\"",
|
||||
"-DDISABLE_CPUCAP",
|
||||
@@ -35,8 +37,6 @@ cxx_library(
|
||||
"-Wno-unused-parameter",
|
||||
"-std=c++11",
|
||||
],
|
||||
exported_headers = subdir_glob([("src/main/cpp/include", "**/*.h")]),
|
||||
header_namespace = "",
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":ndklog",
|
||||
|
@@ -26,8 +26,8 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.facebook.soloader:soloader:0.2.0'
|
||||
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
||||
compile project(':yoga:proguard-annotations')
|
||||
implementation 'com.facebook.soloader:soloader:0.2.0'
|
||||
compileOnly 'com.google.code.findbugs:jsr305:3.0.1'
|
||||
compileOnly project(':yoga:proguard-annotations')
|
||||
}
|
||||
}
|
||||
|
@@ -15,13 +15,13 @@ COMPILER_FLAGS = [
|
||||
cxx_library(
|
||||
name = "gtest",
|
||||
srcs = glob(["googletest/googletest/src/*.cc"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob([
|
||||
("googletest/googletest/include", "**/*.h"),
|
||||
("googletest/googletest", "src/*.h"),
|
||||
("googletest/googletest", "src/*.cc"),
|
||||
]),
|
||||
header_namespace = "",
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
visibility = YOGA_ROOTS,
|
||||
deps = [],
|
||||
)
|
||||
|
@@ -7,11 +7,11 @@
|
||||
|
||||
cxx_library(
|
||||
name = "jni",
|
||||
header_namespace = "",
|
||||
exported_headers = [
|
||||
"jni.h",
|
||||
"real/jni.h",
|
||||
],
|
||||
force_static = True,
|
||||
header_namespace = "",
|
||||
visibility = ["PUBLIC"],
|
||||
)
|
||||
|
@@ -1,8 +1,9 @@
|
||||
function download() {
|
||||
echo "Downloading '$1' to '$2' ..."
|
||||
if hash curl 2>/dev/null; then
|
||||
curl -L -o $2 $1
|
||||
curl --retry 10 -L -o "$2" "$1"
|
||||
elif hash wget 2>/dev/null; then
|
||||
wget -O $2 $1
|
||||
wget -O "$2" "$1"
|
||||
else
|
||||
echo >&2 "No supported download tool installed. Please get either wget or curl."
|
||||
exit
|
||||
@@ -17,21 +18,32 @@ function installsdk() {
|
||||
PROXY_ARGS="--proxy=http --proxy_host=$PROXY_HOST --proxy_port=$PROXY_PORT"
|
||||
fi
|
||||
|
||||
yes | $ANDROID_HOME/tools/bin/sdkmanager $PROXY_ARGS $@
|
||||
yes | "$ANDROID_HOME/tools/bin/sdkmanager" $PROXY_ARGS $@
|
||||
}
|
||||
|
||||
function installAndroidSDK {
|
||||
TMP=/tmp/sdk$$.zip
|
||||
download 'https://dl.google.com/android/repository/tools_r25.2.3-linux.zip' $TMP
|
||||
unzip -d $HOME/android-sdk $TMP
|
||||
rm $TMP
|
||||
|
||||
export ANDROID_HOME=$HOME/android-sdk
|
||||
export ANDROID_NDK_REPOSITORY=$HOME/android-ndk
|
||||
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$PATH"
|
||||
|
||||
mkdir -p $ANDROID_HOME/licenses/
|
||||
echo > $ANDROID_HOME/licenses/android-sdk-license
|
||||
echo -n 8933bad161af4178b1185d1a37fbf41ea5269c55 > $ANDROID_HOME/licenses/android-sdk-license
|
||||
if [[ ! -f "$ANDROID_HOME/tools/bin/sdkmanager" ]]; then
|
||||
TMP=/tmp/sdk$$.zip
|
||||
download 'https://dl.google.com/android/repository/sdk-tools-darwin-3859397.zip' $TMP
|
||||
unzip -qod "$ANDROID_HOME" "$TMP"
|
||||
rm $TMP
|
||||
fi
|
||||
|
||||
installsdk 'build-tools;23.0.2' 'build-tools;25.0.2' 'build-tools;25.0.1' 'platforms;android-23' 'platforms;android-25' 'ndk-bundle' 'extras;android;m2repository'
|
||||
if [[ ! -d "$ANDROID_NDK_REPOSITORY/android-ndk-r15c" ]]; then
|
||||
TMP=/tmp/ndk$$.zip
|
||||
mkdir -p "$ANDROID_NDK_REPOSITORY"
|
||||
download 'https://dl.google.com/android/repository/android-ndk-r15c-darwin-x86_64.zip' $TMP
|
||||
unzip -qod "$ANDROID_NDK_REPOSITORY" "$TMP"
|
||||
rm $TMP
|
||||
fi
|
||||
|
||||
mkdir -p "$ANDROID_HOME/licenses/"
|
||||
echo > "$ANDROID_HOME/licenses/android-sdk-license"
|
||||
echo -n d56f5187479451eabf01fb78af6dfcb131a6481e >> "$ANDROID_HOME/licenses/android-sdk-license"
|
||||
|
||||
installsdk 'build-tools;26.0.2' 'platform-tools' 'platforms;android-23' 'platforms;android-25' 'extras;android;m2repository'
|
||||
}
|
||||
|
@@ -171,6 +171,38 @@ TEST(YogaTest, aspect_ratio_flex_shrink) {
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, aspect_ratio_flex_shrink_2) {
|
||||
const YGNodeRef root = YGNodeNew();
|
||||
YGNodeStyleSetWidth(root, 100);
|
||||
YGNodeStyleSetHeight(root, 100);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNew();
|
||||
YGNodeStyleSetHeightPercent(root_child0, 100);
|
||||
YGNodeStyleSetFlexShrink(root_child0, 1);
|
||||
YGNodeStyleSetAspectRatio(root_child0, 1);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNew();
|
||||
YGNodeStyleSetHeightPercent(root_child1, 100);
|
||||
YGNodeStyleSetFlexShrink(root_child1, 1);
|
||||
YGNodeStyleSetAspectRatio(root_child1, 1);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, aspect_ratio_basis) {
|
||||
const YGNodeRef root = YGNodeNew();
|
||||
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
|
||||
@@ -562,8 +594,8 @@ TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) {
|
||||
|
||||
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(200, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
@@ -584,8 +616,8 @@ TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) {
|
||||
|
||||
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||
ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
@@ -747,3 +779,96 @@ TEST(YogaTest, aspect_ratio_defined_cross_with_margin) {
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, aspect_ratio_should_prefer_explicit_height) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetUseWebDefaults(config, true);
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumn);
|
||||
YGNodeStyleSetHeight(root_child0_child0, 100);
|
||||
YGNodeStyleSetAspectRatio(root_child0_child0, 2);
|
||||
YGNodeInsertChild(root_child0, root_child0_child0, 0);
|
||||
|
||||
YGNodeCalculateLayout(root, 100, 200, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_EQ(200, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, aspect_ratio_should_prefer_explicit_width) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetUseWebDefaults(config, true);
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow);
|
||||
YGNodeStyleSetWidth(root_child0_child0, 100);
|
||||
YGNodeStyleSetAspectRatio(root_child0_child0, 0.5);
|
||||
YGNodeInsertChild(root_child0, root_child0_child0, 0);
|
||||
|
||||
YGNodeCalculateLayout(root, 200, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(200, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0));
|
||||
ASSERT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
||||
TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetUseWebDefaults(config, true);
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn);
|
||||
YGNodeStyleSetAspectRatio(root_child0, 2);
|
||||
YGNodeStyleSetFlexGrow(root_child0, 1);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetAspectRatio(root_child0_child0, 4);
|
||||
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
|
||||
YGNodeInsertChild(root_child0, root_child0_child0, 0);
|
||||
|
||||
YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0));
|
||||
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
|
@@ -80,6 +80,30 @@ TEST_F(YogaTest_HadOverflowTests, no_overflow_no_wrap_and_flex_children) {
|
||||
ASSERT_FALSE(YGNodeLayoutGetHadOverflow(root));
|
||||
}
|
||||
|
||||
TEST_F(YogaTest_HadOverflowTests, hadOverflow_gets_reset_if_not_logger_valid) {
|
||||
const YGNodeRef child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(child0, 80);
|
||||
YGNodeStyleSetHeight(child0, 40);
|
||||
YGNodeStyleSetMargin(child0, YGEdgeTop, 10);
|
||||
YGNodeStyleSetMargin(child0, YGEdgeBottom, 10);
|
||||
YGNodeInsertChild(root, child0, 0);
|
||||
const YGNodeRef child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(child1, 80);
|
||||
YGNodeStyleSetHeight(child1, 40);
|
||||
YGNodeStyleSetMargin(child1, YGEdgeBottom, 5);
|
||||
YGNodeInsertChild(root, child1, 1);
|
||||
|
||||
YGNodeCalculateLayout(root, 200, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_TRUE(YGNodeLayoutGetHadOverflow(root));
|
||||
|
||||
YGNodeStyleSetFlexShrink(child1, 1);
|
||||
|
||||
YGNodeCalculateLayout(root, 200, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_FALSE(YGNodeLayoutGetHadOverflow(root));
|
||||
}
|
||||
|
||||
TEST_F(YogaTest_HadOverflowTests, spacing_overflow_in_nested_nodes) {
|
||||
const YGNodeRef child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(child0, 80);
|
||||
|
55
tests/YGInfiniteHeightTest.cpp
Normal file
55
tests/YGInfiniteHeightTest.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
// This test isn't correct from the Flexbox standard standpoint,
|
||||
// because percentages are calculated with parent constraints.
|
||||
// However, we need to make sure we fail gracefully in this case, not returning NaN
|
||||
TEST(YogaTest, percent_absolute_position_infinite_height) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
YGNodeStyleSetWidth(root, 300);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root_child0, 300);
|
||||
YGNodeStyleSetHeight(root_child0, 300);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPositionPercent(root_child1, YGEdgeLeft, 20);
|
||||
YGNodeStyleSetPositionPercent(root_child1, YGEdgeTop, 20);
|
||||
YGNodeStyleSetWidthPercent(root_child1, 20);
|
||||
YGNodeStyleSetHeightPercent(root_child1, 20);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
251
tests/YGPersistenceTest.cpp
Normal file
251
tests/YGPersistenceTest.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
// @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
TEST(YogaTest, cloning_shared_root) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root, 100);
|
||||
YGNodeStyleSetHeight(root, 100);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexGrow(root_child0, 1);
|
||||
YGNodeStyleSetFlexBasis(root_child0, 50);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexGrow(root_child1, 1);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
const YGNodeRef root2 = YGNodeClone(root);
|
||||
YGNodeStyleSetWidth(root2, 100);
|
||||
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root2));
|
||||
// The children should have referential equality at this point.
|
||||
ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0));
|
||||
ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1));
|
||||
|
||||
YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root2));
|
||||
// Relayout with no changed input should result in referential equality.
|
||||
ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0));
|
||||
ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1));
|
||||
|
||||
YGNodeStyleSetWidth(root2, 150);
|
||||
YGNodeStyleSetHeight(root2, 200);
|
||||
YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root2));
|
||||
// Relayout with changed input should result in cloned children.
|
||||
const YGNodeRef root2_child0 = YGNodeGetChild(root2, 0);
|
||||
const YGNodeRef root2_child1 = YGNodeGetChild(root2, 1);
|
||||
ASSERT_NE(root_child0, root2_child0);
|
||||
ASSERT_NE(root_child1, root2_child1);
|
||||
|
||||
// Everything in the root should remain unchanged.
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
// The new root now has new layout.
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2));
|
||||
ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2));
|
||||
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root2));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2_child0));
|
||||
ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child0));
|
||||
ASSERT_FLOAT_EQ(125, YGNodeLayoutGetHeight(root2_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child1));
|
||||
ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root2_child1));
|
||||
ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child1));
|
||||
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root2_child1));
|
||||
|
||||
YGNodeFreeRecursive(root2);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
||||
|
||||
TEST(YogaTest, mutating_children_of_a_clone_clones) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
ASSERT_EQ(0, YGNodeGetChildCount(root));
|
||||
|
||||
const YGNodeRef root2 = YGNodeClone(root);
|
||||
ASSERT_EQ(0, YGNodeGetChildCount(root2));
|
||||
|
||||
const YGNodeRef root2_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeInsertChild(root2, root2_child0, 0);
|
||||
|
||||
ASSERT_EQ(0, YGNodeGetChildCount(root));
|
||||
ASSERT_EQ(1, YGNodeGetChildCount(root2));
|
||||
|
||||
const YGNodeRef root3 = YGNodeClone(root2);
|
||||
ASSERT_EQ(1, YGNodeGetChildCount(root2));
|
||||
ASSERT_EQ(1, YGNodeGetChildCount(root3));
|
||||
ASSERT_EQ(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0));
|
||||
|
||||
const YGNodeRef root3_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeInsertChild(root3, root3_child1, 1);
|
||||
ASSERT_EQ(1, YGNodeGetChildCount(root2));
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root3));
|
||||
ASSERT_EQ(root3_child1, YGNodeGetChild(root3, 1));
|
||||
ASSERT_NE(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0));
|
||||
|
||||
const YGNodeRef root4 = YGNodeClone(root3);
|
||||
ASSERT_EQ(root3_child1, YGNodeGetChild(root4, 1));
|
||||
|
||||
YGNodeRemoveChild(root4, root3_child1);
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root3));
|
||||
ASSERT_EQ(1, YGNodeGetChildCount(root4));
|
||||
ASSERT_NE(YGNodeGetChild(root3, 0), YGNodeGetChild(root4, 0));
|
||||
|
||||
YGNodeFreeRecursive(root4);
|
||||
YGNodeFreeRecursive(root3);
|
||||
YGNodeFreeRecursive(root2);
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
||||
|
||||
TEST(YogaTest, cloning_two_levels) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root, 100);
|
||||
YGNodeStyleSetHeight(root, 100);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexGrow(root_child0, 1);
|
||||
YGNodeStyleSetFlexBasis(root_child0, 15);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexGrow(root_child1, 1);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
|
||||
const YGNodeRef root_child1_0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexBasis(root_child1_0, 10);
|
||||
YGNodeStyleSetFlexGrow(root_child1_0, 1);
|
||||
YGNodeInsertChild(root_child1, root_child1_0, 0);
|
||||
|
||||
const YGNodeRef root_child1_1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexBasis(root_child1_1, 25);
|
||||
YGNodeInsertChild(root_child1, root_child1_1, 1);
|
||||
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0));
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1));
|
||||
ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0));
|
||||
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1));
|
||||
|
||||
const YGNodeRef root2_child0 = YGNodeClone(root_child0);
|
||||
const YGNodeRef root2_child1 = YGNodeClone(root_child1);
|
||||
const YGNodeRef root2 = YGNodeClone(root);
|
||||
|
||||
YGNodeStyleSetFlexGrow(root2_child0, 0);
|
||||
YGNodeStyleSetFlexBasis(root2_child0, 40);
|
||||
|
||||
YGNodeRemoveAllChildren(root2);
|
||||
YGNodeInsertChild(root2, root2_child0, 0);
|
||||
YGNodeInsertChild(root2, root2_child1, 1);
|
||||
ASSERT_EQ(2, YGNodeGetChildCount(root2));
|
||||
|
||||
YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
// Original root is unchanged
|
||||
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0));
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1));
|
||||
ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0));
|
||||
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1));
|
||||
|
||||
// New root has new layout at the top
|
||||
ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root2_child0));
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root2_child1));
|
||||
|
||||
// The deeper children are untouched.
|
||||
ASSERT_EQ(YGNodeGetChild(root2_child1, 0), root_child1_0);
|
||||
ASSERT_EQ(YGNodeGetChild(root2_child1, 1), root_child1_1);
|
||||
|
||||
YGNodeFreeRecursive(root2);
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
||||
|
||||
TEST(YogaTest, cloning_and_freeing) {
|
||||
const int32_t initialInstanceCount = YGNodeGetInstanceCount();
|
||||
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root, 100);
|
||||
YGNodeStyleSetHeight(root, 100);
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
const YGNodeRef root2 = YGNodeClone(root);
|
||||
|
||||
// Freeing the original root should be safe as long as we don't free its children.
|
||||
YGNodeFree(root);
|
||||
|
||||
YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
YGNodeFreeRecursive(root2);
|
||||
|
||||
YGNodeFree(root_child0);
|
||||
YGNodeFree(root_child1);
|
||||
|
||||
YGConfigFree(config);
|
||||
|
||||
ASSERT_EQ(initialInstanceCount, YGNodeGetInstanceCount());
|
||||
}
|
31
tests/YGRoundingFunctionTest.cpp
Normal file
31
tests/YGRoundingFunctionTest.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <yoga/Yoga.h>
|
||||
#include <yoga/Yoga-internal.h>
|
||||
|
||||
TEST(YogaTest, rounding_value) {
|
||||
// Test that whole numbers are rounded to whole despite ceil/floor flags
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, false, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, true, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.000001, 2.0, false, true));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, false, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, true, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.999999, 2.0, false, true));
|
||||
|
||||
// Test that numbers with fraction are rounded correctly accounting for ceil/floor flags
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.01, 2.0, false, false));
|
||||
ASSERT_FLOAT_EQ(6.5, YGRoundValueToPixelGrid(6.01, 2.0, true, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(6.01, 2.0, false, true));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.99, 2.0, false, false));
|
||||
ASSERT_FLOAT_EQ(6.0, YGRoundValueToPixelGrid(5.99, 2.0, true, false));
|
||||
ASSERT_FLOAT_EQ(5.5, YGRoundValueToPixelGrid(5.99, 2.0, false, true));
|
||||
}
|
39
tests/YGZeroOutLayoutRecursivlyTest.cpp
Normal file
39
tests/YGZeroOutLayoutRecursivlyTest.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
TEST(YogaTest, zero_out_layout) {
|
||||
const YGNodeRef root = YGNodeNew();
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
YGNodeStyleSetWidth(root, 200);
|
||||
YGNodeStyleSetHeight(root, 200);
|
||||
|
||||
const YGNodeRef child = YGNodeNew();
|
||||
YGNodeInsertChild(root, child, 0);
|
||||
YGNodeStyleSetWidth(child, 100);
|
||||
YGNodeStyleSetHeight(child, 100);
|
||||
YGNodeStyleSetMargin(child, YGEdgeTop, 10);
|
||||
YGNodeStyleSetPadding(child, YGEdgeTop, 10);
|
||||
|
||||
YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetMargin(child, YGEdgeTop));
|
||||
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetPadding(child, YGEdgeTop));
|
||||
|
||||
YGNodeStyleSetDisplay(child, YGDisplayNone);
|
||||
|
||||
YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetMargin(child, YGEdgeTop));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetPadding(child, YGEdgeTop));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
@@ -7,6 +7,8 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "YGNodeList.h"
|
||||
|
||||
extern YGMalloc gYGMalloc;
|
||||
@@ -72,6 +74,17 @@ void YGNodeListInsert(YGNodeListRef *listp, const YGNodeRef node, const uint32_t
|
||||
list->items[index] = node;
|
||||
}
|
||||
|
||||
void YGNodeListReplace(YGNodeListRef list, const uint32_t index, const YGNodeRef newNode) {
|
||||
list->items[index] = newNode;
|
||||
}
|
||||
|
||||
void YGNodeListRemoveAll(const YGNodeListRef list) {
|
||||
for (uint32_t i = 0; i < list->count; i++) {
|
||||
list->items[i] = NULL;
|
||||
}
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
YGNodeRef YGNodeListRemove(const YGNodeListRef list, const uint32_t index) {
|
||||
const YGNodeRef removed = list->items[index];
|
||||
list->items[index] = NULL;
|
||||
@@ -102,3 +115,17 @@ YGNodeRef YGNodeListGet(const YGNodeListRef list, const uint32_t index) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
YGNodeListRef YGNodeListClone(const YGNodeListRef oldList) {
|
||||
if (!oldList) {
|
||||
return NULL;
|
||||
}
|
||||
const uint32_t count = oldList->count;
|
||||
if (count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
const YGNodeListRef newList = YGNodeListNew(count);
|
||||
memcpy(newList->items, oldList->items, sizeof(YGNodeRef) * count);
|
||||
newList->count = count;
|
||||
return newList;
|
||||
}
|
||||
|
@@ -26,8 +26,11 @@ void YGNodeListFree(const YGNodeListRef list);
|
||||
uint32_t YGNodeListCount(const YGNodeListRef list);
|
||||
void YGNodeListAdd(YGNodeListRef *listp, const YGNodeRef node);
|
||||
void YGNodeListInsert(YGNodeListRef *listp, const YGNodeRef node, const uint32_t index);
|
||||
void YGNodeListReplace(const YGNodeListRef list, const uint32_t index, const YGNodeRef newNode);
|
||||
void YGNodeListRemoveAll(const YGNodeListRef list);
|
||||
YGNodeRef YGNodeListRemove(const YGNodeListRef list, const uint32_t index);
|
||||
YGNodeRef YGNodeListDelete(const YGNodeListRef list, const YGNodeRef node);
|
||||
YGNodeRef YGNodeListGet(const YGNodeListRef list, const uint32_t index);
|
||||
YGNodeListRef YGNodeListClone(YGNodeListRef list);
|
||||
|
||||
YG_EXTERN_C_END
|
||||
|
19
yoga/Yoga-internal.h
Normal file
19
yoga/Yoga-internal.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
YG_EXTERN_C_BEGIN
|
||||
|
||||
WIN_EXPORT float YGRoundValueToPixelGrid(const float value,
|
||||
const float pointScaleFactor,
|
||||
const bool forceCeil,
|
||||
const bool forceFloor);
|
||||
|
||||
YG_EXTERN_C_END
|
546
yoga/Yoga.c
546
yoga/Yoga.c
@@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "YGNodeList.h"
|
||||
#include "Yoga-internal.h"
|
||||
#include "Yoga.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -101,6 +102,7 @@ typedef struct YGConfig {
|
||||
bool useLegacyStretchBehaviour;
|
||||
float pointScaleFactor;
|
||||
YGLogger logger;
|
||||
YGNodeClonedFunc cloneNodeCallback;
|
||||
void *context;
|
||||
} YGConfig;
|
||||
|
||||
@@ -155,7 +157,7 @@ static const float kDefaultFlexGrow = 0.0f;
|
||||
static const float kDefaultFlexShrink = 0.0f;
|
||||
static const float kWebDefaultFlexShrink = 1.0f;
|
||||
|
||||
static YGNode gYGNodeDefaults = {
|
||||
static const YGNode gYGNodeDefaults = {
|
||||
.parent = NULL,
|
||||
.children = NULL,
|
||||
.hasNewLayout = true,
|
||||
@@ -361,6 +363,17 @@ YGNodeRef YGNodeNew(void) {
|
||||
return YGNodeNewWithConfig(&gYGConfigDefaults);
|
||||
}
|
||||
|
||||
YGNodeRef YGNodeClone(const YGNodeRef oldNode) {
|
||||
const YGNodeRef node = gYGMalloc(sizeof(YGNode));
|
||||
YGAssertWithConfig(oldNode->config, node != NULL, "Could not allocate memory for node");
|
||||
gNodeInstanceCount++;
|
||||
|
||||
memcpy(node, oldNode, sizeof(YGNode));
|
||||
node->children = YGNodeListClone(oldNode->children);
|
||||
node->parent = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
void YGNodeFree(const YGNodeRef node) {
|
||||
if (node->parent) {
|
||||
YGNodeListDelete(node->parent->children, node);
|
||||
@@ -381,6 +394,10 @@ void YGNodeFree(const YGNodeRef node) {
|
||||
void YGNodeFreeRecursive(const YGNodeRef root) {
|
||||
while (YGNodeGetChildCount(root) > 0) {
|
||||
const YGNodeRef child = YGNodeGetChild(root, 0);
|
||||
if (child->parent != root) {
|
||||
// Don't free shared nodes that we don't own.
|
||||
break;
|
||||
}
|
||||
YGNodeRemoveChild(root, child);
|
||||
YGNodeFreeRecursive(child);
|
||||
}
|
||||
@@ -473,6 +490,34 @@ YGBaselineFunc YGNodeGetBaselineFunc(const YGNodeRef node) {
|
||||
return node->baseline;
|
||||
}
|
||||
|
||||
static void YGCloneChildrenIfNeeded(const YGNodeRef parent) {
|
||||
// YGNodeRemoveChild has a forked variant of this algorithm optimized for deletions.
|
||||
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||
if (childCount == 0) {
|
||||
// This is an empty set. Nothing to clone.
|
||||
return;
|
||||
}
|
||||
const YGNodeRef firstChild = YGNodeGetChild(parent, 0);
|
||||
if (firstChild->parent == parent) {
|
||||
// If the first child has this node as its parent, we assume that it is already unique.
|
||||
// We can do this because if we have it has a child, that means that its parent was at some
|
||||
// point cloned which made that subtree immutable.
|
||||
// We also assume that all its sibling are cloned as well.
|
||||
return;
|
||||
}
|
||||
const YGNodeClonedFunc cloneNodeCallback = parent->config->cloneNodeCallback;
|
||||
const YGNodeListRef children = parent->children;
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef oldChild = YGNodeListGet(children, i);
|
||||
const YGNodeRef newChild = YGNodeClone(oldChild);
|
||||
YGNodeListReplace(children, i, newChild);
|
||||
newChild->parent = parent;
|
||||
if (cloneNodeCallback) {
|
||||
cloneNodeCallback(oldChild, newChild, parent, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
||||
YGAssertWithNode(node,
|
||||
child->parent == NULL,
|
||||
@@ -481,17 +526,81 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32
|
||||
node->measure == NULL,
|
||||
"Cannot add child: Nodes with measure functions cannot have children.");
|
||||
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
|
||||
YGNodeListInsert(&node->children, child, index);
|
||||
child->parent = node;
|
||||
YGNodeMarkDirtyInternal(node);
|
||||
}
|
||||
|
||||
void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child) {
|
||||
if (YGNodeListDelete(node->children, child) != NULL) {
|
||||
child->layout = gYGNodeDefaults.layout; // layout is no longer valid
|
||||
child->parent = NULL;
|
||||
YGNodeMarkDirtyInternal(node);
|
||||
void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) {
|
||||
// This algorithm is a forked variant from YGCloneChildrenIfNeeded that excludes a child.
|
||||
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||
if (childCount == 0) {
|
||||
// This is an empty set. Nothing to remove.
|
||||
return;
|
||||
}
|
||||
const YGNodeRef firstChild = YGNodeGetChild(parent, 0);
|
||||
if (firstChild->parent == parent) {
|
||||
// If the first child has this node as its parent, we assume that it is already unique.
|
||||
// We can now try to delete a child in this list.
|
||||
if (YGNodeListDelete(parent->children, excludedChild) != NULL) {
|
||||
excludedChild->layout = gYGNodeDefaults.layout; // layout is no longer valid
|
||||
excludedChild->parent = NULL;
|
||||
YGNodeMarkDirtyInternal(parent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Otherwise we have to clone the node list except for the child we're trying to delete.
|
||||
// We don't want to simply clone all children, because then the host will need to free
|
||||
// the clone of the child that was just deleted.
|
||||
const YGNodeClonedFunc cloneNodeCallback = parent->config->cloneNodeCallback;
|
||||
const YGNodeListRef children = parent->children;
|
||||
uint32_t nextInsertIndex = 0;
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef oldChild = YGNodeListGet(children, i);
|
||||
if (excludedChild == oldChild) {
|
||||
// Ignore the deleted child. Don't reset its layout or parent since it is still valid
|
||||
// in the other parent. However, since this parent has now changed, we need to mark it
|
||||
// as dirty.
|
||||
YGNodeMarkDirtyInternal(parent);
|
||||
continue;
|
||||
}
|
||||
const YGNodeRef newChild = YGNodeClone(oldChild);
|
||||
YGNodeListReplace(children, nextInsertIndex, newChild);
|
||||
newChild->parent = parent;
|
||||
if (cloneNodeCallback) {
|
||||
cloneNodeCallback(oldChild, newChild, parent, nextInsertIndex);
|
||||
}
|
||||
nextInsertIndex++;
|
||||
}
|
||||
while (nextInsertIndex < childCount) {
|
||||
YGNodeListRemove(children, nextInsertIndex);
|
||||
nextInsertIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeRemoveAllChildren(const YGNodeRef parent) {
|
||||
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||
if (childCount == 0) {
|
||||
// This is an empty set already. Nothing to do.
|
||||
return;
|
||||
}
|
||||
const YGNodeRef firstChild = YGNodeGetChild(parent, 0);
|
||||
if (firstChild->parent == parent) {
|
||||
// If the first child has this node as its parent, we assume that this child set is unique.
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef oldChild = YGNodeGetChild(parent, i);
|
||||
oldChild->layout = gYGNodeDefaults.layout; // layout is no longer valid
|
||||
oldChild->parent = NULL;
|
||||
}
|
||||
YGNodeListRemoveAll(parent->children);
|
||||
YGNodeMarkDirtyInternal(parent);
|
||||
return;
|
||||
}
|
||||
// Otherwise, we are not the owner of the child set. We don't have to do anything to clear it.
|
||||
parent->children = NULL;
|
||||
YGNodeMarkDirtyInternal(parent);
|
||||
}
|
||||
|
||||
YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) {
|
||||
@@ -502,7 +611,7 @@ YGNodeRef YGNodeGetParent(const YGNodeRef node) {
|
||||
return node->parent;
|
||||
}
|
||||
|
||||
inline uint32_t YGNodeGetChildCount(const YGNodeRef node) {
|
||||
uint32_t YGNodeGetChildCount(const YGNodeRef node) {
|
||||
return YGNodeListCount(node->children);
|
||||
}
|
||||
|
||||
@@ -838,53 +947,84 @@ static inline bool YGFloatsEqual(const float a, const float b) {
|
||||
return fabs(a - b) < 0.0001f;
|
||||
}
|
||||
|
||||
static void YGIndent(const YGNodeRef node, const uint32_t n) {
|
||||
typedef struct YGStringStream {
|
||||
char *str;
|
||||
uint32_t length;
|
||||
uint32_t capacity;
|
||||
} YGStringStream;
|
||||
|
||||
static void YGWriteToStringStream(YGStringStream *stream, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
va_list argsCopy;
|
||||
va_copy(argsCopy, args);
|
||||
int available = stream->capacity - stream->length;
|
||||
int required = vsnprintf(NULL, 0, format, args);
|
||||
va_end(args);
|
||||
if (required >= available) {
|
||||
char *newStr = (char *) realloc(stream->str, sizeof(char) * (stream->capacity) * 2);
|
||||
if (newStr != NULL) {
|
||||
stream->str = newStr;
|
||||
stream->capacity *= 2;
|
||||
available = stream->capacity - stream->length;
|
||||
}
|
||||
};
|
||||
vsnprintf(stream->str + stream->length, available, format, argsCopy);
|
||||
if (required < available) {
|
||||
stream->length += required;
|
||||
} else {
|
||||
stream->length = stream->capacity - 1;
|
||||
}
|
||||
va_end(argsCopy);
|
||||
}
|
||||
|
||||
static void YGIndent(YGStringStream *stream, const uint32_t n) {
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
YGLog(node, YGLogLevelDebug, " ");
|
||||
YGWriteToStringStream(stream, " ");
|
||||
}
|
||||
}
|
||||
|
||||
static void YGPrintNumberIfNotUndefinedf(const YGNodeRef node,
|
||||
static void YGPrintNumberIfNotUndefinedf(YGStringStream *stream,
|
||||
const char *str,
|
||||
const float number) {
|
||||
if (!YGFloatIsUndefined(number)) {
|
||||
YGLog(node, YGLogLevelDebug, "%s: %g; ", str, number);
|
||||
YGWriteToStringStream(stream, "%s: %g; ", str, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void YGPrintNumberIfNotUndefined(const YGNodeRef node,
|
||||
static void YGPrintNumberIfNotUndefined(YGStringStream *stream,
|
||||
const char *str,
|
||||
const YGValue *const number) {
|
||||
if (number->unit != YGUnitUndefined) {
|
||||
if (number->unit == YGUnitAuto) {
|
||||
YGLog(node, YGLogLevelDebug, "%s: auto; ", str);
|
||||
YGWriteToStringStream(stream, "%s: auto; ", str);
|
||||
} else {
|
||||
const char *unit = number->unit == YGUnitPoint ? "px" : "%";
|
||||
YGLog(node, YGLogLevelDebug, "%s: %g%s; ", str, number->value, unit);
|
||||
const char *unit = number->unit == YGUnitPoint ? "px" : "%%";
|
||||
YGWriteToStringStream(stream, "%s: %g%s; ", str, number->value, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void YGPrintNumberIfNotAuto(const YGNodeRef node,
|
||||
static void YGPrintNumberIfNotAuto(YGStringStream *stream,
|
||||
const char *str,
|
||||
const YGValue *const number) {
|
||||
if (number->unit != YGUnitAuto) {
|
||||
YGPrintNumberIfNotUndefined(node, str, number);
|
||||
YGPrintNumberIfNotUndefined(stream, str, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void YGPrintEdgeIfNotUndefined(const YGNodeRef node,
|
||||
static void YGPrintEdgeIfNotUndefined(YGStringStream *stream,
|
||||
const char *str,
|
||||
const YGValue *edges,
|
||||
const YGEdge edge) {
|
||||
YGPrintNumberIfNotUndefined(node, str, YGComputedEdgeValue(edges, edge, &YGValueUndefined));
|
||||
YGPrintNumberIfNotUndefined(stream, str, YGComputedEdgeValue(edges, edge, &YGValueUndefined));
|
||||
}
|
||||
|
||||
static void YGPrintNumberIfNotZero(const YGNodeRef node,
|
||||
static void YGPrintNumberIfNotZero(YGStringStream *stream,
|
||||
const char *str,
|
||||
const YGValue *const number) {
|
||||
if (!YGFloatsEqual(number->value, 0)) {
|
||||
YGPrintNumberIfNotUndefined(node, str, number);
|
||||
YGPrintNumberIfNotUndefined(stream, str, number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,122 +1033,133 @@ static bool YGFourValuesEqual(const YGValue four[4]) {
|
||||
YGValueEqual(four[0], four[3]);
|
||||
}
|
||||
|
||||
static void YGPrintEdges(const YGNodeRef node, const char *str, const YGValue *edges) {
|
||||
static void YGPrintEdges(YGStringStream *stream, const char *str, const YGValue *edges) {
|
||||
if (YGFourValuesEqual(edges)) {
|
||||
YGPrintNumberIfNotZero(node, str, &edges[YGEdgeLeft]);
|
||||
YGPrintNumberIfNotZero(stream, str, &edges[YGEdgeLeft]);
|
||||
} else {
|
||||
for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) {
|
||||
char buf[30];
|
||||
snprintf(buf, sizeof(buf), "%s-%s", str, YGEdgeToString(edge));
|
||||
YGPrintNumberIfNotZero(node, buf, &edges[edge]);
|
||||
YGPrintNumberIfNotZero(stream, buf, &edges[edge]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void YGNodePrintInternal(const YGNodeRef node,
|
||||
const YGPrintOptions options,
|
||||
const uint32_t level) {
|
||||
YGIndent(node, level);
|
||||
YGLog(node, YGLogLevelDebug, "<div ");
|
||||
static void YGNodeToString(YGStringStream *stream,
|
||||
const YGNodeRef node,
|
||||
const YGPrintOptions options,
|
||||
const uint32_t level) {
|
||||
YGIndent(stream, level);
|
||||
YGWriteToStringStream(stream, "<div ");
|
||||
|
||||
if (node->print) {
|
||||
node->print(node);
|
||||
}
|
||||
|
||||
if (options & YGPrintOptionsLayout) {
|
||||
YGLog(node, YGLogLevelDebug, "layout=\"");
|
||||
YGLog(node, YGLogLevelDebug, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
|
||||
YGLog(node, YGLogLevelDebug, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
|
||||
YGLog(node, YGLogLevelDebug, "top: %g; ", node->layout.position[YGEdgeTop]);
|
||||
YGLog(node, YGLogLevelDebug, "left: %g;", node->layout.position[YGEdgeLeft]);
|
||||
YGLog(node, YGLogLevelDebug, "\" ");
|
||||
YGWriteToStringStream(stream, "layout=\"");
|
||||
YGWriteToStringStream(stream, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
|
||||
YGWriteToStringStream(stream, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
|
||||
YGWriteToStringStream(stream, "top: %g; ", node->layout.position[YGEdgeTop]);
|
||||
YGWriteToStringStream(stream, "left: %g;", node->layout.position[YGEdgeLeft]);
|
||||
YGWriteToStringStream(stream, "\" ");
|
||||
}
|
||||
|
||||
if (options & YGPrintOptionsStyle) {
|
||||
YGLog(node, YGLogLevelDebug, "style=\"");
|
||||
YGWriteToStringStream(stream, "style=\"");
|
||||
if (node->style.flexDirection != gYGNodeDefaults.style.flexDirection) {
|
||||
YGLog(node,
|
||||
YGLogLevelDebug,
|
||||
"flex-direction: %s; ",
|
||||
YGFlexDirectionToString(node->style.flexDirection));
|
||||
YGWriteToStringStream(stream,
|
||||
"flex-direction: %s; ",
|
||||
YGFlexDirectionToString(node->style.flexDirection));
|
||||
}
|
||||
if (node->style.justifyContent != gYGNodeDefaults.style.justifyContent) {
|
||||
YGLog(node,
|
||||
YGLogLevelDebug,
|
||||
"justify-content: %s; ",
|
||||
YGJustifyToString(node->style.justifyContent));
|
||||
YGWriteToStringStream(stream,
|
||||
"justify-content: %s; ",
|
||||
YGJustifyToString(node->style.justifyContent));
|
||||
}
|
||||
if (node->style.alignItems != gYGNodeDefaults.style.alignItems) {
|
||||
YGLog(node, YGLogLevelDebug, "align-items: %s; ", YGAlignToString(node->style.alignItems));
|
||||
YGWriteToStringStream(stream, "align-items: %s; ", YGAlignToString(node->style.alignItems));
|
||||
}
|
||||
if (node->style.alignContent != gYGNodeDefaults.style.alignContent) {
|
||||
YGLog(node, YGLogLevelDebug, "align-content: %s; ", YGAlignToString(node->style.alignContent));
|
||||
YGWriteToStringStream(stream, "align-content: %s; ", YGAlignToString(node->style.alignContent));
|
||||
}
|
||||
if (node->style.alignSelf != gYGNodeDefaults.style.alignSelf) {
|
||||
YGLog(node, YGLogLevelDebug, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
|
||||
YGWriteToStringStream(stream, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
|
||||
}
|
||||
|
||||
YGPrintNumberIfNotUndefinedf(node, "flex-grow", node->style.flexGrow);
|
||||
YGPrintNumberIfNotUndefinedf(node, "flex-shrink", node->style.flexShrink);
|
||||
YGPrintNumberIfNotAuto(node, "flex-basis", &node->style.flexBasis);
|
||||
YGPrintNumberIfNotUndefinedf(node, "flex", node->style.flex);
|
||||
YGPrintNumberIfNotUndefinedf(stream, "flex-grow", node->style.flexGrow);
|
||||
YGPrintNumberIfNotUndefinedf(stream, "flex-shrink", node->style.flexShrink);
|
||||
YGPrintNumberIfNotAuto(stream, "flex-basis", &node->style.flexBasis);
|
||||
YGPrintNumberIfNotUndefinedf(stream, "flex", node->style.flex);
|
||||
|
||||
if (node->style.flexWrap != gYGNodeDefaults.style.flexWrap) {
|
||||
YGLog(node, YGLogLevelDebug, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
|
||||
YGWriteToStringStream(stream, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
|
||||
}
|
||||
|
||||
if (node->style.overflow != gYGNodeDefaults.style.overflow) {
|
||||
YGLog(node, YGLogLevelDebug, "overflow: %s; ", YGOverflowToString(node->style.overflow));
|
||||
YGWriteToStringStream(stream, "overflow: %s; ", YGOverflowToString(node->style.overflow));
|
||||
}
|
||||
|
||||
if (node->style.display != gYGNodeDefaults.style.display) {
|
||||
YGLog(node, YGLogLevelDebug, "display: %s; ", YGDisplayToString(node->style.display));
|
||||
YGWriteToStringStream(stream, "display: %s; ", YGDisplayToString(node->style.display));
|
||||
}
|
||||
|
||||
YGPrintEdges(node, "margin", node->style.margin);
|
||||
YGPrintEdges(node, "padding", node->style.padding);
|
||||
YGPrintEdges(node, "border", node->style.border);
|
||||
YGPrintEdges(stream, "margin", node->style.margin);
|
||||
YGPrintEdges(stream, "padding", node->style.padding);
|
||||
YGPrintEdges(stream, "border", node->style.border);
|
||||
|
||||
YGPrintNumberIfNotAuto(node, "width", &node->style.dimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(node, "height", &node->style.dimensions[YGDimensionHeight]);
|
||||
YGPrintNumberIfNotAuto(node, "max-width", &node->style.maxDimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(node, "max-height", &node->style.maxDimensions[YGDimensionHeight]);
|
||||
YGPrintNumberIfNotAuto(node, "min-width", &node->style.minDimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(node, "min-height", &node->style.minDimensions[YGDimensionHeight]);
|
||||
YGPrintNumberIfNotAuto(stream, "width", &node->style.dimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(stream, "height", &node->style.dimensions[YGDimensionHeight]);
|
||||
YGPrintNumberIfNotAuto(stream, "max-width", &node->style.maxDimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(stream, "max-height", &node->style.maxDimensions[YGDimensionHeight]);
|
||||
YGPrintNumberIfNotAuto(stream, "min-width", &node->style.minDimensions[YGDimensionWidth]);
|
||||
YGPrintNumberIfNotAuto(stream, "min-height", &node->style.minDimensions[YGDimensionHeight]);
|
||||
|
||||
if (node->style.positionType != gYGNodeDefaults.style.positionType) {
|
||||
YGLog(node,
|
||||
YGLogLevelDebug,
|
||||
"position: %s; ",
|
||||
YGPositionTypeToString(node->style.positionType));
|
||||
YGWriteToStringStream(stream,
|
||||
"position: %s; ",
|
||||
YGPositionTypeToString(node->style.positionType));
|
||||
}
|
||||
|
||||
YGPrintEdgeIfNotUndefined(node, "left", node->style.position, YGEdgeLeft);
|
||||
YGPrintEdgeIfNotUndefined(node, "right", node->style.position, YGEdgeRight);
|
||||
YGPrintEdgeIfNotUndefined(node, "top", node->style.position, YGEdgeTop);
|
||||
YGPrintEdgeIfNotUndefined(node, "bottom", node->style.position, YGEdgeBottom);
|
||||
YGLog(node, YGLogLevelDebug, "\" ");
|
||||
YGPrintEdgeIfNotUndefined(stream, "left", node->style.position, YGEdgeLeft);
|
||||
YGPrintEdgeIfNotUndefined(stream, "right", node->style.position, YGEdgeRight);
|
||||
YGPrintEdgeIfNotUndefined(stream, "top", node->style.position, YGEdgeTop);
|
||||
YGPrintEdgeIfNotUndefined(stream, "bottom", node->style.position, YGEdgeBottom);
|
||||
YGWriteToStringStream(stream, "\" ");
|
||||
|
||||
if (node->measure != NULL) {
|
||||
YGLog(node, YGLogLevelDebug, "has-custom-measure=\"true\"");
|
||||
YGWriteToStringStream(stream, "has-custom-measure=\"true\"");
|
||||
}
|
||||
}
|
||||
YGLog(node, YGLogLevelDebug, ">");
|
||||
YGWriteToStringStream(stream, ">");
|
||||
|
||||
const uint32_t childCount = YGNodeListCount(node->children);
|
||||
if (options & YGPrintOptionsChildren && childCount > 0) {
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
YGLog(node, YGLogLevelDebug, "\n");
|
||||
YGNodePrintInternal(YGNodeGetChild(node, i), options, level + 1);
|
||||
YGWriteToStringStream(stream, "\n");
|
||||
YGNodeToString(stream, YGNodeGetChild(node, i), options, level + 1);
|
||||
}
|
||||
YGIndent(node, level);
|
||||
YGLog(node, YGLogLevelDebug, "\n");
|
||||
YGWriteToStringStream(stream, "\n");
|
||||
YGIndent(stream, level);
|
||||
}
|
||||
YGWriteToStringStream(stream, "</div>");
|
||||
}
|
||||
|
||||
static void YGNodePrintInternal(const YGNodeRef node,
|
||||
const YGPrintOptions options) {
|
||||
YGStringStream stream;
|
||||
stream.str = (char *) malloc(sizeof(char) * 1024);
|
||||
stream.length = 0;
|
||||
stream.capacity = 1024;
|
||||
if (stream.str != NULL) {
|
||||
YGNodeToString(&stream, node, options, 0);
|
||||
YGLog(node, YGLogLevelDebug, stream.str);
|
||||
free(stream.str);
|
||||
}
|
||||
YGLog(node, YGLogLevelDebug, "</div>");
|
||||
}
|
||||
|
||||
void YGNodePrint(const YGNodeRef node, const YGPrintOptions options) {
|
||||
YGNodePrintInternal(node, options, 0);
|
||||
YGNodePrintInternal(node, options);
|
||||
}
|
||||
|
||||
static const YGEdge leading[4] = {
|
||||
@@ -1513,31 +1664,42 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
|
||||
}
|
||||
}
|
||||
|
||||
if (!YGFloatIsUndefined(child->style.aspectRatio)) {
|
||||
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
|
||||
childHeight = (childWidth - marginRow) / child->style.aspectRatio;
|
||||
childHeightMeasureMode = YGMeasureModeExactly;
|
||||
} else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
|
||||
childWidth = (childHeight - marginColumn) * child->style.aspectRatio;
|
||||
childWidthMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
// If child has no defined size in the cross axis and is set to stretch,
|
||||
// set the cross
|
||||
// axis to be measured exactly with the available inner width
|
||||
if (!isMainAxisRow && !YGFloatIsUndefined(width) && !isRowStyleDimDefined &&
|
||||
widthMode == YGMeasureModeExactly && YGNodeAlignItem(node, child) == YGAlignStretch) {
|
||||
|
||||
const bool hasExactWidth = !YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly;
|
||||
const bool childWidthStretch = YGNodeAlignItem(node, child) == YGAlignStretch &&
|
||||
childWidthMeasureMode != YGMeasureModeExactly;
|
||||
if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && childWidthStretch) {
|
||||
childWidth = width;
|
||||
childWidthMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
if (isMainAxisRow && !YGFloatIsUndefined(height) && !isColumnStyleDimDefined &&
|
||||
heightMode == YGMeasureModeExactly && YGNodeAlignItem(node, child) == YGAlignStretch) {
|
||||
childHeight = height;
|
||||
childHeightMeasureMode = YGMeasureModeExactly;
|
||||
if (!YGFloatIsUndefined(child->style.aspectRatio)) {
|
||||
childHeight = (childWidth - marginRow) / child->style.aspectRatio;
|
||||
childHeightMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
if (!YGFloatIsUndefined(child->style.aspectRatio)) {
|
||||
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf((childWidth - marginRow) / child->style.aspectRatio,
|
||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth));
|
||||
return;
|
||||
} else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
|
||||
child->layout.computedFlexBasis =
|
||||
fmaxf((childHeight - marginColumn) * child->style.aspectRatio,
|
||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth));
|
||||
return;
|
||||
const bool hasExactHeight = !YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly;
|
||||
const bool childHeightStretch = YGNodeAlignItem(node, child) == YGAlignStretch &&
|
||||
childHeightMeasureMode != YGMeasureModeExactly;
|
||||
if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && childHeightStretch) {
|
||||
childHeight = height;
|
||||
childHeightMeasureMode = YGMeasureModeExactly;
|
||||
|
||||
if (!YGFloatIsUndefined(child->style.aspectRatio)) {
|
||||
childWidth = (childHeight - marginColumn) * child->style.aspectRatio;
|
||||
childWidthMeasureMode = YGMeasureModeExactly;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1630,13 +1792,9 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) {
|
||||
if (!YGFloatIsUndefined(child->style.aspectRatio)) {
|
||||
if (YGFloatIsUndefined(childWidth)) {
|
||||
childWidth =
|
||||
marginRow + fmaxf((childHeight - marginColumn) * child->style.aspectRatio,
|
||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, width));
|
||||
childWidth = marginRow + (childHeight - marginColumn) * child->style.aspectRatio;
|
||||
} else if (YGFloatIsUndefined(childHeight)) {
|
||||
childHeight =
|
||||
marginColumn + fmaxf((childWidth - marginRow) / child->style.aspectRatio,
|
||||
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, width));
|
||||
childHeight = marginColumn + (childWidth - marginRow) / child->style.aspectRatio;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1687,11 +1845,11 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
config);
|
||||
|
||||
if (YGNodeIsTrailingPosDefined(child, mainAxis) && !YGNodeIsLeadingPosDefined(child, mainAxis)) {
|
||||
child->layout.position[leading[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] -
|
||||
child->layout.measuredDimensions[dim[mainAxis]] -
|
||||
YGNodeTrailingBorder(node, mainAxis) -
|
||||
YGNodeTrailingMargin(child, mainAxis, width) -
|
||||
YGNodeTrailingPosition(child, mainAxis, isMainAxisRow ? width : height);
|
||||
child->layout.position[leading[mainAxis]] =
|
||||
node->layout.measuredDimensions[dim[mainAxis]] -
|
||||
child->layout.measuredDimensions[dim[mainAxis]] - YGNodeTrailingBorder(node, mainAxis) -
|
||||
YGNodeTrailingMargin(child, mainAxis, width) -
|
||||
YGNodeTrailingPosition(child, mainAxis, isMainAxisRow ? width : height);
|
||||
} else if (!YGNodeIsLeadingPosDefined(child, mainAxis) &&
|
||||
node->style.justifyContent == YGJustifyCenter) {
|
||||
child->layout.position[leading[mainAxis]] = (node->layout.measuredDimensions[dim[mainAxis]] -
|
||||
@@ -1705,11 +1863,11 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
|
||||
if (YGNodeIsTrailingPosDefined(child, crossAxis) &&
|
||||
!YGNodeIsLeadingPosDefined(child, crossAxis)) {
|
||||
child->layout.position[leading[crossAxis]] = node->layout.measuredDimensions[dim[crossAxis]] -
|
||||
child->layout.measuredDimensions[dim[crossAxis]] -
|
||||
YGNodeTrailingBorder(node, crossAxis) -
|
||||
YGNodeTrailingMargin(child, crossAxis, width) -
|
||||
YGNodeTrailingPosition(child, crossAxis, isMainAxisRow ? height : width);
|
||||
child->layout.position[leading[crossAxis]] =
|
||||
node->layout.measuredDimensions[dim[crossAxis]] -
|
||||
child->layout.measuredDimensions[dim[crossAxis]] - YGNodeTrailingBorder(node, crossAxis) -
|
||||
YGNodeTrailingMargin(child, crossAxis, width) -
|
||||
YGNodeTrailingPosition(child, crossAxis, isMainAxisRow ? height : width);
|
||||
} else if (!YGNodeIsLeadingPosDefined(child, crossAxis) &&
|
||||
YGNodeAlignItem(node, child) == YGAlignCenter) {
|
||||
child->layout.position[leading[crossAxis]] =
|
||||
@@ -1717,7 +1875,8 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
|
||||
child->layout.measuredDimensions[dim[crossAxis]]) /
|
||||
2.0f;
|
||||
} else if (!YGNodeIsLeadingPosDefined(child, crossAxis) &&
|
||||
((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^ (node->style.flexWrap == YGWrapWrapReverse))) {
|
||||
((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^
|
||||
(node->style.flexWrap == YGWrapWrapReverse))) {
|
||||
child->layout.position[leading[crossAxis]] = (node->layout.measuredDimensions[dim[crossAxis]] -
|
||||
child->layout.measuredDimensions[dim[crossAxis]]);
|
||||
}
|
||||
@@ -1741,11 +1900,12 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node,
|
||||
|
||||
// We want to make sure we don't call measure with negative size
|
||||
const float innerWidth = YGFloatIsUndefined(availableWidth)
|
||||
? availableWidth
|
||||
: fmaxf(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
|
||||
const float innerHeight = YGFloatIsUndefined(availableHeight)
|
||||
? availableHeight
|
||||
: fmaxf(0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);
|
||||
? availableWidth
|
||||
: fmaxf(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
|
||||
const float innerHeight =
|
||||
YGFloatIsUndefined(availableHeight)
|
||||
? availableHeight
|
||||
: fmaxf(0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);
|
||||
|
||||
if (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly) {
|
||||
// Don't bother sizing the text if both dimensions are already defined.
|
||||
@@ -1855,19 +2015,9 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
|
||||
}
|
||||
|
||||
static void YGZeroOutLayoutRecursivly(const YGNodeRef node) {
|
||||
node->layout.dimensions[YGDimensionHeight] = 0;
|
||||
node->layout.dimensions[YGDimensionWidth] = 0;
|
||||
node->layout.position[YGEdgeTop] = 0;
|
||||
node->layout.position[YGEdgeBottom] = 0;
|
||||
node->layout.position[YGEdgeLeft] = 0;
|
||||
node->layout.position[YGEdgeRight] = 0;
|
||||
node->layout.cachedLayout.availableHeight = 0;
|
||||
node->layout.cachedLayout.availableWidth = 0;
|
||||
node->layout.cachedLayout.heightMeasureMode = YGMeasureModeExactly;
|
||||
node->layout.cachedLayout.widthMeasureMode = YGMeasureModeExactly;
|
||||
node->layout.cachedLayout.computedWidth = 0;
|
||||
node->layout.cachedLayout.computedHeight = 0;
|
||||
memset(&(node->layout), 0, sizeof(YGLayout));
|
||||
node->hasNewLayout = true;
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
const uint32_t childCount = YGNodeGetChildCount(node);
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef child = YGNodeListGet(node->children, i);
|
||||
@@ -2041,6 +2191,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point we know we're going to perform work. Ensure that each child has a mutable copy.
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
|
||||
// Reset layout flags, as they could have changed.
|
||||
node->layout.hadOverflow = false;
|
||||
|
||||
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
|
||||
const YGFlexDirection mainAxis = YGResolveFlexDirection(node->style.flexDirection, direction);
|
||||
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
|
||||
@@ -2240,7 +2396,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
const float childMarginMainAxis = YGNodeMarginForAxis(child, mainAxis, availableInnerWidth);
|
||||
const float flexBasisWithMaxConstraints =
|
||||
fminf(YGResolveValue(&child->style.maxDimensions[dim[mainAxis]], mainAxisParentSize),
|
||||
child->layout.computedFlexBasis);
|
||||
child->layout.computedFlexBasis);
|
||||
const float flexBasisWithMinAndMaxConstraints =
|
||||
fmaxf(YGResolveValue(&child->style.minDimensions[dim[mainAxis]], mainAxisParentSize),
|
||||
flexBasisWithMaxConstraints);
|
||||
@@ -2494,11 +2650,21 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
YGMeasureMode childCrossMeasureMode;
|
||||
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
|
||||
|
||||
if (!YGFloatIsUndefined(availableInnerCrossDim) &&
|
||||
!YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
||||
measureModeCrossDim == YGMeasureModeExactly &&
|
||||
!(isNodeFlexWrap && flexBasisOverflows) &&
|
||||
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) {
|
||||
if (!YGFloatIsUndefined(currentRelativeChild->style.aspectRatio)) {
|
||||
childCrossSize =
|
||||
isMainAxisRow
|
||||
? (childMainSize - marginMain) / currentRelativeChild->style.aspectRatio
|
||||
: (childMainSize - marginMain) * currentRelativeChild->style.aspectRatio;
|
||||
childCrossMeasureMode = YGMeasureModeExactly;
|
||||
|
||||
childCrossSize += marginCross;
|
||||
} else if (!YGFloatIsUndefined(availableInnerCrossDim) &&
|
||||
!YGNodeIsStyleDimDefined(currentRelativeChild,
|
||||
crossAxis,
|
||||
availableInnerCrossDim) &&
|
||||
measureModeCrossDim == YGMeasureModeExactly &&
|
||||
!(isNodeFlexWrap && flexBasisOverflows) &&
|
||||
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) {
|
||||
childCrossSize = availableInnerCrossDim;
|
||||
childCrossMeasureMode = YGMeasureModeExactly;
|
||||
} else if (!YGNodeIsStyleDimDefined(currentRelativeChild,
|
||||
@@ -2519,26 +2685,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
: YGMeasureModeExactly;
|
||||
}
|
||||
|
||||
if (!YGFloatIsUndefined(currentRelativeChild->style.aspectRatio)) {
|
||||
childCrossSize = fmaxf(
|
||||
isMainAxisRow
|
||||
? (childMainSize - marginMain) / currentRelativeChild->style.aspectRatio
|
||||
: (childMainSize - marginMain) * currentRelativeChild->style.aspectRatio,
|
||||
YGNodePaddingAndBorderForAxis(currentRelativeChild, crossAxis, availableInnerWidth));
|
||||
childCrossMeasureMode = YGMeasureModeExactly;
|
||||
|
||||
// Parent size constraint should have higher priority than flex
|
||||
if (YGNodeIsFlex(currentRelativeChild)) {
|
||||
childCrossSize = fminf(childCrossSize - marginCross, availableInnerCrossDim);
|
||||
childMainSize =
|
||||
marginMain + (isMainAxisRow
|
||||
? childCrossSize * currentRelativeChild->style.aspectRatio
|
||||
: childCrossSize / currentRelativeChild->style.aspectRatio);
|
||||
}
|
||||
|
||||
childCrossSize += marginCross;
|
||||
}
|
||||
|
||||
YGConstrainMaxSizeForMode(currentRelativeChild,
|
||||
mainAxis,
|
||||
availableInnerMainDim,
|
||||
@@ -2577,14 +2723,14 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
performLayout && !requiresStretchLayout,
|
||||
"flex",
|
||||
config);
|
||||
node->layout.hadOverflow = node->layout.hadOverflow || currentRelativeChild->layout.hadOverflow;
|
||||
node->layout.hadOverflow |= currentRelativeChild->layout.hadOverflow;
|
||||
|
||||
currentRelativeChild = currentRelativeChild->nextChild;
|
||||
}
|
||||
}
|
||||
|
||||
remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace;
|
||||
node->layout.hadOverflow = node->layout.hadOverflow || (remainingFreeSpace < 0);
|
||||
node->layout.hadOverflow |= (remainingFreeSpace < 0);
|
||||
|
||||
// STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION
|
||||
|
||||
@@ -2746,12 +2892,15 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
// top/left/bottom/right
|
||||
// set, override all the previously computed positions to set it
|
||||
// correctly.
|
||||
if (YGNodeIsLeadingPosDefined(child, crossAxis)) {
|
||||
const bool isChildLeadingPosDefined = YGNodeIsLeadingPosDefined(child, crossAxis);
|
||||
if (isChildLeadingPosDefined) {
|
||||
child->layout.position[pos[crossAxis]] =
|
||||
YGNodeLeadingPosition(child, crossAxis, availableInnerCrossDim) +
|
||||
YGNodeLeadingBorder(node, crossAxis) +
|
||||
YGNodeLeadingMargin(child, crossAxis, availableInnerWidth);
|
||||
} else {
|
||||
}
|
||||
// If leading position is not defined or calculations result in Nan, default to border + margin
|
||||
if (!isChildLeadingPosDefined || YGFloatIsUndefined(child->layout.position[pos[crossAxis]])) {
|
||||
child->layout.position[pos[crossAxis]] =
|
||||
YGNodeLeadingBorder(node, crossAxis) +
|
||||
YGNodeLeadingMargin(child, crossAxis, availableInnerWidth);
|
||||
@@ -3155,21 +3304,25 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(YGMeasureM
|
||||
lastSize > size && (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize));
|
||||
}
|
||||
|
||||
static float YGRoundValueToPixelGrid(const float value,
|
||||
const float pointScaleFactor,
|
||||
const bool forceCeil,
|
||||
const bool forceFloor) {
|
||||
float YGRoundValueToPixelGrid(const float value,
|
||||
const float pointScaleFactor,
|
||||
const bool forceCeil,
|
||||
const bool forceFloor) {
|
||||
float scaledValue = value * pointScaleFactor;
|
||||
float fractial = fmodf(scaledValue, 1.0);
|
||||
if (YGFloatsEqual(fractial, 0)) {
|
||||
// Still remove fractial as fractial could be extremely small.
|
||||
// First we check if the value is already rounded
|
||||
scaledValue = scaledValue - fractial;
|
||||
} else if (forceCeil) {
|
||||
} else if (YGFloatsEqual(fractial, 1.0)) {
|
||||
scaledValue = scaledValue - fractial + 1.0;
|
||||
} else if (forceCeil) {
|
||||
// Next we check if we need to use forced rounding
|
||||
scaledValue = scaledValue - fractial + 1.0f;
|
||||
} else if (forceFloor) {
|
||||
scaledValue = scaledValue - fractial;
|
||||
} else {
|
||||
scaledValue = scaledValue - fractial + (fractial >= 0.5f ? 1.0 : 0);
|
||||
// Finally we just round the value
|
||||
scaledValue = scaledValue - fractial + (fractial >= 0.5f ? 1.0f : 0.0f);
|
||||
}
|
||||
return scaledValue / pointScaleFactor;
|
||||
}
|
||||
@@ -3191,13 +3344,25 @@ bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
|
||||
return false;
|
||||
}
|
||||
bool useRoundedComparison = config != NULL && config->pointScaleFactor != 0;
|
||||
const float effectiveWidth = useRoundedComparison ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) : width;
|
||||
const float effectiveHeight = useRoundedComparison ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) : height;
|
||||
const float effectiveLastWidth = useRoundedComparison ? YGRoundValueToPixelGrid(lastWidth, config->pointScaleFactor, false, false) : lastWidth;
|
||||
const float effectiveLastHeight = useRoundedComparison ? YGRoundValueToPixelGrid(lastHeight, config->pointScaleFactor, false, false) : lastHeight;
|
||||
const float effectiveWidth =
|
||||
useRoundedComparison ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false)
|
||||
: width;
|
||||
const float effectiveHeight =
|
||||
useRoundedComparison ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false)
|
||||
: height;
|
||||
const float effectiveLastWidth =
|
||||
useRoundedComparison
|
||||
? YGRoundValueToPixelGrid(lastWidth, config->pointScaleFactor, false, false)
|
||||
: lastWidth;
|
||||
const float effectiveLastHeight =
|
||||
useRoundedComparison
|
||||
? YGRoundValueToPixelGrid(lastHeight, config->pointScaleFactor, false, false)
|
||||
: lastHeight;
|
||||
|
||||
const bool hasSameWidthSpec = lastWidthMode == widthMode && YGFloatsEqual(effectiveLastWidth, effectiveWidth);
|
||||
const bool hasSameHeightSpec = lastHeightMode == heightMode && YGFloatsEqual(effectiveLastHeight, effectiveHeight);
|
||||
const bool hasSameWidthSpec =
|
||||
lastWidthMode == widthMode && YGFloatsEqual(effectiveLastWidth, effectiveWidth);
|
||||
const bool hasSameHeightSpec =
|
||||
lastHeightMode == heightMode && YGFloatsEqual(effectiveLastHeight, effectiveHeight);
|
||||
|
||||
const bool widthIsCompatible =
|
||||
hasSameWidthSpec || YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(widthMode,
|
||||
@@ -3471,22 +3636,25 @@ static void YGRoundToPixelGrid(const YGNodeRef node,
|
||||
node->layout.position[YGEdgeTop] =
|
||||
YGRoundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding);
|
||||
|
||||
const bool hasFractionalWidth = !YGFloatsEqual(fmodf(nodeWidth, 1 / pointScaleFactor), 0);
|
||||
const bool hasFractionalHeight = !YGFloatsEqual(fmodf(nodeHeight, 1 / pointScaleFactor), 0);
|
||||
// We multiply dimension by scale factor and if the result is close to the whole number, we don't
|
||||
// have any fraction
|
||||
// To verify if the result is close to whole number we want to check both floor and ceil numbers
|
||||
const bool hasFractionalWidth = !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) &&
|
||||
!YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0);
|
||||
const bool hasFractionalHeight = !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) &&
|
||||
!YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0);
|
||||
|
||||
node->layout.dimensions[YGDimensionWidth] =
|
||||
YGRoundValueToPixelGrid(
|
||||
absoluteNodeRight,
|
||||
pointScaleFactor,
|
||||
(textRounding && hasFractionalWidth),
|
||||
(textRounding && !hasFractionalWidth)) -
|
||||
YGRoundValueToPixelGrid(absoluteNodeRight,
|
||||
pointScaleFactor,
|
||||
(textRounding && hasFractionalWidth),
|
||||
(textRounding && !hasFractionalWidth)) -
|
||||
YGRoundValueToPixelGrid(absoluteNodeLeft, pointScaleFactor, false, textRounding);
|
||||
node->layout.dimensions[YGDimensionHeight] =
|
||||
YGRoundValueToPixelGrid(
|
||||
absoluteNodeBottom,
|
||||
pointScaleFactor,
|
||||
(textRounding && hasFractionalHeight),
|
||||
(textRounding && !hasFractionalHeight)) -
|
||||
YGRoundValueToPixelGrid(absoluteNodeBottom,
|
||||
pointScaleFactor,
|
||||
(textRounding && hasFractionalHeight),
|
||||
(textRounding && !hasFractionalHeight)) -
|
||||
YGRoundValueToPixelGrid(absoluteNodeTop, pointScaleFactor, false, textRounding);
|
||||
|
||||
const uint32_t childCount = YGNodeListCount(node->children);
|
||||
@@ -3645,6 +3813,10 @@ void *YGConfigGetContext(const YGConfigRef config) {
|
||||
return config->context;
|
||||
}
|
||||
|
||||
void YGConfigSetNodeClonedFunc(const YGConfigRef config, const YGNodeClonedFunc callback) {
|
||||
config->cloneNodeCallback = callback;
|
||||
}
|
||||
|
||||
void YGSetMemoryFuncs(YGMalloc ygmalloc, YGCalloc yccalloc, YGRealloc ygrealloc, YGFree ygfree) {
|
||||
YGAssert(gNodeInstanceCount == 0 && gConfigInstanceCount == 0,
|
||||
"Cannot set memory functions: all node must be freed first");
|
||||
|
11
yoga/Yoga.h
11
yoga/Yoga.h
@@ -60,6 +60,10 @@ typedef int (*YGLogger)(const YGConfigRef config,
|
||||
YGLogLevel level,
|
||||
const char *format,
|
||||
va_list args);
|
||||
typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode,
|
||||
YGNodeRef newNode,
|
||||
YGNodeRef parent,
|
||||
int childIndex);
|
||||
|
||||
typedef void *(*YGMalloc)(size_t size);
|
||||
typedef void *(*YGCalloc)(size_t count, size_t size);
|
||||
@@ -69,6 +73,7 @@ typedef void (*YGFree)(void *ptr);
|
||||
// YGNode
|
||||
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
||||
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config);
|
||||
WIN_EXPORT YGNodeRef YGNodeClone(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeFree(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeFreeRecursive(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeReset(const YGNodeRef node);
|
||||
@@ -78,6 +83,7 @@ WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
|
||||
const YGNodeRef child,
|
||||
const uint32_t index);
|
||||
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
|
||||
WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
|
||||
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
||||
@@ -112,7 +118,7 @@ WIN_EXPORT bool YGNodeCanUseCachedMeasurement(const YGMeasureMode widthMode,
|
||||
const float lastComputedHeight,
|
||||
const float marginRow,
|
||||
const float marginColumn,
|
||||
YGConfigRef config);
|
||||
const YGConfigRef config);
|
||||
|
||||
WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode);
|
||||
|
||||
@@ -264,6 +270,9 @@ WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
|
||||
WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled);
|
||||
WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config);
|
||||
|
||||
WIN_EXPORT void YGConfigSetNodeClonedFunc(const YGConfigRef config,
|
||||
const YGNodeClonedFunc callback);
|
||||
|
||||
// Export only for C#
|
||||
WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
|
||||
|
||||
|
Reference in New Issue
Block a user